summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mcrute@gmail.com>2015-07-29 18:38:22 -0700
committerMike Crute <mcrute@gmail.com>2015-07-29 18:38:22 -0700
commit53335ce936e758b816cce584665d1d55914b4ef4 (patch)
tree3822198638830ea0894ba06136a0e29cea7c05b9
downloadaudiocloud-53335ce936e758b816cce584665d1d55914b4ef4.tar.bz2
audiocloud-53335ce936e758b816cce584665d1d55914b4ef4.tar.xz
audiocloud-53335ce936e758b816cce584665d1d55914b4ef4.zip
Initial importHEADmaster
-rw-r--r--requirements.txt4
-rw-r--r--src/audiocloudweb.cfg7
-rw-r--r--src/get_music_url.py23
-rw-r--r--src/index_files.py58
-rw-r--r--src/index_search.py10
-rw-r--r--src/index_service.py27
-rw-r--r--src/indexer.py113
-rw-r--r--src/load_filesystem.py11
-rw-r--r--src/load_itunes.py326
-rw-r--r--src/parse_mp4.py67
-rw-r--r--src/parse_smart_playlist.py636
-rw-r--r--src/test.html16
-rw-r--r--src/test.py21
-rwxr-xr-xsrc/track_service.py132
-rw-r--r--src/util.py29
-rw-r--r--webapp/css/main.css55
-rwxr-xr-xwebapp/index.html36
-rwxr-xr-xwebapp/robots.txt3
-rw-r--r--webapp/test.css303
-rw-r--r--webapp/test.html145
-rw-r--r--webapp/vendor/backbone-1.1.2.js1608
-rwxr-xr-xwebapp/vendor/html5-boilerplate-4.3.0/.gitattributes1
-rwxr-xr-xwebapp/vendor/html5-boilerplate-4.3.0/.gitignore2
-rwxr-xr-xwebapp/vendor/html5-boilerplate-4.3.0/.htaccess551
-rwxr-xr-xwebapp/vendor/html5-boilerplate-4.3.0/css/main.css304
-rwxr-xr-xwebapp/vendor/html5-boilerplate-4.3.0/css/normalize.css527
-rw-r--r--webapp/vendor/jquery-2.1.1.js9190
-rw-r--r--webapp/vendor/spoticon.svg691
-rw-r--r--webapp/vendor/underscore-1.7.0.js1416
29 files changed, 16312 insertions, 0 deletions
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..4724c3a
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
1Whoosh==2.6.0
2boto==2.32.1
3bottle==0.12.7
4mutagen==1.24
diff --git a/src/audiocloudweb.cfg b/src/audiocloudweb.cfg
new file mode 100644
index 0000000..8df17d0
--- /dev/null
+++ b/src/audiocloudweb.cfg
@@ -0,0 +1,7 @@
1[audiocloudweb]
2access_key =
3secret_key =
4
5[audiocloud]
6access_key =
7secret_key =
diff --git a/src/get_music_url.py b/src/get_music_url.py
new file mode 100644
index 0000000..d4284d4
--- /dev/null
+++ b/src/get_music_url.py
@@ -0,0 +1,23 @@
1import sqlite3
2import urllib
3from util import SimpleConfigParser
4from boto.s3.connection import S3Connection
5
6# remove key metadata
7#key = key.copy(key.bucket.name, key.name, metadata={'Content-Type': 'audio/mp4'}, preserve_acl=True)
8
9db = sqlite3.connect('iTunesLibrary.db')
10curs = db.cursor()
11cfg = SimpleConfigParser('audiocloudweb.cfg', 'audiocloud')
12s3 = S3Connection(cfg.get('access_key'), cfg.get('secret_key'))
13bucket = s3.get_bucket('mecmusic')
14
15
16
17#curs.execute('select location from track where artist = 629 limit 1')
18curs.execute('select location from track where track_id = 29510')
19track = curs.fetchone()[0][6:]#.encode('utf-8')
20
21key = bucket.get_key(track, validate=True)
22key.metadata = {}
23print key.generate_url(60 * 10)
diff --git a/src/index_files.py b/src/index_files.py
new file mode 100644
index 0000000..ece51aa
--- /dev/null
+++ b/src/index_files.py
@@ -0,0 +1,58 @@
1import os
2import re
3import json
4import mutagen
5from pprint import pprint
6
7
8music = re.compile('.*\.(mp3|m4a)$')
9
10
11tags = set()
12
13
14def parse_frame(txt):
15 frame_type, remainder = txt.split(':', 1)
16 content = None
17
18 if remainder.startswith('http'):
19 remainder = remainder.split(':', 2)
20 content = remainder[-1]
21 remainder = ':'.join(remainder[:2])
22 elif ':' in remainder:
23 remainder, content = remainder.split(':', 1)
24
25 return frame_type, remainder, content
26
27
28for path, dirs, files in os.walk(os.path.expanduser('~/Desktop/Music')):
29 for file in files:
30 fullname = os.path.join(path, file)
31
32 if not music.match(fullname):
33 continue
34
35 file = mutagen.File(fullname)
36
37 if not file or not file.tags:
38 print "ERROR: ", fullname
39 continue
40
41 for tag, value in file.tags.items():
42 #if hasattr(value, 'text'):
43 # value = value.text
44
45 #if isinstance(value, list) and len(value) == 1:
46 # value = value[0]
47
48 #if tag == 'covr':
49 # continue
50
51 #if hasattr(value, 'mime') and value.mime.startswith('image'):
52 # continue
53
54 #if tag.startswith(('PRIV', 'APIC', 'COMM', 'USLT', 'WCOM')):
55 # continue
56
57 #if not isinstance(value, unicode):
58 print repr(tag), type(value), repr(value)
diff --git a/src/index_search.py b/src/index_search.py
new file mode 100644
index 0000000..805a9fb
--- /dev/null
+++ b/src/index_search.py
@@ -0,0 +1,10 @@
1from whoosh import index
2from whoosh.qparser import MultifieldParser
3
4idx = index.open_dir("indexdir")
5parser = MultifieldParser(["track_name", "artist", "album"], schema=idx.schema)
6
7with idx.searcher() as searcher:
8 results = searcher.search(parser.parse("nine inch nails"), groupedby="genre")
9 import pdb; pdb.set_trace()
10 True
diff --git a/src/index_service.py b/src/index_service.py
new file mode 100644
index 0000000..5038fce
--- /dev/null
+++ b/src/index_service.py
@@ -0,0 +1,27 @@
1from whoosh import index
2from whoosh.qparser import MultifieldParser
3
4import bottle
5from bottle import route, run, request
6
7
8@route('/search')
9def search():
10 term = request.query.get("q")
11
12 if not term:
13 return { 'error': 'No search term specified' }
14
15 idx = index.open_dir("indexdir")
16 parser = MultifieldParser(
17 ["track_name", "artist", "album"], schema=idx.schema)
18
19 with idx.searcher() as searcher:
20 results = searcher.search(parser.parse(term))
21 return { 'results': [dict(result) for result in results] }
22
23bottle.debug(True)
24app = bottle.default_app()
25
26#if __name__ == "__main__":
27run(host='localhost', port=8080)
diff --git a/src/indexer.py b/src/indexer.py
new file mode 100644
index 0000000..283cdbc
--- /dev/null
+++ b/src/indexer.py
@@ -0,0 +1,113 @@
1import sqlite3
2
3from whoosh import fields, index
4
5TRACK_QUERY = """
6SELECT
7 t.track_id, t.composer, t.explicit, t.disc_number, t.name as track_name,
8 t.track_number, t.year as track_year, g.name as genre, a.artist,
9 ab.title as album, ab.artist as album_artist, ab.compilation,
10 ab.disc_count, ab.gapless, ab.release_date, ab.track_count,
11 ab.year as album_year, p.bpm, p.bit_rate, p.sample_rate, p.total_time,
12 k.kind
13FROM
14 track t
15INNER JOIN
16 genre g
17ON t.genre = g.id
18INNER JOIN
19 artist a
20ON t.artist = a.id
21INNER JOIN
22 album ab
23ON t.album = ab.id
24INNER JOIN
25 track_physical p
26ON t.track_id = p.track_id
27INNER JOIN
28 kind k
29ON p.kind = k.id
30"""
31
32def safe_unicode(value):
33 return value
34 return value.decode("utf-8") if value else None
35
36def safe_int(value):
37 return int(value) if value is not None else None
38
39def to_boolean(value):
40 return 1 if value else 0
41
42def first_value(*items):
43 for item in items:
44 if item is not None:
45 return item
46
47 return None
48
49
50db = sqlite3.connect('iTunesLibrary.db')
51db.row_factory = sqlite3.Row
52
53curs = db.cursor()
54curs.execute(TRACK_QUERY)
55
56schema = fields.Schema(
57 track_id=fields.ID(stored=True),
58 composer=fields.TEXT(stored=True),
59 explicit=fields.BOOLEAN(stored=True),
60 disc_number=fields.NUMERIC(stored=True),
61
62 track_name=fields.NGRAM(stored=True),
63 genre=fields.NGRAM(stored=True),
64 artist=fields.NGRAM(stored=True),
65 album=fields.NGRAM(stored=True),
66
67 track_number=fields.NUMERIC(stored=True),
68 year=fields.NUMERIC(stored=True),
69 compilation=fields.BOOLEAN(stored=True),
70 disc_count=fields.NUMERIC(stored=True),
71 gapless=fields.BOOLEAN(stored=True),
72 release_date=fields.DATETIME(stored=True),
73 track_count=fields.NUMERIC(stored=True),
74 bpm=fields.NUMERIC(stored=True),
75 bit_rate=fields.NUMERIC(stored=True),
76 sample_rate=fields.NUMERIC(stored=True),
77 total_time=fields.NUMERIC(stored=True),
78 kind=fields.TEXT(stored=True)
79)
80
81idx = index.create_in("indexdir", schema)
82writer = idx.writer()
83
84for record in curs.fetchall():
85 writer.add_document(
86 track_id=str(record['track_id']).decode("ascii"),
87
88 composer=safe_unicode(record['composer']),
89 genre=safe_unicode(record['genre']),
90 album=safe_unicode(record['album']),
91 artist=safe_unicode(first_value(record['artist'], record['album_artist'])),
92 track_name=safe_unicode(record['track_name']),
93 kind=safe_unicode(record['kind']),
94
95 #release_date=record['release_date'],
96
97 explicit=to_boolean(record['explicit']),
98 compilation=to_boolean(record['compilation']),
99 gapless=to_boolean(record['gapless']),
100
101 disc_number=safe_int(record['disc_number']),
102 track_number=safe_int(record['track_number']),
103 year=safe_int(first_value(record['track_year'], record['album_year'])),
104 disc_count=safe_int(record['disc_count']),
105 track_count=safe_int(record['track_count']),
106 bpm=safe_int(record['bpm']),
107 bit_rate=safe_int(record['bit_rate']),
108 sample_rate=safe_int(record['sample_rate']),
109 total_time=safe_int(record['total_time']),
110 )
111
112writer.commit()
113db.close()
diff --git a/src/load_filesystem.py b/src/load_filesystem.py
new file mode 100644
index 0000000..6181017
--- /dev/null
+++ b/src/load_filesystem.py
@@ -0,0 +1,11 @@
1import sqlite3
2import codecs
3
4db = sqlite3.connect('iTunes/iTunesLibrary.db')
5curs = db.cursor()
6
7with codecs.open('tracks.txt', 'r', 'utf-8') as fp:
8 for track in fp:
9 curs.execute('insert into filesystem(location) values(?)', (track.strip(),))
10
11db.commit()
diff --git a/src/load_itunes.py b/src/load_itunes.py
new file mode 100644
index 0000000..f4131b1
--- /dev/null
+++ b/src/load_itunes.py
@@ -0,0 +1,326 @@
1import sqlite3
2import plistlib
3
4library = plistlib.readPlist('iTunes-Music-Library.xml')
5
6
7class BasicLibraryItem(object):
8
9 def get_insert_query(self):
10 return 'INSERT INTO {} VALUES ({})'.format(
11 self.TABLE_NAME, self.get_bind_string(self.COLUMN_COUNT))
12
13 @staticmethod
14 def get_bind_string(count):
15 return ('?,' * count)[:-1]
16
17 @staticmethod
18 def as_data_string(value):
19 if not value:
20 return None
21 else:
22 return value.asBase64()
23
24 @staticmethod
25 def as_boolean(value):
26 return 1 if value else 0
27
28 @staticmethod
29 def format_name(name):
30 return name.lower().replace(' ', '_')
31
32 @classmethod
33 def from_plist_entry(cls, entry):
34 self = cls()
35
36 for key, value in entry.items():
37 name = cls.format_name(key)
38
39 if not hasattr(self, name):
40 raise Exception("No attribute named %r" % name)
41
42 setattr(self, name, value)
43
44 return self
45
46
47class Playlist(BasicLibraryItem):
48
49 COLUMN_COUNT = 21
50 TABLE_NAME = 'playlist'
51
52 def __init__(self):
53 self.playlist_id = None
54 self.playlist_persistent_id = None
55 self.parent_persistent_id = None
56 self.distinguished_kind = None
57 self.genius_track_id = None
58 self.name = None
59
60 self.master = False
61 self.visible = False
62 self.all_items = False
63 self.folder = False
64
65 self.music = False
66 self.movies = False
67 self.tv_shows = False
68 self.podcasts = False
69 self.itunesu = False
70 self.audiobooks = False
71 self.books = False
72 self.purchased_music = False
73
74 self.smart_info = None
75 self.smart_criteria = None
76
77 self.items = []
78
79 def as_dbrow_tuple(self):
80 return (
81 self.playlist_id, #int
82 1, # user_id
83 self.playlist_persistent_id,
84 self.parent_persistent_id,
85 self.distinguished_kind, #int
86 self.genius_track_id, #int
87 self.name,
88
89 self.as_boolean(self.master),
90 self.as_boolean(self.visible),
91 self.as_boolean(self.all_items),
92 self.as_boolean(self.folder),
93 self.as_boolean(self.music),
94 self.as_boolean(self.movies),
95 self.as_boolean(self.tv_shows),
96 self.as_boolean(self.podcasts),
97 self.as_boolean(self.itunesu),
98 self.as_boolean(self.audiobooks),
99 self.as_boolean(self.books),
100 self.as_boolean(self.purchased_music),
101
102 self.as_data_string(self.smart_info),
103 self.as_data_string(self.smart_criteria)
104 )
105
106 @classmethod
107 def from_plist_entry(cls, entry):
108 self = cls()
109
110 for key, value in entry.items():
111 if key == 'Playlist Items':
112 for item in value:
113 self.items.append(item['Track ID'])
114
115 continue
116
117 name = cls.format_name(key)
118
119 if not hasattr(self, name):
120 raise Exception("No attribute named %r" % name)
121
122 setattr(self, name, value)
123
124 return self
125
126
127class Track(BasicLibraryItem):
128
129 COLUMN_COUNT = 53
130 TABLE_NAME = 'track'
131
132 def __init__(self):
133 self.album_rating = None
134 self.album_rating_computed = False
135 self.comments = None
136 self.volume_adjustment = None
137 self.unplayed = False
138 self.date_added = None
139 self.date_modified = None
140 self.disabled = False
141 self.play_count = None
142 self.play_date = None
143 self.play_date_utc = None
144 self.rating = None
145 self.skip_count = None
146 self.skip_date = None
147 self.track_id = None
148 self.persistent_id = None
149 self.library_folder_count = None
150 self.file_folder_count = None
151 self.location = None
152 self.track_type = None
153 self.file_type = None
154 self.artwork_count = None
155 self.hd = False
156 self.has_video = False
157 self.itunesu = False
158 self.tv_show = False
159 self.podcast = False
160 self.protected = False
161 self.purchased = False
162 self.movie = False
163 self.music_video = False
164 self.bpm = None
165 self.bit_rate = None
166 self.sample_rate = None
167 self.size = None
168 self.total_time = None
169 self.kind = None
170 self.video_height = None
171 self.video_width = None
172 self.sort_album = None
173 self.sort_album_artist = None
174 self.sort_artist = None
175 self.sort_composer = None
176 self.sort_name = None
177 self.sort_series = None
178 self.album = None
179 self.album_artist = None
180 self.artist = None
181 self.clean = False
182 self.compilation = False
183 self.composer = None
184 self.content_rating = None
185 self.disc_count = None
186 self.disc_number = None
187 self.episode = None
188 self.episode_order = None
189 self.explicit = False
190 self.genre = None
191 self.grouping = None
192 self.name = None
193 self.part_of_gapless_album = False
194 self.release_date = None
195 self.season = None
196 self.series = None
197 self.track_count = None
198 self.track_number = None
199 self.year = None
200
201 def as_dbrow_tuple(self):
202 return (
203 self.track_id,
204 self.persistent_id,
205 self.library_folder_count,
206 self.file_folder_count,
207 self.location,
208 self.track_type,
209 self.file_type,
210 self.artwork_count,
211 self.as_boolean(self.hd),
212 self.as_boolean(self.has_video),
213 self.as_boolean(self.itunesu),
214 self.as_boolean(self.tv_show),
215 self.as_boolean(self.podcast),
216 self.as_boolean(self.protected),
217 self.as_boolean(self.purchased),
218 self.as_boolean(self.movie),
219 self.as_boolean(self.music_video),
220 self.bpm,
221 self.bit_rate,
222 self.sample_rate,
223 self.size,
224 self.total_time,
225 self.kind,
226 self.video_height,
227 self.video_width,
228 self.sort_album,
229 self.sort_album_artist,
230 self.sort_artist,
231 self.sort_composer,
232 self.sort_name,
233 self.sort_series,
234 self.album,
235 self.album_artist,
236 self.artist,
237 self.as_boolean(self.clean),
238 self.as_boolean(self.compilation),
239 self.composer,
240 self.content_rating,
241 self.disc_count,
242 self.disc_number,
243 self.episode,
244 self.episode_order,
245 self.as_boolean(self.explicit),
246 self.genre,
247 self.grouping,
248 self.name,
249 self.as_boolean(self.part_of_gapless_album),
250 self.release_date,
251 self.season,
252 self.series,
253 self.track_count,
254 self.track_number,
255 self.year
256 )
257
258 def usermeta_as_dbrow_tuple(self):
259 return (
260 1,
261 self.track_id,
262 self.album_rating,
263 self.as_boolean(self.album_rating_computed),
264 self.comments,
265 self.volume_adjustment,
266 self.as_boolean(self.unplayed),
267 self.date_added,
268 self.date_modified,
269 self.as_boolean(self.disabled),
270 self.play_count,
271 self.play_date,
272 self.play_date_utc,
273 self.rating,
274 self.skip_count,
275 self.skip_date
276 )
277
278 USERMETA_COLUMN_COUNT = 16
279 USERMETA_TABLE_NAME = 'user_track_metadata'
280
281 def get_usermeta_insert_query(self):
282 return 'INSERT INTO {} VALUES ({})'.format(
283 self.USERMETA_TABLE_NAME,
284 self.get_bind_string(self.USERMETA_COLUMN_COUNT))
285
286
287assert library['Major Version'] == 1, "Invalid major version"
288assert library['Minor Version'] == 1, "Invalid minor version"
289
290def insert_playlists(db, library):
291 playlists = [Playlist.from_plist_entry(entry)
292 for entry in library['Playlists']]
293
294 curs = db.cursor()
295 track_insert_query = playlists[0].get_insert_query()
296
297 for playlist in playlists:
298 curs.execute(track_insert_query, playlist.as_dbrow_tuple())
299
300 for item in playlist.items:
301 curs.execute('INSERT INTO playlist_track VALUES (?, ?)',
302 (playlist.playlist_id, item))
303
304 db.commit()
305
306
307def insert_tracks(db, library):
308 music_folder = library['Music Folder']
309 tracks = [Track.from_plist_entry(entry)
310 for entry in library['Tracks'].values()]
311
312 curs = db.cursor()
313 track_insert_query = tracks[0].get_insert_query()
314 usermeta_insert_query = tracks[0].get_usermeta_insert_query()
315
316 for track in tracks:
317 curs.execute(track_insert_query, track.as_dbrow_tuple())
318 curs.execute(usermeta_insert_query, track.usermeta_as_dbrow_tuple())
319
320 db.commit()
321
322
323db = sqlite3.connect('iTunesLibrary.db')
324#insert_playlists(db, library)
325insert_tracks(db, library)
326db.close()
diff --git a/src/parse_mp4.py b/src/parse_mp4.py
new file mode 100644
index 0000000..3e92330
--- /dev/null
+++ b/src/parse_mp4.py
@@ -0,0 +1,67 @@
1from mutagen import mp4
2from mutagen.easyid3 import EasyID3
3
4
5class MP4Tags(mp4.MP4Tags):
6
7 fields = {
8 'cover': 'covr',
9 'tempo': 'tmpo',
10 'track_num': 'trkn',
11 'disc_num': 'disk',
12 'is_part_of_compilation': 'cpil',
13 'is_part_of_gapless_album': 'pgap',
14 'is_podcast': 'pcst',
15 'track_title': '\xa9nam',
16 'album': '\xa9alb',
17 'artist': '\xa9ART',
18 'album_artist': 'aART',
19 'composer': '\xa9wrt',
20 'year': '\xa9day',
21 'comment': '\xa9cmt',
22 'description': 'desc',
23 'purchase_date': 'purd',
24 'grouping': '\xa9grp',
25 'genre': '\xa9gen',
26 'lyrics': '\xa9lyr',
27 'podcast_url': 'purl',
28 'podcast_episode_id': 'egid',
29 'podcast_category': 'catg',
30 'podcast_keyword': 'keyw',
31 'encoded_by': '\xa9too',
32 'copyright': 'cprt',
33 'sort_album': 'soal',
34 'sort_album_artist': 'soaa',
35 'sort_artist': 'soar',
36 'sort_title': 'sonm',
37 'sort_composer': 'soco',
38 'sort_show': 'sosn',
39 'tv_show_name': 'tvsh',
40 }
41
42 @property
43 def track_number(self):
44 return self.track_num[0]
45
46 @property
47 def total_tracks(self):
48 return self.track_num[1]
49
50 @property
51 def disc_number(self):
52 return self.disc_num[0]
53
54 @property
55 def total_discs(self):
56 return self.disc_num[1]
57
58 def __getattr__(self, attr):
59 value = self[self.fields[attr]]
60 if len(value) == 1:
61 return value[0]
62 else:
63 return value
64
65
66class MP4(mp4.MP4):
67 MP4Tags = MP4Tags
diff --git a/src/parse_smart_playlist.py b/src/parse_smart_playlist.py
new file mode 100644
index 0000000..0bfde9d
--- /dev/null
+++ b/src/parse_smart_playlist.py
@@ -0,0 +1,636 @@
1# // http://banshee-itunes-import-plugin.googlecode.com/svn/trunk/
2# using System;
3# using System.Collections.Generic;
4# using System.Text;
5# using Banshee.SmartPlaylist;
6#
7# namespace Banshee.Plugins.iTunesImporter
8# {
9# internal struct SmartPlaylist
10# {
11# public string Query, Ignore, OrderBy, Name, Output;
12# public uint LimitNumber;
13# public byte LimitMethod;
14# }
15#
16# internal static partial class SmartPlaylistParser
17# {
18# private delegate bool KindEvalDel(Kind kind, string query);
19#
20# // INFO OFFSETS
21# //
22# // Offsets for bytes which...
23# const int MATCHBOOLOFFSET = 1; // determin whether logical matching is to be performed - Absolute offset
24# const int LIMITBOOLOFFSET = 2; // determin whether results are limited - Absolute offset
25# const int LIMITMETHODOFFSET = 3; // determin by what criteria the results are limited - Absolute offset
26# const int SELECTIONMETHODOFFSET = 7; // determin by what criteria limited playlists are populated - Absolute offset
27# const int LIMITINTOFFSET = 11; // determin the limited - Absolute offset
28# const int SELECTIONMETHODSIGNOFFSET = 13;// determin whether certain selection methods are "most" or "least" - Absolute offset
29#
30# // CRITERIA OFFSETS
31# //
32# // Offsets for bytes which...
33# const int LOGICTYPEOFFSET = 15; // determin whether all or any criteria must match - Absolute offset
34# const int FIELDOFFSET = 139; // determin what is being matched (Artist, Album, &c) - Absolute offset
35# const int LOGICSIGNOFFSET = 1; // determin whether the matching rule is positive or negative (e.g., is vs. is not) - Relative offset from FIELDOFFSET
36# const int LOGICRULEOFFSET = 4; // determin the kind of logic used (is, contains, begins, &c) - Relative offset from FIELDOFFSET
37# const int STRINGOFFSET = 54; // begin string data - Relative offset from FIELDOFFSET
38# const int INTAOFFSET = 60; // begin the first int - Relative offset from FIELDOFFSET
39# const int INTBOFFSET = 24; // begin the second int - Relative offset from INTAOFFSET
40# const int TIMEMULTIPLEOFFSET = 76;// begin the int with the multiple of time - Relative offset from FIELDOFFSET
41# const int TIMEVALUEOFFSET = 68; // begin the inverse int with the value of time - Relative offset from FIELDOFFSET
42#
43# const int INTLENGTH = 64; // The length on a int criteria starting at the first int
44# static DateTime STARTOFTIME = new DateTime(1904, 1, 1); // Dates are recorded as seconds since Jan 1, 1904
45#
46# static bool or, again;
47# static string conjunctionOutput, conjunctionQuery, output, query, ignore;
48# static int offset, logicSignOffset,logicRulesOffset, stringOffset, intAOffset, intBOffset,
49# timeMultipleOffset, timeValueOffset;
50# static byte[] info, criteria;
51#
52# static KindEvalDel KindEval;
53#
54# public static SmartPlaylist Parse(byte[] i, byte[] c)
55# {
56# info = i;
57# criteria = c;
58# SmartPlaylist result = new SmartPlaylist();
59# offset = FIELDOFFSET;
60# output = "";
61# query = "";
62# ignore = "";
63#
64# if(info[MATCHBOOLOFFSET] == 1) {
65# or = (criteria[LOGICTYPEOFFSET] == 1) ? true : false;
66# if(or) {
67# conjunctionQuery = " OR ";
68# conjunctionOutput = " or\n";
69# } else {
70# conjunctionQuery = " AND ";
71# conjunctionOutput = " and\n";
72# }
73# do {
74# again = false;
75# logicSignOffset = offset + LOGICSIGNOFFSET;
76# logicRulesOffset = offset + LOGICRULEOFFSET;
77# stringOffset = offset + STRINGOFFSET;
78# intAOffset = offset + INTAOFFSET;
79# intBOffset = intAOffset + INTBOFFSET;
80# timeMultipleOffset = offset + TIMEMULTIPLEOFFSET;
81# timeValueOffset = offset + TIMEVALUEOFFSET;
82#
83# if(Enum.IsDefined(typeof(StringFields), (int)criteria[offset])) {
84# ProcessStringField();
85# } else if(Enum.IsDefined(typeof(IntFields), (int)criteria[offset])) {
86# ProcessIntField();
87# } else if(Enum.IsDefined(typeof(DateFields), (int)criteria[offset])) {
88# ProcessDateField();
89# } else {
90# ignore += "Not processed";
91# }
92# }
93# while(again);
94# }
95# result.Output = output;
96# result.Query = query;
97# result.Ignore = ignore;
98# if(info[LIMITBOOLOFFSET] == 1) {
99# uint limit = BytesToUInt(info, LIMITINTOFFSET);
100# result.LimitNumber = (info[LIMITMETHODOFFSET] == (byte)LimitMethods.GB) ? limit * 1024 : limit;
101# if(output.Length > 0) {
102# output += "\n";
103# }
104# output += "Limited to " + limit.ToString() + " " +
105# Enum.GetName(typeof(LimitMethods), (int)info[LIMITMETHODOFFSET]) + " selected by ";
106# switch(info[LIMITMETHODOFFSET]) {
107# case (byte)LimitMethods.Items:
108# result.LimitMethod = 0;
109# break;
110# case (byte)LimitMethods.Minutes:
111# result.LimitMethod = 1;
112# break;
113# case (byte)LimitMethods.Hours:
114# result.LimitMethod = 2;
115# break;
116# case (byte)LimitMethods.MB:
117# result.LimitMethod = 3;
118# break;
119# case (byte)LimitMethods.GB:
120# goto case (byte)LimitMethods.MB;
121# }
122# switch(info[SELECTIONMETHODOFFSET]) {
123# case (byte)SelectionMethods.Random:
124# output += "random";
125# result.OrderBy = "RANDOM()";
126# break;
127# case (byte)SelectionMethods.HighestRating:
128# output += "highest rated";
129# result.OrderBy = "Rating DESC";
130# break;
131# case (byte)SelectionMethods.LowestRating:
132# output += "lowest rated";
133# result.OrderBy = "Rating ASC";
134# break;
135# case (byte)SelectionMethods.RecentlyPlayed:
136# output += (info[SELECTIONMETHODSIGNOFFSET] == 0)
137# ? "most recently played" : "least recently played";
138# result.OrderBy = (info[SELECTIONMETHODSIGNOFFSET] == 0)
139# ? "LastPlayedStamp DESC" : "LastPlayedStamp ASC";
140# break;
141# case (byte)SelectionMethods.OftenPlayed:
142# output += (info[SELECTIONMETHODSIGNOFFSET] == 0)
143# ? "most often played" : "least often played";
144# result.OrderBy = (info[SELECTIONMETHODSIGNOFFSET] == 0)
145# ? "NumberOfPlays DESC" : "NumberOfPlays ASC";
146# break;
147# case (byte)SelectionMethods.RecentlyAdded:
148# output += (info[SELECTIONMETHODSIGNOFFSET] == 0)
149# ? "most recently added" : "least recently added";
150# result.OrderBy = (info[SELECTIONMETHODSIGNOFFSET] == 0)
151# ? "DateAddedStamp DESC" : "DateAddedStamp ASC";
152# break;
153# default:
154# result.OrderBy = Enum.GetName(typeof(SelectionMethods), (int)info[SELECTIONMETHODOFFSET]);
155# break;
156# }
157# }
158# if(ignore.Length > 0) {
159# output += "\n\nIGNORING:\n" + ignore;
160# }
161#
162# if(query.Length > 0) {
163# output += "\n\nQUERY:\n" + query;
164# }
165# return result;
166# }
167#
168# private static void ProcessStringField()
169# {
170# bool end = false;
171# string workingOutput = Enum.GetName(typeof(StringFields), criteria[offset]);
172# string workingQuery = "(lower(" + Enum.GetName(typeof(StringFields), criteria[offset]) + ")";
173# switch(criteria[logicRulesOffset]) {
174# case (byte)LogicRule.Contains:
175# if((criteria[logicSignOffset] == (byte)LogicSign.StringPositive)) {
176# workingOutput += " contains ";
177# workingQuery += " LIKE '%";
178# } else {
179# workingOutput += " does not contain ";
180# workingQuery += " NOT LIKE '%";
181# }
182# if(criteria[offset] == (byte)StringFields.Kind) {
183# KindEval = delegate(Kind kind, string query) {
184# return (kind.Name.IndexOf(query) != -1);
185# };
186# }
187# end = true;
188# break;
189# case (byte)LogicRule.Is:
190# if((criteria[logicSignOffset] == (byte)LogicSign.StringPositive)) {
191# workingOutput += " is ";
192# workingQuery += " = '";
193# } else {
194# workingOutput += " is not ";
195# workingQuery += " != '";
196# }
197# if(criteria[offset] == (byte)StringFields.Kind) {
198# KindEval = delegate(Kind kind, string query) {
199# return (kind.Name == query);
200# };
201# }
202# break;
203# case (byte)LogicRule.Starts:
204# workingOutput += " starts with ";
205# workingQuery += " LIKE '";
206# if(criteria[offset] == (byte)StringFields.Kind) {
207# KindEval = delegate (Kind kind, string query) {
208# return (kind.Name.IndexOf(query) == 0);
209# };
210# }
211# end = true;
212# break;
213# case (byte)LogicRule.Ends:
214# workingOutput += " ends with ";
215# workingQuery += " LIKE '%";
216# if(criteria[offset] == (byte)StringFields.Kind) {
217# KindEval = delegate (Kind kind, string query) {
218# return (kind.Name.IndexOf(query) == (kind.Name.Length - query.Length));
219# };
220# }
221# break;
222# }
223# workingOutput += "\"";
224# byte[] character = new byte[1];
225# string content = "";
226# bool onByte = true;
227# for(int i = (stringOffset); i < criteria.Length; i++) {
228# // Off bytes are 0
229# if(onByte) {
230# // If the byte is 0 and it's not the last byte,
231# // we have another condition
232# if(criteria[i] == 0 && i != (criteria.Length - 1)) {
233# again = true;
234# FinishStringField(content, workingOutput, workingQuery, end);
235# offset = i + 2;
236# return;
237# }
238# character[0] = criteria[i];
239# content += Encoding.UTF8.GetString(character);
240# }
241# onByte = !onByte;
242# }
243# FinishStringField(content, workingOutput, workingQuery, end);
244# }
245#
246# private static void FinishStringField(string content, string workingOutput, string workingQuery, bool end)
247# {
248# workingOutput += content;
249# workingOutput += "\" ";
250# bool failed = false;
251# if(criteria[offset] == (byte)StringFields.Kind) {
252# workingQuery = "";
253# foreach(Kind kind in Kinds) {
254# if(KindEval(kind, content)) {
255# if(workingQuery.Length > 0) {
256# if((query.Length == 0 && !again) || or) {
257# workingQuery += " OR ";
258# } else {
259# failed = true;
260# break;
261# }
262# }
263# workingQuery += "(lower(Uri)";
264# workingQuery += ((criteria[logicSignOffset] == (byte)LogicSign.StringPositive))
265# ? " LIKE '%" + kind.Extension + "')" : " NOT LIKE '%" + kind.Extension + "%')";
266# }
267# }
268# } else {
269# workingQuery += content.ToLower();
270# workingQuery += (end) ? "%')" : "')";
271# }
272# if(Enum.IsDefined(typeof(IgnoreStringFields),
273# (int)criteria[offset]) || failed) {
274# if(ignore.Length > 0) {
275# ignore += conjunctionOutput;
276# }
277# ignore += workingOutput;
278# } else {
279# if(output.Length > 0) {
280# output += conjunctionOutput;
281# }
282# if(query.Length > 0) {
283# query += conjunctionQuery;
284# }
285# output += workingOutput;
286# query += workingQuery;
287# }
288# }
289#
290# private static void ProcessIntField()
291# {
292# string workingOutput = Enum.GetName(typeof(IntFields), criteria[offset]);
293# string workingQuery = "(" + Enum.GetName(typeof(IntFields), criteria[offset]);
294#
295# switch(criteria[logicRulesOffset]) {
296# case (byte)LogicRule.Is:
297# if(criteria[logicSignOffset] == (byte)LogicSign.IntPositive) {
298# workingOutput += " is ";
299# workingQuery += " = ";
300# } else {
301# workingOutput += " is not ";
302# workingQuery += " != ";
303# }
304# goto case 255;
305# case (byte)LogicRule.Greater:
306# workingOutput += " is greater than ";
307# workingQuery += " > ";
308# goto case 255;
309# case (byte)LogicRule.Less:
310# workingOutput += " is less than ";
311# workingQuery += " > ";
312# goto case 255;
313# case 255:
314# uint number = (criteria[offset] == (byte)IntFields.Rating)
315# ? (BytesToUInt(criteria, intAOffset) / 20) : BytesToUInt(criteria, intAOffset);
316# workingOutput += number.ToString();
317# workingQuery += number.ToString();
318# break;
319# case (byte)LogicRule.Other:
320# if(criteria[logicSignOffset + 2] == 1) {
321# workingOutput += " is in the range of ";
322# workingQuery += " BETWEEN ";
323# uint num = (criteria[offset] == (byte)IntFields.Rating)
324# ? (BytesToUInt(criteria, intAOffset) / 20) : BytesToUInt(criteria, intAOffset);
325# workingOutput += num.ToString();
326# workingQuery += num.ToString();
327# workingOutput += " to ";
328# workingQuery += " AND ";
329# num = (criteria[offset] == (byte)IntFields.Rating)
330# ? ((BytesToUInt(criteria, intBOffset) - 19) / 20) : BytesToUInt(criteria, intBOffset);
331# workingOutput += num.ToString();
332# workingQuery += num.ToString();
333# }
334# break;
335# }
336# workingQuery += ")";
337# if(Enum.IsDefined(typeof(IgnoreIntFields),
338# (int)criteria[offset])) {
339# if(ignore.Length > 0) {
340# ignore += conjunctionOutput;
341# }
342# ignore += workingOutput;
343# } else {
344# if(output.Length > 0) {
345# output += conjunctionOutput;
346# }
347# if(query.Length > 0) {
348# query += conjunctionQuery;
349# }
350# output += workingOutput;
351# query += workingQuery;
352# }
353# offset = intAOffset + INTLENGTH;
354# if(criteria.Length > offset) {
355# again = true;
356# }
357# }
358#
359# private static void ProcessDateField()
360# {
361# bool isIgnore = false;
362# string workingOutput = Enum.GetName(typeof(DateFields), criteria[offset]);
363# string workingQuery = "((strftime(\"%s\", current_timestamp) - DateAddedStamp + 3600)";
364# switch(criteria[logicRulesOffset]) {
365# case (byte)LogicRule.Greater:
366# workingOutput += " is after ";
367# workingQuery += " > ";
368# goto case 255;
369# case (byte)LogicRule.Less:
370# workingOutput += " is before ";
371# workingQuery += " > ";
372# goto case 255;
373# case 255:
374# isIgnore = true;
375# DateTime time = BytesToDateTime(criteria, intAOffset);
376# workingOutput += time.ToString();
377# workingQuery += ((int)DateTime.Now.Subtract(time).TotalSeconds).ToString();
378# break;
379# case (byte)LogicRule.Other:
380# if(criteria[logicSignOffset + 2] == 1) {
381# isIgnore = true;
382# DateTime t2 = BytesToDateTime(criteria, intAOffset);
383# DateTime t1 = BytesToDateTime(criteria, intBOffset);
384# if(criteria[logicSignOffset] == (byte)LogicSign.IntPositive) {
385# workingOutput += " is in the range of ";
386# workingQuery += " BETWEEN " +
387# ((int)DateTime.Now.Subtract(t1).TotalSeconds).ToString() +
388# " AND " +
389# ((int)DateTime.Now.Subtract(t2).TotalSeconds).ToString();
390# } else {
391# workingOutput += " is not in the range of ";
392# }
393# workingOutput += t1.ToString();
394# workingOutput += " to ";
395# workingOutput += t2.ToString();
396# } else if(criteria[logicSignOffset + 2] == 2) {
397# if(criteria[logicSignOffset] == (byte)LogicSign.IntPositive) {
398# workingOutput += " is in the last ";
399# workingQuery += " < ";
400# } else {
401# workingOutput += " is not in the last ";
402# workingQuery += " > ";
403# }
404# uint t = InverseBytesToUInt(criteria, timeValueOffset);
405# uint multiple = BytesToUInt(criteria, timeMultipleOffset);
406# workingQuery += (t * multiple).ToString();
407# workingOutput += t.ToString() + " ";
408# switch(multiple) {
409# case 86400:
410# workingOutput += "days";
411# break;
412# case 604800:
413# workingOutput += "weeks";
414# break;
415# case 2628000:
416# workingOutput += "months";
417# break;
418# }
419# }
420# break;
421# }
422# workingQuery += ")";
423# if(isIgnore || Enum.IsDefined(typeof(IgnoreDateFields), (int)criteria[offset])) {
424# if(ignore.Length > 0) {
425# ignore += conjunctionOutput;
426# }
427# ignore += workingOutput;
428# } else {
429# if(output.Length > 0) {
430# output += conjunctionOutput;
431# }
432# output += workingOutput;
433# if(query.Length > 0) {
434# query += conjunctionQuery;
435# }
436# query += workingQuery;
437# }
438# offset = intAOffset + INTLENGTH;
439# if(criteria.Length > offset) {
440# again = true;
441# }
442# }
443#
444# /// <summary>
445# /// Converts 4 bytes to a uint
446# /// </summary>
447# /// <param name="byteArray">A byte array</param>
448# /// <param name="offset">Should be the byte of the uint with the 0th-power position</param>
449# /// <returns></returns>
450# private static uint BytesToUInt(byte[] byteArray, int offset)
451# {
452# uint output = 0;
453# for (byte i = 0; i <= 4; i++) {
454# output += (uint)(byteArray[offset - i] * Math.Pow(2, (8 * i)));
455# }
456# return output;
457# }
458#
459# private static uint InverseBytesToUInt(byte[] byteArray, int offset)
460# {
461# uint output = 0;
462# for (byte i = 0; i <= 4; i++) {
463# output += (uint)((255 - (uint)(byteArray[offset - i])) * Math.Pow(2, (8 * i)));
464# }
465# return ++output;
466# }
467#
468# private static DateTime BytesToDateTime (byte[] byteArray, int offset)
469# {
470# uint number = BytesToUInt(byteArray, offset);
471# return STARTOFTIME.AddSeconds(number);
472# }
473# }
474# }
475# namespace Banshee.Plugins.iTunesImporter
476# {
477# internal struct Kind
478# {
479# public string Name, Extension;
480# public Kind(string name, string extension)
481# {
482# Name = name;
483# Extension = extension;
484# }
485# }
486#
487# internal partial class SmartPlaylistParser
488# {
489# private static Kind[] Kinds = {
490# new Kind("Protected AAC audio file", ".m4p"),
491# new Kind("MPEG audio file", ".mp3"),
492# new Kind("AIFF audio file", ".aiff"),
493# new Kind("WAV audio file", ".wav"),
494# new Kind("QuickTime movie file", ".mov"),
495# new Kind("MPEG-4 video file", ".mp4"),
496# new Kind("AAC audio file", ".m4a")
497# };
498#
499# /// <summary>
500# /// The methods by which the number of songs in a playlist are limited
501# /// </summary>
502# private enum LimitMethods
503# {
504# Minutes = 0x01,
505# MB = 0x02,
506# Items = 0x03,
507# Hours = 0x04,
508# GB = 0x05,
509# }
510# /// <summary>
511# /// The methods by which songs are selected for inclusion in a limited playlist
512# /// </summary>
513# private enum SelectionMethods
514# {
515# Random = 0x02,
516# Title = 0x05,
517# AlbumTitle = 0x06,
518# Artist = 0x07,
519# Genre = 0x09,
520# HighestRating = 0x1c,
521# LowestRating = 0x01,
522# RecentlyPlayed = 0x1a,
523# OftenPlayed = 0x19,
524# RecentlyAdded = 0x15
525# }
526# /// <summary>
527# /// The matching criteria which take string data
528# /// </summary>
529# private enum StringFields
530# {
531# AlbumTitle = 0x03,
532# AlbumArtist = 0x47,
533# Artist = 0x04,
534# Category = 0x37,
535# Comments = 0x0e,
536# Composer = 0x12,
537# Description = 0x36,
538# Genre = 0x08,
539# Grouping = 0x27,
540# Kind = 0x09,
541# Title = 0x02,
542# Show = 0x3e
543# }
544# /// <summary>
545# /// The matching criteria which take integer data
546# /// </summary>
547# private enum IntFields
548# {
549# BPM = 0x23,
550# BitRate = 0x05,
551# Compilation = 0x1f,
552# DiskNumber = 0x18,
553# NumberOfPlays = 0x16,
554# Rating = 0x19,
555# Playlist = 0x28, // FIXME Move this?
556# Podcast = 0x39,
557# SampleRate = 0x06,
558# Season = 0x3f,
559# Size = 0x0c,
560# SkipCount = 0x44,
561# Duration = 0x0d,
562# TrackNumber = 0x0b,
563# VideoKind = 0x3c,
564# Year = 0x07
565# }
566# /// <summary>
567# /// The matching criteria which take date data
568# /// </summary>
569# private enum DateFields
570# {
571# DateAdded = 0x10,
572# DateModified = 0x0a,
573# LastPlayed = 0x17,
574# LastSkipped = 0x45
575# }
576# /// <summary>
577# /// The matching criteria which we do no handle
578# /// </summary>
579# private enum IgnoreStringFields
580# {
581# AlbumArtist = 0x47,
582# Category = 0x37,
583# Comments = 0x0e,
584# Composer = 0x12,
585# Description = 0x36,
586# Grouping = 0x27,
587# Show = 0x3e
588# }
589# /// <summary>
590# /// The matching criteria which we do no handle
591# /// </summary>
592# private enum IgnoreIntFields
593# {
594# BPM = 0x23,
595# BitRate = 0x05,
596# Compilation = 0x1f,
597# DiskNumber = 0x18,
598# Playlist = 0x28,
599# Podcast = 0x39,
600# SampleRate = 0x06,
601# Season = 0x3f,
602# Size = 0x0c,
603# SkipCount = 0x44,
604# TrackNumber = 0x0b,
605# VideoKind = 0x3c
606# }
607# private enum IgnoreDateFields
608# {
609# DateModified = 0x0a,
610# LastSkipped = 0x45
611# }
612# /// <summary>
613# /// The signs which apply to different kinds of logic (is vs. is not, contains vs. doesn't contain, etc.)
614# /// </summary>
615# private enum LogicSign
616# {
617# IntPositive = 0x00,
618# StringPositive = 0x01,
619# IntNegative = 0x02,
620# StringNegative = 0x03
621# }
622# /// <summary>
623# /// The logical rules
624# /// </summary>
625# private enum LogicRule
626# {
627# Other = 0x00,
628# Is = 0x01,
629# Contains = 0x02,
630# Starts = 0x04,
631# Ends = 0x08,
632# Greater = 0x10,
633# Less = 0x40
634# }
635# }
636# }
diff --git a/src/test.html b/src/test.html
new file mode 100644
index 0000000..b1636dd
--- /dev/null
+++ b/src/test.html
@@ -0,0 +1,16 @@
1<!doctype html>
2<html class="no-js" lang="">
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <title></title>
7 <meta name="description" content="">
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9 </head>
10 <body>
11 <audio controls>
12 <source src="https://mecmusic.s3.amazonaws.com/Katy%20Perry/E.T.%20%28feat.%20Kanye%20West%29%20-%20Single/01%20E.T.%20%28feat.%20Kayne%20West%29.m4a?Signature=H59mUAn6GVYQKs%2B3OpNCWkehGME%3D&Expires=1410061622&AWSAccessKeyId=AKIAJBVOGJDEU5V22WJA&x-amz-meta-s3cmd-attrs=uid%3A501/gname%3Astaff/uname%3Amcrute/gid%3A20/mode%3A33216/mtime%3A1385081486/atime%3A1409625877/ctime%3A1408591516">
13 Your browser does not support the audio element.
14 </audio>
15 </body>
16</html>
diff --git a/src/test.py b/src/test.py
new file mode 100644
index 0000000..3f5ccd8
--- /dev/null
+++ b/src/test.py
@@ -0,0 +1,21 @@
1import sqlite3
2
3def unfuck_unicode(text):
4 return ''.join([chr(n) for n in [ord(i) for i in text]]).decode('utf-8')
5
6conn = sqlite3.connect('iTunesLibrary.db')
7curs = conn.cursor()
8upcurs = conn.cursor()
9
10curs.execute('select track_id, location from track where location is not null')
11
12
13for id, datum in curs.fetchall():
14 try:
15 datum.decode('utf-8')
16 except UnicodeEncodeError:
17 print id, type(datum), datum.encode('utf-8')
18 #upcurs.execute('update track set location = ? where track_id = ?',
19 # (datum.encode('utf-8'), id))
20
21conn.commit()
diff --git a/src/track_service.py b/src/track_service.py
new file mode 100755
index 0000000..4a5a149
--- /dev/null
+++ b/src/track_service.py
@@ -0,0 +1,132 @@
1#!/usr/bin/env python
2
3import sqlite3
4import bottle
5import urllib
6
7db = sqlite3.connect('iTunesLibrary.db')
8db.row_factory = sqlite3.Row
9
10ARTIST_COUNT_QUERY = """
11select a.*, count(t.track_id) as total_tracks
12from track t
13inner join artist a on t.artist = a.id
14{where}
15group by t.artist
16"""
17
18GENRE_COUNT_QUERY = """
19select g.*, count(t.track_id) as total_tracks
20from track t
21inner join genre g on t.genre = g.id
22{where}
23group by t.genre
24"""
25
26ALBUM_COUNT_QUERY = """
27select a.id, a.title, count(t.track_id) as total_tracks
28from track t
29inner join album a on t.album = a.id
30{where}
31group by t.album
32"""
33
34TRACK_QUERY = """
35select
36t.track_id, t.name, t.track_number, t.disc_number,
37ar.artist,
38ab.title, ab.track_count, ab.disc_count,
39g.name
40from track t
41inner join artist ar on t.artist = ar.id
42inner join album ab on t.album = ab.id
43inner join genre g on t.genre = g.id
44{where}
45"""
46
47def _format_json(curs):
48 data = []
49
50 for item in curs.fetchall():
51 data.append({
52 'id': item[0],
53 'name': item[1].encode('utf-8'),
54 'tracks': item[2],
55 })
56
57 return data
58
59
60def _run_query(curs, query, where="", params=None):
61 query = query.format(where=where)
62
63 if params:
64 curs.execute(query, params)
65 else:
66 curs.execute(query)
67
68
69def _build_where(query):
70 where = []
71 params = []
72
73 if 'genre' in query:
74 where.append('t.genre = ?')
75 params.append(query['genre'])
76
77 if 'artist' in query:
78 where.append('t.artist = ?')
79 params.append(query['artist'])
80
81 if 'album' in query:
82 where.append('t.album = ?')
83 params.append(query['album'])
84
85 if where:
86 where = 'WHERE ' + ' AND '.join(where)
87 else:
88 where = ""
89
90 return where, params
91
92
93@bottle.route('/genre')
94def genre_controller():
95 curs = db.cursor()
96 curs.execute(GENRE_COUNT_QUERY.format(where=""))
97 return { 'data': _format_json(curs) }
98
99
100@bottle.route('/browser')
101def browser_controller():
102 curs = db.cursor()
103 where, params = _build_where(bottle.request.query)
104
105 _run_query(curs, ARTIST_COUNT_QUERY, where, params)
106 artists = _format_json(curs)
107
108 _run_query(curs, GENRE_COUNT_QUERY, where, params)
109 genres = _format_json(curs)
110
111 _run_query(curs, ALBUM_COUNT_QUERY, where, params)
112 albums = _format_json(curs)
113
114 return {
115 'data': {
116 'artists': artists,
117 'genres': genres,
118 'albums': albums,
119 }
120 }
121
122
123@bottle.route('/tracks')
124def tracks_controller():
125 curs = db.cursor()
126 where, params = _build_where(bottle.request.query)
127 _run_query(curs, TRACK_QUERY, where, params)
128 return { 'data': [dict(row) for row in curs.fetchall()] }
129
130
131bottle.debug(True)
132bottle.run(host='localhost', port=8100)
diff --git a/src/util.py b/src/util.py
new file mode 100644
index 0000000..ff1df56
--- /dev/null
+++ b/src/util.py
@@ -0,0 +1,29 @@
1from ConfigParser import SafeConfigParser
2
3class SimpleConfigParser(SafeConfigParser, object):
4 """SafeConfigParser that auto-loads files
5
6 This class also supports a more terse form of get that uses the default
7 section which can be passed to the constructor.
8 """
9
10 def __init__(self, filename, default_section=None):
11 super(SimpleConfigParser, self).__init__()
12 self.default_section = default_section
13
14 with open(filename) as fp:
15 self.readfp(fp)
16
17 def get(self, section, option=None):
18 """Get that allows skipping section
19
20 This can be called with one or two arguments. The two argument form is
21 the same as ConfigParser. The one argument form allows skipping the
22 section if the class has a default_section set.
23 """
24 default_get = super(SimpleConfigParser, self).get
25
26 if not option and self.default_section:
27 return default_get(self.default_section, section)
28 else:
29 return default_get(section, option)
diff --git a/webapp/css/main.css b/webapp/css/main.css
new file mode 100644
index 0000000..fecb981
--- /dev/null
+++ b/webapp/css/main.css
@@ -0,0 +1,55 @@
1@font-face {
2 font-family: "spoticon";
3 src: url("../vendor/spoticon.svg") format("svg"); /* ,url("https://glue-static.s3-external-3.amazonaws.com/fonts/spoticon_1d2b9f586650bafedbd44381e1efa36b.woff") format("woff"),url("https://glue-static.s3-external-3.amazonaws.com/fonts/spoticon_1d2b9f586650bafedbd44381e1efa36b.ttf") format("truetype"); */
4 font-weight: normal;
5 font-style:normal;
6}
7
8
9
10
11#main-navigation, #main-area, #player {
12 position: absolute;
13 top: 0;
14 bottom: 0;
15}
16
17#main-navigation, #player {
18 width: 20%;
19 background: #CCC;
20 padding: 1em;
21}
22
23#main-navigation {
24 left: 0;
25}
26
27#main-area {
28 left: 0;
29 right: 0;
30 padding-right: 20%;
31 padding-left: 20%;
32}
33
34#player {
35 right: 0;
36}
37
38
39
40
41
42[class^="spoticon-"]:before, [class*="spoticon-"]:before {
43 font-family:"spoticon";
44 font-style:normal;
45 font-weight:normal;
46 -webkit-font-smoothing:antialiased;
47 -moz-osx-font-smoothing:grayscale;
48 line-height:inherit;
49 vertical-align:bottom;
50 display:inline-block;
51 text-decoration:inherit;
52}
53
54.spoticon-add-to-playlist:before { content: "\f160"; font-size: 32px; }
55
diff --git a/webapp/index.html b/webapp/index.html
new file mode 100755
index 0000000..2e98565
--- /dev/null
+++ b/webapp/index.html
@@ -0,0 +1,36 @@
1<!DOCTYPE html>
2<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
3<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
4<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
5<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
6 <head>
7 <meta charset="utf-8">
8 <meta http-equiv="X-UA-Compatible" content="IE=edge">
9 <title></title>
10 <meta name="description" content="">
11 <meta name="viewport" content="width=device-width, initial-scale=1">
12
13 <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
14
15 <link rel="stylesheet" href="vendor/html5-boilerplate-4.3.0/css/normalize.css">
16 <link rel="stylesheet" href="vendor/html5-boilerplate-4.3.0/css/main.css">
17 <link rel="stylesheet" href="css/main.css">
18 </head>
19 <body>
20 <section id="main-navigation">
21 <p class="spoticon-add-to-playlist">Foobear</p>
22 </section>
23
24 <section id="main-area">
25 Foobear
26 </section>
27
28 <section id="player">
29 Foobear
30 </section>
31
32 <script src="vendor/jquery-2.1.1.js"></script>
33 <script src="vendor/underscore-1.7.0.js"></script>
34 <script src="vendor/backbone-1.1.2.js"></script>
35 </body>
36</html>
diff --git a/webapp/robots.txt b/webapp/robots.txt
new file mode 100755
index 0000000..ee2cc21
--- /dev/null
+++ b/webapp/robots.txt
@@ -0,0 +1,3 @@
1# robotstxt.org/
2
3User-agent: *
diff --git a/webapp/test.css b/webapp/test.css
new file mode 100644
index 0000000..7ac5fba
--- /dev/null
+++ b/webapp/test.css
@@ -0,0 +1,303 @@
1@font-face {
2 font-family: "spoticon";
3 src: url("vendor/spoticon.svg") format("svg");
4 font-weight: normal;
5 font-style:normal;
6}
7
8li:before {
9 font-family:"spoticon";
10 font-style:normal;
11 font-weight:normal;
12 -webkit-font-smoothing:antialiased;
13 -moz-osx-font-smoothing:grayscale;
14 line-height:inherit;
15 vertical-align:bottom;
16 display:inline-block;
17 text-decoration:inherit;
18}
19
20li { list-style: none; display: inline-block; height: 32px; width: 32px; border: 1px solid #CCC; margin: 10px;}
21
22.font-100:before { content: "\f100"; font-size: 32px; }
23.font-101:before { content: "\f101"; font-size: 32px; }
24.font-102:before { content: "\f102"; font-size: 32px; }
25.font-103:before { content: "\f103"; font-size: 32px; }
26.font-104:before { content: "\f104"; font-size: 32px; }
27.font-105:before { content: "\f105"; font-size: 32px; }
28.font-106:before { content: "\f106"; font-size: 32px; }
29.font-107:before { content: "\f107"; font-size: 32px; }
30.font-108:before { content: "\f108"; font-size: 32px; }
31.font-109:before { content: "\f109"; font-size: 32px; }
32.font-10a:before { content: "\f10a"; font-size: 32px; }
33.font-10b:before { content: "\f10b"; font-size: 32px; }
34.font-10c:before { content: "\f10c"; font-size: 32px; }
35.font-10d:before { content: "\f10d"; font-size: 32px; }
36.font-10e:before { content: "\f10e"; font-size: 32px; }
37.font-10f:before { content: "\f10f"; font-size: 32px; }
38.font-110:before { content: "\f110"; font-size: 32px; }
39.font-111:before { content: "\f111"; font-size: 32px; }
40.font-112:before { content: "\f112"; font-size: 32px; }
41.font-113:before { content: "\f113"; font-size: 32px; }
42.font-114:before { content: "\f114"; font-size: 32px; }
43.font-115:before { content: "\f115"; font-size: 32px; }
44.font-116:before { content: "\f116"; font-size: 32px; }
45.font-117:before { content: "\f117"; font-size: 32px; }
46.font-11a:before { content: "\f11a"; font-size: 32px; }
47.font-11b:before { content: "\f11b"; font-size: 32px; }
48.font-11c:before { content: "\f11c"; font-size: 32px; }
49.font-11d:before { content: "\f11d"; font-size: 32px; }
50.font-11e:before { content: "\f11e"; font-size: 32px; }
51.font-11f:before { content: "\f11f"; font-size: 32px; }
52.font-120:before { content: "\f120"; font-size: 32px; }
53.font-121:before { content: "\f121"; font-size: 32px; }
54.font-122:before { content: "\f122"; font-size: 32px; }
55.font-123:before { content: "\f123"; font-size: 32px; }
56.font-124:before { content: "\f124"; font-size: 32px; }
57.font-125:before { content: "\f125"; font-size: 32px; }
58.font-126:before { content: "\f126"; font-size: 32px; }
59.font-127:before { content: "\f127"; font-size: 32px; }
60.font-128:before { content: "\f128"; font-size: 32px; }
61.font-129:before { content: "\f129"; font-size: 32px; }
62.font-12a:before { content: "\f12a"; font-size: 32px; }
63.font-12b:before { content: "\f12b"; font-size: 32px; }
64.font-12c:before { content: "\f12c"; font-size: 32px; }
65.font-12d:before { content: "\f12d"; font-size: 32px; }
66.font-12e:before { content: "\f12e"; font-size: 32px; }
67.font-12f:before { content: "\f12f"; font-size: 32px; }
68.font-130:before { content: "\f130"; font-size: 32px; }
69.font-131:before { content: "\f131"; font-size: 32px; }
70.font-132:before { content: "\f132"; font-size: 32px; }
71.font-133:before { content: "\f133"; font-size: 32px; }
72.font-134:before { content: "\f134"; font-size: 32px; }
73.font-135:before { content: "\f135"; font-size: 32px; }
74.font-136:before { content: "\f136"; font-size: 32px; }
75.font-137:before { content: "\f137"; font-size: 32px; }
76.font-138:before { content: "\f138"; font-size: 32px; }
77.font-139:before { content: "\f139"; font-size: 32px; }
78.font-13a:before { content: "\f13a"; font-size: 32px; }
79.font-13b:before { content: "\f13b"; font-size: 32px; }
80.font-13c:before { content: "\f13c"; font-size: 32px; }
81.font-13d:before { content: "\f13d"; font-size: 32px; }
82.font-13e:before { content: "\f13e"; font-size: 32px; }
83.font-13f:before { content: "\f13f"; font-size: 32px; }
84.font-140:before { content: "\f140"; font-size: 32px; }
85.font-141:before { content: "\f141"; font-size: 32px; }
86.font-142:before { content: "\f142"; font-size: 32px; }
87.font-143:before { content: "\f143"; font-size: 32px; }
88.font-144:before { content: "\f144"; font-size: 32px; }
89.font-145:before { content: "\f145"; font-size: 32px; }
90.font-146:before { content: "\f146"; font-size: 32px; }
91.font-147:before { content: "\f147"; font-size: 32px; }
92.font-148:before { content: "\f148"; font-size: 32px; }
93.font-149:before { content: "\f149"; font-size: 32px; }
94.font-14a:before { content: "\f14a"; font-size: 32px; }
95.font-14b:before { content: "\f14b"; font-size: 32px; }
96.font-14c:before { content: "\f14c"; font-size: 32px; }
97.font-14d:before { content: "\f14d"; font-size: 32px; }
98.font-14e:before { content: "\f14e"; font-size: 32px; }
99.font-14f:before { content: "\f14f"; font-size: 32px; }
100.font-150:before { content: "\f150"; font-size: 32px; }
101.font-151:before { content: "\f151"; font-size: 32px; }
102.font-152:before { content: "\f152"; font-size: 32px; }
103.font-153:before { content: "\f153"; font-size: 32px; }
104.font-154:before { content: "\f154"; font-size: 32px; }
105.font-155:before { content: "\f155"; font-size: 32px; }
106.font-156:before { content: "\f156"; font-size: 32px; }
107.font-157:before { content: "\f157"; font-size: 32px; }
108.font-158:before { content: "\f158"; font-size: 32px; }
109.font-159:before { content: "\f159"; font-size: 32px; }
110.font-15c:before { content: "\f15c"; font-size: 32px; }
111.font-15d:before { content: "\f15d"; font-size: 32px; }
112.font-15e:before { content: "\f15e"; font-size: 32px; }
113.font-15f:before { content: "\f15f"; font-size: 32px; }
114.font-160:before { content: "\f160"; font-size: 32px; }
115.font-161:before { content: "\f161"; font-size: 32px; }
116.font-164:before { content: "\f164"; font-size: 32px; }
117.font-165:before { content: "\f165"; font-size: 32px; }
118.font-166:before { content: "\f166"; font-size: 32px; }
119.font-167:before { content: "\f167"; font-size: 32px; }
120.font-168:before { content: "\f168"; font-size: 32px; }
121.font-169:before { content: "\f169"; font-size: 32px; }
122.font-16a:before { content: "\f16a"; font-size: 32px; }
123.font-16b:before { content: "\f16b"; font-size: 32px; }
124.font-16c:before { content: "\f16c"; font-size: 32px; }
125.font-16d:before { content: "\f16d"; font-size: 32px; }
126.font-16e:before { content: "\f16e"; font-size: 32px; }
127.font-16f:before { content: "\f16f"; font-size: 32px; }
128.font-170:before { content: "\f170"; font-size: 32px; }
129.font-171:before { content: "\f171"; font-size: 32px; }
130.font-172:before { content: "\f172"; font-size: 32px; }
131.font-173:before { content: "\f173"; font-size: 32px; }
132.font-174:before { content: "\f174"; font-size: 32px; }
133.font-175:before { content: "\f175"; font-size: 32px; }
134.font-176:before { content: "\f176"; font-size: 32px; }
135.font-177:before { content: "\f177"; font-size: 32px; }
136.font-178:before { content: "\f178"; font-size: 32px; }
137.font-179:before { content: "\f179"; font-size: 32px; }
138.font-17a:before { content: "\f17a"; font-size: 32px; }
139.font-17b:before { content: "\f17b"; font-size: 32px; }
140.font-17c:before { content: "\f17c"; font-size: 32px; }
141.font-17d:before { content: "\f17d"; font-size: 32px; }
142.font-17e:before { content: "\f17e"; font-size: 32px; }
143.font-17f:before { content: "\f17f"; font-size: 32px; }
144.font-180:before { content: "\f180"; font-size: 32px; }
145.font-181:before { content: "\f181"; font-size: 32px; }
146.font-182:before { content: "\f182"; font-size: 32px; }
147.font-183:before { content: "\f183"; font-size: 32px; }
148.font-184:before { content: "\f184"; font-size: 32px; }
149.font-185:before { content: "\f185"; font-size: 32px; }
150.font-186:before { content: "\f186"; font-size: 32px; }
151.font-187:before { content: "\f187"; font-size: 32px; }
152.font-188:before { content: "\f188"; font-size: 32px; }
153.font-189:before { content: "\f189"; font-size: 32px; }
154.font-18a:before { content: "\f18a"; font-size: 32px; }
155.font-18b:before { content: "\f18b"; font-size: 32px; }
156.font-18c:before { content: "\f18c"; font-size: 32px; }
157.font-18d:before { content: "\f18d"; font-size: 32px; }
158.font-18e:before { content: "\f18e"; font-size: 32px; }
159.font-18f:before { content: "\f18f"; font-size: 32px; }
160.font-190:before { content: "\f190"; font-size: 32px; }
161.font-191:before { content: "\f191"; font-size: 32px; }
162.font-192:before { content: "\f192"; font-size: 32px; }
163.font-193:before { content: "\f193"; font-size: 32px; }
164.font-194:before { content: "\f194"; font-size: 32px; }
165.font-195:before { content: "\f195"; font-size: 32px; }
166.font-196:before { content: "\f196"; font-size: 32px; }
167.font-197:before { content: "\f197"; font-size: 32px; }
168.font-198:before { content: "\f198"; font-size: 32px; }
169.font-199:before { content: "\f199"; font-size: 32px; }
170.font-19a:before { content: "\f19a"; font-size: 32px; }
171.font-19b:before { content: "\f19b"; font-size: 32px; }
172.font-19c:before { content: "\f19c"; font-size: 32px; }
173.font-19d:before { content: "\f19d"; font-size: 32px; }
174.font-19e:before { content: "\f19e"; font-size: 32px; }
175.font-19f:before { content: "\f19f"; font-size: 32px; }
176.font-1a0:before { content: "\f1a0"; font-size: 32px; }
177.font-1a1:before { content: "\f1a1"; font-size: 32px; }
178.font-1a2:before { content: "\f1a2"; font-size: 32px; }
179.font-1a3:before { content: "\f1a3"; font-size: 32px; }
180.font-1a4:before { content: "\f1a4"; font-size: 32px; }
181.font-1a5:before { content: "\f1a5"; font-size: 32px; }
182.font-1a6:before { content: "\f1a6"; font-size: 32px; }
183.font-1a7:before { content: "\f1a7"; font-size: 32px; }
184.font-1a8:before { content: "\f1a8"; font-size: 32px; }
185.font-1a9:before { content: "\f1a9"; font-size: 32px; }
186.font-1aa:before { content: "\f1aa"; font-size: 32px; }
187.font-1ab:before { content: "\f1ab"; font-size: 32px; }
188.font-1ac:before { content: "\f1ac"; font-size: 32px; }
189.font-1ad:before { content: "\f1ad"; font-size: 32px; }
190.font-1ae:before { content: "\f1ae"; font-size: 32px; }
191.font-1af:before { content: "\f1af"; font-size: 32px; }
192.font-1b0:before { content: "\f1b0"; font-size: 32px; }
193.font-1b1:before { content: "\f1b1"; font-size: 32px; }
194.font-1b2:before { content: "\f1b2"; font-size: 32px; }
195.font-1b3:before { content: "\f1b3"; font-size: 32px; }
196.font-1b4:before { content: "\f1b4"; font-size: 32px; }
197.font-1b5:before { content: "\f1b5"; font-size: 32px; }
198.font-1b6:before { content: "\f1b6"; font-size: 32px; }
199.font-1b7:before { content: "\f1b7"; font-size: 32px; }
200.font-1b8:before { content: "\f1b8"; font-size: 32px; }
201.font-1b9:before { content: "\f1b9"; font-size: 32px; }
202.font-1ba:before { content: "\f1ba"; font-size: 32px; }
203.font-1bb:before { content: "\f1bb"; font-size: 32px; }
204.font-1bc:before { content: "\f1bc"; font-size: 32px; }
205.font-1bd:before { content: "\f1bd"; font-size: 32px; }
206.font-1be:before { content: "\f1be"; font-size: 32px; }
207.font-1bf:before { content: "\f1bf"; font-size: 32px; }
208.font-1c0:before { content: "\f1c0"; font-size: 32px; }
209.font-1c1:before { content: "\f1c1"; font-size: 32px; }
210.font-1c2:before { content: "\f1c2"; font-size: 32px; }
211.font-1c3:before { content: "\f1c3"; font-size: 32px; }
212.font-1c4:before { content: "\f1c4"; font-size: 32px; }
213.font-1c5:before { content: "\f1c5"; font-size: 32px; }
214.font-1c6:before { content: "\f1c6"; font-size: 32px; }
215.font-1c7:before { content: "\f1c7"; font-size: 32px; }
216.font-1c8:before { content: "\f1c8"; font-size: 32px; }
217.font-1c9:before { content: "\f1c9"; font-size: 32px; }
218.font-1ca:before { content: "\f1ca"; font-size: 32px; }
219.font-1cb:before { content: "\f1cb"; font-size: 32px; }
220.font-1cc:before { content: "\f1cc"; font-size: 32px; }
221.font-1cd:before { content: "\f1cd"; font-size: 32px; }
222.font-1ce:before { content: "\f1ce"; font-size: 32px; }
223.font-1cf:before { content: "\f1cf"; font-size: 32px; }
224.font-1d0:before { content: "\f1d0"; font-size: 32px; }
225.font-1d1:before { content: "\f1d1"; font-size: 32px; }
226.font-1d2:before { content: "\f1d2"; font-size: 32px; }
227.font-1d3:before { content: "\f1d3"; font-size: 32px; }
228.font-1d4:before { content: "\f1d4"; font-size: 32px; }
229.font-1d5:before { content: "\f1d5"; font-size: 32px; }
230.font-1d6:before { content: "\f1d6"; font-size: 32px; }
231.font-1d7:before { content: "\f1d7"; font-size: 32px; }
232.font-1d8:before { content: "\f1d8"; font-size: 32px; }
233.font-1d9:before { content: "\f1d9"; font-size: 32px; }
234.font-1da:before { content: "\f1da"; font-size: 32px; }
235.font-1db:before { content: "\f1db"; font-size: 32px; }
236.font-1dc:before { content: "\f1dc"; font-size: 32px; }
237.font-1dd:before { content: "\f1dd"; font-size: 32px; }
238.font-1de:before { content: "\f1de"; font-size: 32px; }
239.font-1df:before { content: "\f1df"; font-size: 32px; }
240.font-1e0:before { content: "\f1e0"; font-size: 32px; }
241.font-1e1:before { content: "\f1e1"; font-size: 32px; }
242.font-1e2:before { content: "\f1e2"; font-size: 32px; }
243.font-1e3:before { content: "\f1e3"; font-size: 32px; }
244.font-1e4:before { content: "\f1e4"; font-size: 32px; }
245.font-1e5:before { content: "\f1e5"; font-size: 32px; }
246.font-1e6:before { content: "\f1e6"; font-size: 32px; }
247.font-1e7:before { content: "\f1e7"; font-size: 32px; }
248.font-1e8:before { content: "\f1e8"; font-size: 32px; }
249.font-1e9:before { content: "\f1e9"; font-size: 32px; }
250.font-1ea:before { content: "\f1ea"; font-size: 32px; }
251.font-1eb:before { content: "\f1eb"; font-size: 32px; }
252.font-1ec:before { content: "\f1ec"; font-size: 32px; }
253.font-1ed:before { content: "\f1ed"; font-size: 32px; }
254.font-1ee:before { content: "\f1ee"; font-size: 32px; }
255.font-1ef:before { content: "\f1ef"; font-size: 32px; }
256.font-1f0:before { content: "\f1f0"; font-size: 32px; }
257.font-1f1:before { content: "\f1f1"; font-size: 32px; }
258.font-1f2:before { content: "\f1f2"; font-size: 32px; }
259.font-1f3:before { content: "\f1f3"; font-size: 32px; }
260.font-1f4:before { content: "\f1f4"; font-size: 32px; }
261.font-1f5:before { content: "\f1f5"; font-size: 32px; }
262.font-1f6:before { content: "\f1f6"; font-size: 32px; }
263.font-1f7:before { content: "\f1f7"; font-size: 32px; }
264.font-1f8:before { content: "\f1f8"; font-size: 32px; }
265.font-1f9:before { content: "\f1f9"; font-size: 32px; }
266.font-1fa:before { content: "\f1fa"; font-size: 32px; }
267.font-1fb:before { content: "\f1fb"; font-size: 32px; }
268.font-1fc:before { content: "\f1fc"; font-size: 32px; }
269.font-1fd:before { content: "\f1fd"; font-size: 32px; }
270.font-1fe:before { content: "\f1fe"; font-size: 32px; }
271.font-1ff:before { content: "\f1ff"; font-size: 32px; }
272.font-200:before { content: "\f200"; font-size: 32px; }
273.font-201:before { content: "\f201"; font-size: 32px; }
274.font-202:before { content: "\f202"; font-size: 32px; }
275.font-203:before { content: "\f203"; font-size: 32px; }
276.font-204:before { content: "\f204"; font-size: 32px; }
277.font-205:before { content: "\f205"; font-size: 32px; }
278.font-206:before { content: "\f206"; font-size: 32px; }
279.font-207:before { content: "\f207"; font-size: 32px; }
280.font-208:before { content: "\f208"; font-size: 32px; }
281.font-209:before { content: "\f209"; font-size: 32px; }
282.font-20a:before { content: "\f20a"; font-size: 32px; }
283.font-20b:before { content: "\f20b"; font-size: 32px; }
284.font-20c:before { content: "\f20c"; font-size: 32px; }
285.font-20d:before { content: "\f20d"; font-size: 32px; }
286.font-20e:before { content: "\f20e"; font-size: 32px; }
287.font-20f:before { content: "\f20f"; font-size: 32px; }
288.font-210:before { content: "\f210"; font-size: 32px; }
289.font-211:before { content: "\f211"; font-size: 32px; }
290.font-212:before { content: "\f212"; font-size: 32px; }
291.font-213:before { content: "\f213"; font-size: 32px; }
292.font-214:before { content: "\f214"; font-size: 32px; }
293.font-215:before { content: "\f215"; font-size: 32px; }
294.font-216:before { content: "\f216"; font-size: 32px; }
295.font-217:before { content: "\f217"; font-size: 32px; }
296.font-218:before { content: "\f218"; font-size: 32px; }
297.font-219:before { content: "\f219"; font-size: 32px; }
298.font-21a:before { content: "\f21a"; font-size: 32px; }
299.font-21b:before { content: "\f21b"; font-size: 32px; }
300.font-21c:before { content: "\f21c"; font-size: 32px; }
301.font-21d:before { content: "\f21d"; font-size: 32px; }
302.font-21e:before { content: "\f21e"; font-size: 32px; }
303.font-21f:before { content: "\f21f"; font-size: 32px; }
diff --git a/webapp/test.html b/webapp/test.html
new file mode 100644
index 0000000..c82f51c
--- /dev/null
+++ b/webapp/test.html
@@ -0,0 +1,145 @@
1<!DOCTYPE html>
2<html>
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <title></title>
7 <meta name="description" content="">
8 <meta name="viewport" content="width=device-width, initial-scale=1">
9 <link rel="stylesheet" href="test.css">
10 </head>
11 <body>
12
13<ul>
14<li class="font-100"></li>
15<li class="font-108"></li>
16<li class="font-136"></li>
17<li class="font-1c0"></li>
18
19<br/>
20
21<li class="font-10c"></li>
22<li class="font-10e"></li>
23<li class="font-110"></li>
24<li class="font-112"></li>
25<li class="font-184"></li>
26<li class="font-185"></li>
27<li class="font-186"></li>
28<li class="font-188"></li>
29<li class="font-1dc"></li>
30<li class="font-1de"></li>
31<li class="font-1e0"></li>
32<li class="font-1e1"></li>
33<li class="font-11a"></li>
34
35<br/>
36
37<li class="font-134"></li>
38<li class="font-114"></li>
39<li class="font-12a"></li>
40<li class="font-156"></li>
41<li class="font-164"></li>
42<li class="font-1fc"></li>
43<li class="font-20a"></li>
44
45<br/>
46
47<li class="font-120"></li>
48<li class="font-176"></li>
49<li class="font-15c"></li>
50<li class="font-1f5"></li>
51
52<br/>
53
54<li class="font-130"></li>
55<li class="font-132"></li>
56<li class="font-13e"></li>
57<li class="font-144"></li>
58<li class="font-146"></li>
59<li class="font-148"></li>
60<li class="font-18b"></li>
61<li class="font-195"></li>
62<li class="font-200"></li>
63
64<br/>
65
66<li class="font-1ef"></li>
67<li class="font-203"></li>
68<li class="font-206"></li>
69<li class="font-15e"></li>
70
71<br/>
72
73<li class="font-13a"></li>
74<li class="font-17c"></li>
75<li class="font-1bd"></li>
76<li class="font-1ff"></li>
77
78<br/>
79
80<li class="font-12c"></li>
81<li class="font-1f8"></li>
82<li class="font-21b"></li>
83
84<br/>
85
86<li class="font-124"></li>
87<li class="font-13c"></li>
88<li class="font-190"></li>
89<li class="font-198"></li>
90<li class="font-19c"></li>
91<li class="font-1b3"></li>
92<li class="font-1f6"></li>
93<li class="font-1f7"></li>
94<li class="font-1f9"></li>
95<li class="font-210"></li>
96<li class="font-213"></li>
97<li class="font-216"></li>
98
99<br/>
100
101<li class="font-10a"></li>
102<li class="font-138"></li>
103<li class="font-142"></li>
104<li class="font-14a"></li>
105<li class="font-14e"></li>
106<li class="font-150"></li>
107<li class="font-11e"></li>
108<li class="font-160"></li>
109<li class="font-1b9"></li>
110<li class="font-1e2"></li>
111<li class="font-11c"></li>
112<li class="font-122"></li>
113
114<br/>
115
116<li class="font-152"></li>
117<li class="font-154"></li>
118<li class="font-158"></li>
119<li class="font-172"></li>
120<li class="font-1ac"></li>
121
122<br/>
123
124
125
126
127
128
129<li class="font-102"></li>
130<li class="font-104"></li>
131<li class="font-106"></li>
132<li class="font-116"></li>
133<li class="font-126"></li>
134<li class="font-128"></li>
135<li class="font-12e"></li>
136<li class="font-140"></li>
137<li class="font-14c"></li>
138<li class="font-178"></li>
139<li class="font-1b6"></li>
140<li class="font-1f2"></li>
141<li class="font-20d"></li>
142<li class="font-21d"></li>
143</ul>
144 </body>
145</html>
diff --git a/webapp/vendor/backbone-1.1.2.js b/webapp/vendor/backbone-1.1.2.js
new file mode 100644
index 0000000..24a550a
--- /dev/null
+++ b/webapp/vendor/backbone-1.1.2.js
@@ -0,0 +1,1608 @@
1// Backbone.js 1.1.2
2
3// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4// Backbone may be freely distributed under the MIT license.
5// For all details and documentation:
6// http://backbonejs.org
7
8(function(root, factory) {
9
10 // Set up Backbone appropriately for the environment. Start with AMD.
11 if (typeof define === 'function' && define.amd) {
12 define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
13 // Export global even in AMD case in case this script is loaded with
14 // others that may still expect a global Backbone.
15 root.Backbone = factory(root, exports, _, $);
16 });
17
18 // Next for Node.js or CommonJS. jQuery may not be needed as a module.
19 } else if (typeof exports !== 'undefined') {
20 var _ = require('underscore');
21 factory(root, exports, _);
22
23 // Finally, as a browser global.
24 } else {
25 root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
26 }
27
28}(this, function(root, Backbone, _, $) {
29
30 // Initial Setup
31 // -------------
32
33 // Save the previous value of the `Backbone` variable, so that it can be
34 // restored later on, if `noConflict` is used.
35 var previousBackbone = root.Backbone;
36
37 // Create local references to array methods we'll want to use later.
38 var array = [];
39 var push = array.push;
40 var slice = array.slice;
41 var splice = array.splice;
42
43 // Current version of the library. Keep in sync with `package.json`.
44 Backbone.VERSION = '1.1.2';
45
46 // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
47 // the `$` variable.
48 Backbone.$ = $;
49
50 // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
51 // to its previous owner. Returns a reference to this Backbone object.
52 Backbone.noConflict = function() {
53 root.Backbone = previousBackbone;
54 return this;
55 };
56
57 // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
58 // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
59 // set a `X-Http-Method-Override` header.
60 Backbone.emulateHTTP = false;
61
62 // Turn on `emulateJSON` to support legacy servers that can't deal with direct
63 // `application/json` requests ... will encode the body as
64 // `application/x-www-form-urlencoded` instead and will send the model in a
65 // form param named `model`.
66 Backbone.emulateJSON = false;
67
68 // Backbone.Events
69 // ---------------
70
71 // A module that can be mixed in to *any object* in order to provide it with
72 // custom events. You may bind with `on` or remove with `off` callback
73 // functions to an event; `trigger`-ing an event fires all callbacks in
74 // succession.
75 //
76 // var object = {};
77 // _.extend(object, Backbone.Events);
78 // object.on('expand', function(){ alert('expanded'); });
79 // object.trigger('expand');
80 //
81 var Events = Backbone.Events = {
82
83 // Bind an event to a `callback` function. Passing `"all"` will bind
84 // the callback to all events fired.
85 on: function(name, callback, context) {
86 if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
87 this._events || (this._events = {});
88 var events = this._events[name] || (this._events[name] = []);
89 events.push({callback: callback, context: context, ctx: context || this});
90 return this;
91 },
92
93 // Bind an event to only be triggered a single time. After the first time
94 // the callback is invoked, it will be removed.
95 once: function(name, callback, context) {
96 if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
97 var self = this;
98 var once = _.once(function() {
99 self.off(name, once);
100 callback.apply(this, arguments);
101 });
102 once._callback = callback;
103 return this.on(name, once, context);
104 },
105
106 // Remove one or many callbacks. If `context` is null, removes all
107 // callbacks with that function. If `callback` is null, removes all
108 // callbacks for the event. If `name` is null, removes all bound
109 // callbacks for all events.
110 off: function(name, callback, context) {
111 var retain, ev, events, names, i, l, j, k;
112 if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
113 if (!name && !callback && !context) {
114 this._events = void 0;
115 return this;
116 }
117 names = name ? [name] : _.keys(this._events);
118 for (i = 0, l = names.length; i < l; i++) {
119 name = names[i];
120 if (events = this._events[name]) {
121 this._events[name] = retain = [];
122 if (callback || context) {
123 for (j = 0, k = events.length; j < k; j++) {
124 ev = events[j];
125 if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
126 (context && context !== ev.context)) {
127 retain.push(ev);
128 }
129 }
130 }
131 if (!retain.length) delete this._events[name];
132 }
133 }
134
135 return this;
136 },
137
138 // Trigger one or many events, firing all bound callbacks. Callbacks are
139 // passed the same arguments as `trigger` is, apart from the event name
140 // (unless you're listening on `"all"`, which will cause your callback to
141 // receive the true name of the event as the first argument).
142 trigger: function(name) {
143 if (!this._events) return this;
144 var args = slice.call(arguments, 1);
145 if (!eventsApi(this, 'trigger', name, args)) return this;
146 var events = this._events[name];
147 var allEvents = this._events.all;
148 if (events) triggerEvents(events, args);
149 if (allEvents) triggerEvents(allEvents, arguments);
150 return this;
151 },
152
153 // Tell this object to stop listening to either specific events ... or
154 // to every object it's currently listening to.
155 stopListening: function(obj, name, callback) {
156 var listeningTo = this._listeningTo;
157 if (!listeningTo) return this;
158 var remove = !name && !callback;
159 if (!callback && typeof name === 'object') callback = this;
160 if (obj) (listeningTo = {})[obj._listenId] = obj;
161 for (var id in listeningTo) {
162 obj = listeningTo[id];
163 obj.off(name, callback, this);
164 if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id];
165 }
166 return this;
167 }
168
169 };
170
171 // Regular expression used to split event strings.
172 var eventSplitter = /\s+/;
173
174 // Implement fancy features of the Events API such as multiple event
175 // names `"change blur"` and jQuery-style event maps `{change: action}`
176 // in terms of the existing API.
177 var eventsApi = function(obj, action, name, rest) {
178 if (!name) return true;
179
180 // Handle event maps.
181 if (typeof name === 'object') {
182 for (var key in name) {
183 obj[action].apply(obj, [key, name[key]].concat(rest));
184 }
185 return false;
186 }
187
188 // Handle space separated event names.
189 if (eventSplitter.test(name)) {
190 var names = name.split(eventSplitter);
191 for (var i = 0, l = names.length; i < l; i++) {
192 obj[action].apply(obj, [names[i]].concat(rest));
193 }
194 return false;
195 }
196
197 return true;
198 };
199
200 // A difficult-to-believe, but optimized internal dispatch function for
201 // triggering events. Tries to keep the usual cases speedy (most internal
202 // Backbone events have 3 arguments).
203 var triggerEvents = function(events, args) {
204 var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
205 switch (args.length) {
206 case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
207 case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
208 case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
209 case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
210 default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
211 }
212 };
213
214 var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
215
216 // Inversion-of-control versions of `on` and `once`. Tell *this* object to
217 // listen to an event in another object ... keeping track of what it's
218 // listening to.
219 _.each(listenMethods, function(implementation, method) {
220 Events[method] = function(obj, name, callback) {
221 var listeningTo = this._listeningTo || (this._listeningTo = {});
222 var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
223 listeningTo[id] = obj;
224 if (!callback && typeof name === 'object') callback = this;
225 obj[implementation](name, callback, this);
226 return this;
227 };
228 });
229
230 // Aliases for backwards compatibility.
231 Events.bind = Events.on;
232 Events.unbind = Events.off;
233
234 // Allow the `Backbone` object to serve as a global event bus, for folks who
235 // want global "pubsub" in a convenient place.
236 _.extend(Backbone, Events);
237
238 // Backbone.Model
239 // --------------
240
241 // Backbone **Models** are the basic data object in the framework --
242 // frequently representing a row in a table in a database on your server.
243 // A discrete chunk of data and a bunch of useful, related methods for
244 // performing computations and transformations on that data.
245
246 // Create a new model with the specified attributes. A client id (`cid`)
247 // is automatically generated and assigned for you.
248 var Model = Backbone.Model = function(attributes, options) {
249 var attrs = attributes || {};
250 options || (options = {});
251 this.cid = _.uniqueId('c');
252 this.attributes = {};
253 if (options.collection) this.collection = options.collection;
254 if (options.parse) attrs = this.parse(attrs, options) || {};
255 attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
256 this.set(attrs, options);
257 this.changed = {};
258 this.initialize.apply(this, arguments);
259 };
260
261 // Attach all inheritable methods to the Model prototype.
262 _.extend(Model.prototype, Events, {
263
264 // A hash of attributes whose current and previous value differ.
265 changed: null,
266
267 // The value returned during the last failed validation.
268 validationError: null,
269
270 // The default name for the JSON `id` attribute is `"id"`. MongoDB and
271 // CouchDB users may want to set this to `"_id"`.
272 idAttribute: 'id',
273
274 // Initialize is an empty function by default. Override it with your own
275 // initialization logic.
276 initialize: function(){},
277
278 // Return a copy of the model's `attributes` object.
279 toJSON: function(options) {
280 return _.clone(this.attributes);
281 },
282
283 // Proxy `Backbone.sync` by default -- but override this if you need
284 // custom syncing semantics for *this* particular model.
285 sync: function() {
286 return Backbone.sync.apply(this, arguments);
287 },
288
289 // Get the value of an attribute.
290 get: function(attr) {
291 return this.attributes[attr];
292 },
293
294 // Get the HTML-escaped value of an attribute.
295 escape: function(attr) {
296 return _.escape(this.get(attr));
297 },
298
299 // Returns `true` if the attribute contains a value that is not null
300 // or undefined.
301 has: function(attr) {
302 return this.get(attr) != null;
303 },
304
305 // Set a hash of model attributes on the object, firing `"change"`. This is
306 // the core primitive operation of a model, updating the data and notifying
307 // anyone who needs to know about the change in state. The heart of the beast.
308 set: function(key, val, options) {
309 var attr, attrs, unset, changes, silent, changing, prev, current;
310 if (key == null) return this;
311
312 // Handle both `"key", value` and `{key: value}` -style arguments.
313 if (typeof key === 'object') {
314 attrs = key;
315 options = val;
316 } else {
317 (attrs = {})[key] = val;
318 }
319
320 options || (options = {});
321
322 // Run validation.
323 if (!this._validate(attrs, options)) return false;
324
325 // Extract attributes and options.
326 unset = options.unset;
327 silent = options.silent;
328 changes = [];
329 changing = this._changing;
330 this._changing = true;
331
332 if (!changing) {
333 this._previousAttributes = _.clone(this.attributes);
334 this.changed = {};
335 }
336 current = this.attributes, prev = this._previousAttributes;
337
338 // Check for changes of `id`.
339 if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
340
341 // For each `set` attribute, update or delete the current value.
342 for (attr in attrs) {
343 val = attrs[attr];
344 if (!_.isEqual(current[attr], val)) changes.push(attr);
345 if (!_.isEqual(prev[attr], val)) {
346 this.changed[attr] = val;
347 } else {
348 delete this.changed[attr];
349 }
350 unset ? delete current[attr] : current[attr] = val;
351 }
352
353 // Trigger all relevant attribute changes.
354 if (!silent) {
355 if (changes.length) this._pending = options;
356 for (var i = 0, l = changes.length; i < l; i++) {
357 this.trigger('change:' + changes[i], this, current[changes[i]], options);
358 }
359 }
360
361 // You might be wondering why there's a `while` loop here. Changes can
362 // be recursively nested within `"change"` events.
363 if (changing) return this;
364 if (!silent) {
365 while (this._pending) {
366 options = this._pending;
367 this._pending = false;
368 this.trigger('change', this, options);
369 }
370 }
371 this._pending = false;
372 this._changing = false;
373 return this;
374 },
375
376 // Remove an attribute from the model, firing `"change"`. `unset` is a noop
377 // if the attribute doesn't exist.
378 unset: function(attr, options) {
379 return this.set(attr, void 0, _.extend({}, options, {unset: true}));
380 },
381
382 // Clear all attributes on the model, firing `"change"`.
383 clear: function(options) {
384 var attrs = {};
385 for (var key in this.attributes) attrs[key] = void 0;
386 return this.set(attrs, _.extend({}, options, {unset: true}));
387 },
388
389 // Determine if the model has changed since the last `"change"` event.
390 // If you specify an attribute name, determine if that attribute has changed.
391 hasChanged: function(attr) {
392 if (attr == null) return !_.isEmpty(this.changed);
393 return _.has(this.changed, attr);
394 },
395
396 // Return an object containing all the attributes that have changed, or
397 // false if there are no changed attributes. Useful for determining what
398 // parts of a view need to be updated and/or what attributes need to be
399 // persisted to the server. Unset attributes will be set to undefined.
400 // You can also pass an attributes object to diff against the model,
401 // determining if there *would be* a change.
402 changedAttributes: function(diff) {
403 if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
404 var val, changed = false;
405 var old = this._changing ? this._previousAttributes : this.attributes;
406 for (var attr in diff) {
407 if (_.isEqual(old[attr], (val = diff[attr]))) continue;
408 (changed || (changed = {}))[attr] = val;
409 }
410 return changed;
411 },
412
413 // Get the previous value of an attribute, recorded at the time the last
414 // `"change"` event was fired.
415 previous: function(attr) {
416 if (attr == null || !this._previousAttributes) return null;
417 return this._previousAttributes[attr];
418 },
419
420 // Get all of the attributes of the model at the time of the previous
421 // `"change"` event.
422 previousAttributes: function() {
423 return _.clone(this._previousAttributes);
424 },
425
426 // Fetch the model from the server. If the server's representation of the
427 // model differs from its current attributes, they will be overridden,
428 // triggering a `"change"` event.
429 fetch: function(options) {
430 options = options ? _.clone(options) : {};
431 if (options.parse === void 0) options.parse = true;
432 var model = this;
433 var success = options.success;
434 options.success = function(resp) {
435 if (!model.set(model.parse(resp, options), options)) return false;
436 if (success) success(model, resp, options);
437 model.trigger('sync', model, resp, options);
438 };
439 wrapError(this, options);
440 return this.sync('read', this, options);
441 },
442
443 // Set a hash of model attributes, and sync the model to the server.
444 // If the server returns an attributes hash that differs, the model's
445 // state will be `set` again.
446 save: function(key, val, options) {
447 var attrs, method, xhr, attributes = this.attributes;
448
449 // Handle both `"key", value` and `{key: value}` -style arguments.
450 if (key == null || typeof key === 'object') {
451 attrs = key;
452 options = val;
453 } else {
454 (attrs = {})[key] = val;
455 }
456
457 options = _.extend({validate: true}, options);
458
459 // If we're not waiting and attributes exist, save acts as
460 // `set(attr).save(null, opts)` with validation. Otherwise, check if
461 // the model will be valid when the attributes, if any, are set.
462 if (attrs && !options.wait) {
463 if (!this.set(attrs, options)) return false;
464 } else {
465 if (!this._validate(attrs, options)) return false;
466 }
467
468 // Set temporary attributes if `{wait: true}`.
469 if (attrs && options.wait) {
470 this.attributes = _.extend({}, attributes, attrs);
471 }
472
473 // After a successful server-side save, the client is (optionally)
474 // updated with the server-side state.
475 if (options.parse === void 0) options.parse = true;
476 var model = this;
477 var success = options.success;
478 options.success = function(resp) {
479 // Ensure attributes are restored during synchronous saves.
480 model.attributes = attributes;
481 var serverAttrs = model.parse(resp, options);
482 if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
483 if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
484 return false;
485 }
486 if (success) success(model, resp, options);
487 model.trigger('sync', model, resp, options);
488 };
489 wrapError(this, options);
490
491 method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
492 if (method === 'patch') options.attrs = attrs;
493 xhr = this.sync(method, this, options);
494
495 // Restore attributes.
496 if (attrs && options.wait) this.attributes = attributes;
497
498 return xhr;
499 },
500
501 // Destroy this model on the server if it was already persisted.
502 // Optimistically removes the model from its collection, if it has one.
503 // If `wait: true` is passed, waits for the server to respond before removal.
504 destroy: function(options) {
505 options = options ? _.clone(options) : {};
506 var model = this;
507 var success = options.success;
508
509 var destroy = function() {
510 model.trigger('destroy', model, model.collection, options);
511 };
512
513 options.success = function(resp) {
514 if (options.wait || model.isNew()) destroy();
515 if (success) success(model, resp, options);
516 if (!model.isNew()) model.trigger('sync', model, resp, options);
517 };
518
519 if (this.isNew()) {
520 options.success();
521 return false;
522 }
523 wrapError(this, options);
524
525 var xhr = this.sync('delete', this, options);
526 if (!options.wait) destroy();
527 return xhr;
528 },
529
530 // Default URL for the model's representation on the server -- if you're
531 // using Backbone's restful methods, override this to change the endpoint
532 // that will be called.
533 url: function() {
534 var base =
535 _.result(this, 'urlRoot') ||
536 _.result(this.collection, 'url') ||
537 urlError();
538 if (this.isNew()) return base;
539 return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id);
540 },
541
542 // **parse** converts a response into the hash of attributes to be `set` on
543 // the model. The default implementation is just to pass the response along.
544 parse: function(resp, options) {
545 return resp;
546 },
547
548 // Create a new model with identical attributes to this one.
549 clone: function() {
550 return new this.constructor(this.attributes);
551 },
552
553 // A model is new if it has never been saved to the server, and lacks an id.
554 isNew: function() {
555 return !this.has(this.idAttribute);
556 },
557
558 // Check if the model is currently in a valid state.
559 isValid: function(options) {
560 return this._validate({}, _.extend(options || {}, { validate: true }));
561 },
562
563 // Run validation against the next complete set of model attributes,
564 // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
565 _validate: function(attrs, options) {
566 if (!options.validate || !this.validate) return true;
567 attrs = _.extend({}, this.attributes, attrs);
568 var error = this.validationError = this.validate(attrs, options) || null;
569 if (!error) return true;
570 this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
571 return false;
572 }
573
574 });
575
576 // Underscore methods that we want to implement on the Model.
577 var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
578
579 // Mix in each Underscore method as a proxy to `Model#attributes`.
580 _.each(modelMethods, function(method) {
581 Model.prototype[method] = function() {
582 var args = slice.call(arguments);
583 args.unshift(this.attributes);
584 return _[method].apply(_, args);
585 };
586 });
587
588 // Backbone.Collection
589 // -------------------
590
591 // If models tend to represent a single row of data, a Backbone Collection is
592 // more analagous to a table full of data ... or a small slice or page of that
593 // table, or a collection of rows that belong together for a particular reason
594 // -- all of the messages in this particular folder, all of the documents
595 // belonging to this particular author, and so on. Collections maintain
596 // indexes of their models, both in order, and for lookup by `id`.
597
598 // Create a new **Collection**, perhaps to contain a specific type of `model`.
599 // If a `comparator` is specified, the Collection will maintain
600 // its models in sort order, as they're added and removed.
601 var Collection = Backbone.Collection = function(models, options) {
602 options || (options = {});
603 if (options.model) this.model = options.model;
604 if (options.comparator !== void 0) this.comparator = options.comparator;
605 this._reset();
606 this.initialize.apply(this, arguments);
607 if (models) this.reset(models, _.extend({silent: true}, options));
608 };
609
610 // Default options for `Collection#set`.
611 var setOptions = {add: true, remove: true, merge: true};
612 var addOptions = {add: true, remove: false};
613
614 // Define the Collection's inheritable methods.
615 _.extend(Collection.prototype, Events, {
616
617 // The default model for a collection is just a **Backbone.Model**.
618 // This should be overridden in most cases.
619 model: Model,
620
621 // Initialize is an empty function by default. Override it with your own
622 // initialization logic.
623 initialize: function(){},
624
625 // The JSON representation of a Collection is an array of the
626 // models' attributes.
627 toJSON: function(options) {
628 return this.map(function(model){ return model.toJSON(options); });
629 },
630
631 // Proxy `Backbone.sync` by default.
632 sync: function() {
633 return Backbone.sync.apply(this, arguments);
634 },
635
636 // Add a model, or list of models to the set.
637 add: function(models, options) {
638 return this.set(models, _.extend({merge: false}, options, addOptions));
639 },
640
641 // Remove a model, or a list of models from the set.
642 remove: function(models, options) {
643 var singular = !_.isArray(models);
644 models = singular ? [models] : _.clone(models);
645 options || (options = {});
646 var i, l, index, model;
647 for (i = 0, l = models.length; i < l; i++) {
648 model = models[i] = this.get(models[i]);
649 if (!model) continue;
650 delete this._byId[model.id];
651 delete this._byId[model.cid];
652 index = this.indexOf(model);
653 this.models.splice(index, 1);
654 this.length--;
655 if (!options.silent) {
656 options.index = index;
657 model.trigger('remove', model, this, options);
658 }
659 this._removeReference(model, options);
660 }
661 return singular ? models[0] : models;
662 },
663
664 // Update a collection by `set`-ing a new list of models, adding new ones,
665 // removing models that are no longer present, and merging models that
666 // already exist in the collection, as necessary. Similar to **Model#set**,
667 // the core operation for updating the data contained by the collection.
668 set: function(models, options) {
669 options = _.defaults({}, options, setOptions);
670 if (options.parse) models = this.parse(models, options);
671 var singular = !_.isArray(models);
672 models = singular ? (models ? [models] : []) : _.clone(models);
673 var i, l, id, model, attrs, existing, sort;
674 var at = options.at;
675 var targetModel = this.model;
676 var sortable = this.comparator && (at == null) && options.sort !== false;
677 var sortAttr = _.isString(this.comparator) ? this.comparator : null;
678 var toAdd = [], toRemove = [], modelMap = {};
679 var add = options.add, merge = options.merge, remove = options.remove;
680 var order = !sortable && add && remove ? [] : false;
681
682 // Turn bare objects into model references, and prevent invalid models
683 // from being added.
684 for (i = 0, l = models.length; i < l; i++) {
685 attrs = models[i] || {};
686 if (attrs instanceof Model) {
687 id = model = attrs;
688 } else {
689 id = attrs[targetModel.prototype.idAttribute || 'id'];
690 }
691
692 // If a duplicate is found, prevent it from being added and
693 // optionally merge it into the existing model.
694 if (existing = this.get(id)) {
695 if (remove) modelMap[existing.cid] = true;
696 if (merge) {
697 attrs = attrs === model ? model.attributes : attrs;
698 if (options.parse) attrs = existing.parse(attrs, options);
699 existing.set(attrs, options);
700 if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
701 }
702 models[i] = existing;
703
704 // If this is a new, valid model, push it to the `toAdd` list.
705 } else if (add) {
706 model = models[i] = this._prepareModel(attrs, options);
707 if (!model) continue;
708 toAdd.push(model);
709 this._addReference(model, options);
710 }
711
712 // Do not add multiple models with the same `id`.
713 model = existing || model;
714 if (order && (model.isNew() || !modelMap[model.id])) order.push(model);
715 modelMap[model.id] = true;
716 }
717
718 // Remove nonexistent models if appropriate.
719 if (remove) {
720 for (i = 0, l = this.length; i < l; ++i) {
721 if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
722 }
723 if (toRemove.length) this.remove(toRemove, options);
724 }
725
726 // See if sorting is needed, update `length` and splice in new models.
727 if (toAdd.length || (order && order.length)) {
728 if (sortable) sort = true;
729 this.length += toAdd.length;
730 if (at != null) {
731 for (i = 0, l = toAdd.length; i < l; i++) {
732 this.models.splice(at + i, 0, toAdd[i]);
733 }
734 } else {
735 if (order) this.models.length = 0;
736 var orderedModels = order || toAdd;
737 for (i = 0, l = orderedModels.length; i < l; i++) {
738 this.models.push(orderedModels[i]);
739 }
740 }
741 }
742
743 // Silently sort the collection if appropriate.
744 if (sort) this.sort({silent: true});
745
746 // Unless silenced, it's time to fire all appropriate add/sort events.
747 if (!options.silent) {
748 for (i = 0, l = toAdd.length; i < l; i++) {
749 (model = toAdd[i]).trigger('add', model, this, options);
750 }
751 if (sort || (order && order.length)) this.trigger('sort', this, options);
752 }
753
754 // Return the added (or merged) model (or models).
755 return singular ? models[0] : models;
756 },
757
758 // When you have more items than you want to add or remove individually,
759 // you can reset the entire set with a new list of models, without firing
760 // any granular `add` or `remove` events. Fires `reset` when finished.
761 // Useful for bulk operations and optimizations.
762 reset: function(models, options) {
763 options || (options = {});
764 for (var i = 0, l = this.models.length; i < l; i++) {
765 this._removeReference(this.models[i], options);
766 }
767 options.previousModels = this.models;
768 this._reset();
769 models = this.add(models, _.extend({silent: true}, options));
770 if (!options.silent) this.trigger('reset', this, options);
771 return models;
772 },
773
774 // Add a model to the end of the collection.
775 push: function(model, options) {
776 return this.add(model, _.extend({at: this.length}, options));
777 },
778
779 // Remove a model from the end of the collection.
780 pop: function(options) {
781 var model = this.at(this.length - 1);
782 this.remove(model, options);
783 return model;
784 },
785
786 // Add a model to the beginning of the collection.
787 unshift: function(model, options) {
788 return this.add(model, _.extend({at: 0}, options));
789 },
790
791 // Remove a model from the beginning of the collection.
792 shift: function(options) {
793 var model = this.at(0);
794 this.remove(model, options);
795 return model;
796 },
797
798 // Slice out a sub-array of models from the collection.
799 slice: function() {
800 return slice.apply(this.models, arguments);
801 },
802
803 // Get a model from the set by id.
804 get: function(obj) {
805 if (obj == null) return void 0;
806 return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid];
807 },
808
809 // Get the model at the given index.
810 at: function(index) {
811 return this.models[index];
812 },
813
814 // Return models with matching attributes. Useful for simple cases of
815 // `filter`.
816 where: function(attrs, first) {
817 if (_.isEmpty(attrs)) return first ? void 0 : [];
818 return this[first ? 'find' : 'filter'](function(model) {
819 for (var key in attrs) {
820 if (attrs[key] !== model.get(key)) return false;
821 }
822 return true;
823 });
824 },
825
826 // Return the first model with matching attributes. Useful for simple cases
827 // of `find`.
828 findWhere: function(attrs) {
829 return this.where(attrs, true);
830 },
831
832 // Force the collection to re-sort itself. You don't need to call this under
833 // normal circumstances, as the set will maintain sort order as each item
834 // is added.
835 sort: function(options) {
836 if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
837 options || (options = {});
838
839 // Run sort based on type of `comparator`.
840 if (_.isString(this.comparator) || this.comparator.length === 1) {
841 this.models = this.sortBy(this.comparator, this);
842 } else {
843 this.models.sort(_.bind(this.comparator, this));
844 }
845
846 if (!options.silent) this.trigger('sort', this, options);
847 return this;
848 },
849
850 // Pluck an attribute from each model in the collection.
851 pluck: function(attr) {
852 return _.invoke(this.models, 'get', attr);
853 },
854
855 // Fetch the default set of models for this collection, resetting the
856 // collection when they arrive. If `reset: true` is passed, the response
857 // data will be passed through the `reset` method instead of `set`.
858 fetch: function(options) {
859 options = options ? _.clone(options) : {};
860 if (options.parse === void 0) options.parse = true;
861 var success = options.success;
862 var collection = this;
863 options.success = function(resp) {
864 var method = options.reset ? 'reset' : 'set';
865 collection[method](resp, options);
866 if (success) success(collection, resp, options);
867 collection.trigger('sync', collection, resp, options);
868 };
869 wrapError(this, options);
870 return this.sync('read', this, options);
871 },
872
873 // Create a new instance of a model in this collection. Add the model to the
874 // collection immediately, unless `wait: true` is passed, in which case we
875 // wait for the server to agree.
876 create: function(model, options) {
877 options = options ? _.clone(options) : {};
878 if (!(model = this._prepareModel(model, options))) return false;
879 if (!options.wait) this.add(model, options);
880 var collection = this;
881 var success = options.success;
882 options.success = function(model, resp) {
883 if (options.wait) collection.add(model, options);
884 if (success) success(model, resp, options);
885 };
886 model.save(null, options);
887 return model;
888 },
889
890 // **parse** converts a response into a list of models to be added to the
891 // collection. The default implementation is just to pass it through.
892 parse: function(resp, options) {
893 return resp;
894 },
895
896 // Create a new collection with an identical list of models as this one.
897 clone: function() {
898 return new this.constructor(this.models);
899 },
900
901 // Private method to reset all internal state. Called when the collection
902 // is first initialized or reset.
903 _reset: function() {
904 this.length = 0;
905 this.models = [];
906 this._byId = {};
907 },
908
909 // Prepare a hash of attributes (or other model) to be added to this
910 // collection.
911 _prepareModel: function(attrs, options) {
912 if (attrs instanceof Model) return attrs;
913 options = options ? _.clone(options) : {};
914 options.collection = this;
915 var model = new this.model(attrs, options);
916 if (!model.validationError) return model;
917 this.trigger('invalid', this, model.validationError, options);
918 return false;
919 },
920
921 // Internal method to create a model's ties to a collection.
922 _addReference: function(model, options) {
923 this._byId[model.cid] = model;
924 if (model.id != null) this._byId[model.id] = model;
925 if (!model.collection) model.collection = this;
926 model.on('all', this._onModelEvent, this);
927 },
928
929 // Internal method to sever a model's ties to a collection.
930 _removeReference: function(model, options) {
931 if (this === model.collection) delete model.collection;
932 model.off('all', this._onModelEvent, this);
933 },
934
935 // Internal method called every time a model in the set fires an event.
936 // Sets need to update their indexes when models change ids. All other
937 // events simply proxy through. "add" and "remove" events that originate
938 // in other collections are ignored.
939 _onModelEvent: function(event, model, collection, options) {
940 if ((event === 'add' || event === 'remove') && collection !== this) return;
941 if (event === 'destroy') this.remove(model, options);
942 if (model && event === 'change:' + model.idAttribute) {
943 delete this._byId[model.previous(model.idAttribute)];
944 if (model.id != null) this._byId[model.id] = model;
945 }
946 this.trigger.apply(this, arguments);
947 }
948
949 });
950
951 // Underscore methods that we want to implement on the Collection.
952 // 90% of the core usefulness of Backbone Collections is actually implemented
953 // right here:
954 var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
955 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
956 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
957 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
958 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
959 'lastIndexOf', 'isEmpty', 'chain', 'sample'];
960
961 // Mix in each Underscore method as a proxy to `Collection#models`.
962 _.each(methods, function(method) {
963 Collection.prototype[method] = function() {
964 var args = slice.call(arguments);
965 args.unshift(this.models);
966 return _[method].apply(_, args);
967 };
968 });
969
970 // Underscore methods that take a property name as an argument.
971 var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
972
973 // Use attributes instead of properties.
974 _.each(attributeMethods, function(method) {
975 Collection.prototype[method] = function(value, context) {
976 var iterator = _.isFunction(value) ? value : function(model) {
977 return model.get(value);
978 };
979 return _[method](this.models, iterator, context);
980 };
981 });
982
983 // Backbone.View
984 // -------------
985
986 // Backbone Views are almost more convention than they are actual code. A View
987 // is simply a JavaScript object that represents a logical chunk of UI in the
988 // DOM. This might be a single item, an entire list, a sidebar or panel, or
989 // even the surrounding frame which wraps your whole app. Defining a chunk of
990 // UI as a **View** allows you to define your DOM events declaratively, without
991 // having to worry about render order ... and makes it easy for the view to
992 // react to specific changes in the state of your models.
993
994 // Creating a Backbone.View creates its initial element outside of the DOM,
995 // if an existing element is not provided...
996 var View = Backbone.View = function(options) {
997 this.cid = _.uniqueId('view');
998 options || (options = {});
999 _.extend(this, _.pick(options, viewOptions));
1000 this._ensureElement();
1001 this.initialize.apply(this, arguments);
1002 this.delegateEvents();
1003 };
1004
1005 // Cached regex to split keys for `delegate`.
1006 var delegateEventSplitter = /^(\S+)\s*(.*)$/;
1007
1008 // List of view options to be merged as properties.
1009 var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
1010
1011 // Set up all inheritable **Backbone.View** properties and methods.
1012 _.extend(View.prototype, Events, {
1013
1014 // The default `tagName` of a View's element is `"div"`.
1015 tagName: 'div',
1016
1017 // jQuery delegate for element lookup, scoped to DOM elements within the
1018 // current view. This should be preferred to global lookups where possible.
1019 $: function(selector) {
1020 return this.$el.find(selector);
1021 },
1022
1023 // Initialize is an empty function by default. Override it with your own
1024 // initialization logic.
1025 initialize: function(){},
1026
1027 // **render** is the core function that your view should override, in order
1028 // to populate its element (`this.el`), with the appropriate HTML. The
1029 // convention is for **render** to always return `this`.
1030 render: function() {
1031 return this;
1032 },
1033
1034 // Remove this view by taking the element out of the DOM, and removing any
1035 // applicable Backbone.Events listeners.
1036 remove: function() {
1037 this.$el.remove();
1038 this.stopListening();
1039 return this;
1040 },
1041
1042 // Change the view's element (`this.el` property), including event
1043 // re-delegation.
1044 setElement: function(element, delegate) {
1045 if (this.$el) this.undelegateEvents();
1046 this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
1047 this.el = this.$el[0];
1048 if (delegate !== false) this.delegateEvents();
1049 return this;
1050 },
1051
1052 // Set callbacks, where `this.events` is a hash of
1053 //
1054 // *{"event selector": "callback"}*
1055 //
1056 // {
1057 // 'mousedown .title': 'edit',
1058 // 'click .button': 'save',
1059 // 'click .open': function(e) { ... }
1060 // }
1061 //
1062 // pairs. Callbacks will be bound to the view, with `this` set properly.
1063 // Uses event delegation for efficiency.
1064 // Omitting the selector binds the event to `this.el`.
1065 // This only works for delegate-able events: not `focus`, `blur`, and
1066 // not `change`, `submit`, and `reset` in Internet Explorer.
1067 delegateEvents: function(events) {
1068 if (!(events || (events = _.result(this, 'events')))) return this;
1069 this.undelegateEvents();
1070 for (var key in events) {
1071 var method = events[key];
1072 if (!_.isFunction(method)) method = this[events[key]];
1073 if (!method) continue;
1074
1075 var match = key.match(delegateEventSplitter);
1076 var eventName = match[1], selector = match[2];
1077 method = _.bind(method, this);
1078 eventName += '.delegateEvents' + this.cid;
1079 if (selector === '') {
1080 this.$el.on(eventName, method);
1081 } else {
1082 this.$el.on(eventName, selector, method);
1083 }
1084 }
1085 return this;
1086 },
1087
1088 // Clears all callbacks previously bound to the view with `delegateEvents`.
1089 // You usually don't need to use this, but may wish to if you have multiple
1090 // Backbone views attached to the same DOM element.
1091 undelegateEvents: function() {
1092 this.$el.off('.delegateEvents' + this.cid);
1093 return this;
1094 },
1095
1096 // Ensure that the View has a DOM element to render into.
1097 // If `this.el` is a string, pass it through `$()`, take the first
1098 // matching element, and re-assign it to `el`. Otherwise, create
1099 // an element from the `id`, `className` and `tagName` properties.
1100 _ensureElement: function() {
1101 if (!this.el) {
1102 var attrs = _.extend({}, _.result(this, 'attributes'));
1103 if (this.id) attrs.id = _.result(this, 'id');
1104 if (this.className) attrs['class'] = _.result(this, 'className');
1105 var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
1106 this.setElement($el, false);
1107 } else {
1108 this.setElement(_.result(this, 'el'), false);
1109 }
1110 }
1111
1112 });
1113
1114 // Backbone.sync
1115 // -------------
1116
1117 // Override this function to change the manner in which Backbone persists
1118 // models to the server. You will be passed the type of request, and the
1119 // model in question. By default, makes a RESTful Ajax request
1120 // to the model's `url()`. Some possible customizations could be:
1121 //
1122 // * Use `setTimeout` to batch rapid-fire updates into a single request.
1123 // * Send up the models as XML instead of JSON.
1124 // * Persist models via WebSockets instead of Ajax.
1125 //
1126 // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
1127 // as `POST`, with a `_method` parameter containing the true HTTP method,
1128 // as well as all requests with the body as `application/x-www-form-urlencoded`
1129 // instead of `application/json` with the model in a param named `model`.
1130 // Useful when interfacing with server-side languages like **PHP** that make
1131 // it difficult to read the body of `PUT` requests.
1132 Backbone.sync = function(method, model, options) {
1133 var type = methodMap[method];
1134
1135 // Default options, unless specified.
1136 _.defaults(options || (options = {}), {
1137 emulateHTTP: Backbone.emulateHTTP,
1138 emulateJSON: Backbone.emulateJSON
1139 });
1140
1141 // Default JSON-request options.
1142 var params = {type: type, dataType: 'json'};
1143
1144 // Ensure that we have a URL.
1145 if (!options.url) {
1146 params.url = _.result(model, 'url') || urlError();
1147 }
1148
1149 // Ensure that we have the appropriate request data.
1150 if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
1151 params.contentType = 'application/json';
1152 params.data = JSON.stringify(options.attrs || model.toJSON(options));
1153 }
1154
1155 // For older servers, emulate JSON by encoding the request into an HTML-form.
1156 if (options.emulateJSON) {
1157 params.contentType = 'application/x-www-form-urlencoded';
1158 params.data = params.data ? {model: params.data} : {};
1159 }
1160
1161 // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
1162 // And an `X-HTTP-Method-Override` header.
1163 if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
1164 params.type = 'POST';
1165 if (options.emulateJSON) params.data._method = type;
1166 var beforeSend = options.beforeSend;
1167 options.beforeSend = function(xhr) {
1168 xhr.setRequestHeader('X-HTTP-Method-Override', type);
1169 if (beforeSend) return beforeSend.apply(this, arguments);
1170 };
1171 }
1172
1173 // Don't process data on a non-GET request.
1174 if (params.type !== 'GET' && !options.emulateJSON) {
1175 params.processData = false;
1176 }
1177
1178 // If we're sending a `PATCH` request, and we're in an old Internet Explorer
1179 // that still has ActiveX enabled by default, override jQuery to use that
1180 // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
1181 if (params.type === 'PATCH' && noXhrPatch) {
1182 params.xhr = function() {
1183 return new ActiveXObject("Microsoft.XMLHTTP");
1184 };
1185 }
1186
1187 // Make the request, allowing the user to override any Ajax options.
1188 var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
1189 model.trigger('request', model, xhr, options);
1190 return xhr;
1191 };
1192
1193 var noXhrPatch =
1194 typeof window !== 'undefined' && !!window.ActiveXObject &&
1195 !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
1196
1197 // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
1198 var methodMap = {
1199 'create': 'POST',
1200 'update': 'PUT',
1201 'patch': 'PATCH',
1202 'delete': 'DELETE',
1203 'read': 'GET'
1204 };
1205
1206 // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
1207 // Override this if you'd like to use a different library.
1208 Backbone.ajax = function() {
1209 return Backbone.$.ajax.apply(Backbone.$, arguments);
1210 };
1211
1212 // Backbone.Router
1213 // ---------------
1214
1215 // Routers map faux-URLs to actions, and fire events when routes are
1216 // matched. Creating a new one sets its `routes` hash, if not set statically.
1217 var Router = Backbone.Router = function(options) {
1218 options || (options = {});
1219 if (options.routes) this.routes = options.routes;
1220 this._bindRoutes();
1221 this.initialize.apply(this, arguments);
1222 };
1223
1224 // Cached regular expressions for matching named param parts and splatted
1225 // parts of route strings.
1226 var optionalParam = /\((.*?)\)/g;
1227 var namedParam = /(\(\?)?:\w+/g;
1228 var splatParam = /\*\w+/g;
1229 var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
1230
1231 // Set up all inheritable **Backbone.Router** properties and methods.
1232 _.extend(Router.prototype, Events, {
1233
1234 // Initialize is an empty function by default. Override it with your own
1235 // initialization logic.
1236 initialize: function(){},
1237
1238 // Manually bind a single named route to a callback. For example:
1239 //
1240 // this.route('search/:query/p:num', 'search', function(query, num) {
1241 // ...
1242 // });
1243 //
1244 route: function(route, name, callback) {
1245 if (!_.isRegExp(route)) route = this._routeToRegExp(route);
1246 if (_.isFunction(name)) {
1247 callback = name;
1248 name = '';
1249 }
1250 if (!callback) callback = this[name];
1251 var router = this;
1252 Backbone.history.route(route, function(fragment) {
1253 var args = router._extractParameters(route, fragment);
1254 router.execute(callback, args);
1255 router.trigger.apply(router, ['route:' + name].concat(args));
1256 router.trigger('route', name, args);
1257 Backbone.history.trigger('route', router, name, args);
1258 });
1259 return this;
1260 },
1261
1262 // Execute a route handler with the provided parameters. This is an
1263 // excellent place to do pre-route setup or post-route cleanup.
1264 execute: function(callback, args) {
1265 if (callback) callback.apply(this, args);
1266 },
1267
1268 // Simple proxy to `Backbone.history` to save a fragment into the history.
1269 navigate: function(fragment, options) {
1270 Backbone.history.navigate(fragment, options);
1271 return this;
1272 },
1273
1274 // Bind all defined routes to `Backbone.history`. We have to reverse the
1275 // order of the routes here to support behavior where the most general
1276 // routes can be defined at the bottom of the route map.
1277 _bindRoutes: function() {
1278 if (!this.routes) return;
1279 this.routes = _.result(this, 'routes');
1280 var route, routes = _.keys(this.routes);
1281 while ((route = routes.pop()) != null) {
1282 this.route(route, this.routes[route]);
1283 }
1284 },
1285
1286 // Convert a route string into a regular expression, suitable for matching
1287 // against the current location hash.
1288 _routeToRegExp: function(route) {
1289 route = route.replace(escapeRegExp, '\\$&')
1290 .replace(optionalParam, '(?:$1)?')
1291 .replace(namedParam, function(match, optional) {
1292 return optional ? match : '([^/?]+)';
1293 })
1294 .replace(splatParam, '([^?]*?)');
1295 return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
1296 },
1297
1298 // Given a route, and a URL fragment that it matches, return the array of
1299 // extracted decoded parameters. Empty or unmatched parameters will be
1300 // treated as `null` to normalize cross-browser behavior.
1301 _extractParameters: function(route, fragment) {
1302 var params = route.exec(fragment).slice(1);
1303 return _.map(params, function(param, i) {
1304 // Don't decode the search params.
1305 if (i === params.length - 1) return param || null;
1306 return param ? decodeURIComponent(param) : null;
1307 });
1308 }
1309
1310 });
1311
1312 // Backbone.History
1313 // ----------------
1314
1315 // Handles cross-browser history management, based on either
1316 // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
1317 // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
1318 // and URL fragments. If the browser supports neither (old IE, natch),
1319 // falls back to polling.
1320 var History = Backbone.History = function() {
1321 this.handlers = [];
1322 _.bindAll(this, 'checkUrl');
1323
1324 // Ensure that `History` can be used outside of the browser.
1325 if (typeof window !== 'undefined') {
1326 this.location = window.location;
1327 this.history = window.history;
1328 }
1329 };
1330
1331 // Cached regex for stripping a leading hash/slash and trailing space.
1332 var routeStripper = /^[#\/]|\s+$/g;
1333
1334 // Cached regex for stripping leading and trailing slashes.
1335 var rootStripper = /^\/+|\/+$/g;
1336
1337 // Cached regex for detecting MSIE.
1338 var isExplorer = /msie [\w.]+/;
1339
1340 // Cached regex for removing a trailing slash.
1341 var trailingSlash = /\/$/;
1342
1343 // Cached regex for stripping urls of hash.
1344 var pathStripper = /#.*$/;
1345
1346 // Has the history handling already been started?
1347 History.started = false;
1348
1349 // Set up all inheritable **Backbone.History** properties and methods.
1350 _.extend(History.prototype, Events, {
1351
1352 // The default interval to poll for hash changes, if necessary, is
1353 // twenty times a second.
1354 interval: 50,
1355
1356 // Are we at the app root?
1357 atRoot: function() {
1358 return this.location.pathname.replace(/[^\/]$/, '$&/') === this.root;
1359 },
1360
1361 // Gets the true hash value. Cannot use location.hash directly due to bug
1362 // in Firefox where location.hash will always be decoded.
1363 getHash: function(window) {
1364 var match = (window || this).location.href.match(/#(.*)$/);
1365 return match ? match[1] : '';
1366 },
1367
1368 // Get the cross-browser normalized URL fragment, either from the URL,
1369 // the hash, or the override.
1370 getFragment: function(fragment, forcePushState) {
1371 if (fragment == null) {
1372 if (this._hasPushState || !this._wantsHashChange || forcePushState) {
1373 fragment = decodeURI(this.location.pathname + this.location.search);
1374 var root = this.root.replace(trailingSlash, '');
1375 if (!fragment.indexOf(root)) fragment = fragment.slice(root.length);
1376 } else {
1377 fragment = this.getHash();
1378 }
1379 }
1380 return fragment.replace(routeStripper, '');
1381 },
1382
1383 // Start the hash change handling, returning `true` if the current URL matches
1384 // an existing route, and `false` otherwise.
1385 start: function(options) {
1386 if (History.started) throw new Error("Backbone.history has already been started");
1387 History.started = true;
1388
1389 // Figure out the initial configuration. Do we need an iframe?
1390 // Is pushState desired ... is it available?
1391 this.options = _.extend({root: '/'}, this.options, options);
1392 this.root = this.options.root;
1393 this._wantsHashChange = this.options.hashChange !== false;
1394 this._wantsPushState = !!this.options.pushState;
1395 this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);
1396 var fragment = this.getFragment();
1397 var docMode = document.documentMode;
1398 var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
1399
1400 // Normalize root to always include a leading and trailing slash.
1401 this.root = ('/' + this.root + '/').replace(rootStripper, '/');
1402
1403 if (oldIE && this._wantsHashChange) {
1404 var frame = Backbone.$('<iframe src="javascript:0" tabindex="-1">');
1405 this.iframe = frame.hide().appendTo('body')[0].contentWindow;
1406 this.navigate(fragment);
1407 }
1408
1409 // Depending on whether we're using pushState or hashes, and whether
1410 // 'onhashchange' is supported, determine how we check the URL state.
1411 if (this._hasPushState) {
1412 Backbone.$(window).on('popstate', this.checkUrl);
1413 } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
1414 Backbone.$(window).on('hashchange', this.checkUrl);
1415 } else if (this._wantsHashChange) {
1416 this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
1417 }
1418
1419 // Determine if we need to change the base url, for a pushState link
1420 // opened by a non-pushState browser.
1421 this.fragment = fragment;
1422 var loc = this.location;
1423
1424 // Transition from hashChange to pushState or vice versa if both are
1425 // requested.
1426 if (this._wantsHashChange && this._wantsPushState) {
1427
1428 // If we've started off with a route from a `pushState`-enabled
1429 // browser, but we're currently in a browser that doesn't support it...
1430 if (!this._hasPushState && !this.atRoot()) {
1431 this.fragment = this.getFragment(null, true);
1432 this.location.replace(this.root + '#' + this.fragment);
1433 // Return immediately as browser will do redirect to new url
1434 return true;
1435
1436 // Or if we've started out with a hash-based route, but we're currently
1437 // in a browser where it could be `pushState`-based instead...
1438 } else if (this._hasPushState && this.atRoot() && loc.hash) {
1439 this.fragment = this.getHash().replace(routeStripper, '');
1440 this.history.replaceState({}, document.title, this.root + this.fragment);
1441 }
1442
1443 }
1444
1445 if (!this.options.silent) return this.loadUrl();
1446 },
1447
1448 // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
1449 // but possibly useful for unit testing Routers.
1450 stop: function() {
1451 Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
1452 if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
1453 History.started = false;
1454 },
1455
1456 // Add a route to be tested when the fragment changes. Routes added later
1457 // may override previous routes.
1458 route: function(route, callback) {
1459 this.handlers.unshift({route: route, callback: callback});
1460 },
1461
1462 // Checks the current URL to see if it has changed, and if it has,
1463 // calls `loadUrl`, normalizing across the hidden iframe.
1464 checkUrl: function(e) {
1465 var current = this.getFragment();
1466 if (current === this.fragment && this.iframe) {
1467 current = this.getFragment(this.getHash(this.iframe));
1468 }
1469 if (current === this.fragment) return false;
1470 if (this.iframe) this.navigate(current);
1471 this.loadUrl();
1472 },
1473
1474 // Attempt to load the current URL fragment. If a route succeeds with a
1475 // match, returns `true`. If no defined routes matches the fragment,
1476 // returns `false`.
1477 loadUrl: function(fragment) {
1478 fragment = this.fragment = this.getFragment(fragment);
1479 return _.any(this.handlers, function(handler) {
1480 if (handler.route.test(fragment)) {
1481 handler.callback(fragment);
1482 return true;
1483 }
1484 });
1485 },
1486
1487 // Save a fragment into the hash history, or replace the URL state if the
1488 // 'replace' option is passed. You are responsible for properly URL-encoding
1489 // the fragment in advance.
1490 //
1491 // The options object can contain `trigger: true` if you wish to have the
1492 // route callback be fired (not usually desirable), or `replace: true`, if
1493 // you wish to modify the current URL without adding an entry to the history.
1494 navigate: function(fragment, options) {
1495 if (!History.started) return false;
1496 if (!options || options === true) options = {trigger: !!options};
1497
1498 var url = this.root + (fragment = this.getFragment(fragment || ''));
1499
1500 // Strip the hash for matching.
1501 fragment = fragment.replace(pathStripper, '');
1502
1503 if (this.fragment === fragment) return;
1504 this.fragment = fragment;
1505
1506 // Don't include a trailing slash on the root.
1507 if (fragment === '' && url !== '/') url = url.slice(0, -1);
1508
1509 // If pushState is available, we use it to set the fragment as a real URL.
1510 if (this._hasPushState) {
1511 this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
1512
1513 // If hash changes haven't been explicitly disabled, update the hash
1514 // fragment to store history.
1515 } else if (this._wantsHashChange) {
1516 this._updateHash(this.location, fragment, options.replace);
1517 if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
1518 // Opening and closing the iframe tricks IE7 and earlier to push a
1519 // history entry on hash-tag change. When replace is true, we don't
1520 // want this.
1521 if(!options.replace) this.iframe.document.open().close();
1522 this._updateHash(this.iframe.location, fragment, options.replace);
1523 }
1524
1525 // If you've told us that you explicitly don't want fallback hashchange-
1526 // based history, then `navigate` becomes a page refresh.
1527 } else {
1528 return this.location.assign(url);
1529 }
1530 if (options.trigger) return this.loadUrl(fragment);
1531 },
1532
1533 // Update the hash location, either replacing the current entry, or adding
1534 // a new one to the browser history.
1535 _updateHash: function(location, fragment, replace) {
1536 if (replace) {
1537 var href = location.href.replace(/(javascript:|#).*$/, '');
1538 location.replace(href + '#' + fragment);
1539 } else {
1540 // Some browsers require that `hash` contains a leading #.
1541 location.hash = '#' + fragment;
1542 }
1543 }
1544
1545 });
1546
1547 // Create the default Backbone.history.
1548 Backbone.history = new History;
1549
1550 // Helpers
1551 // -------
1552
1553 // Helper function to correctly set up the prototype chain, for subclasses.
1554 // Similar to `goog.inherits`, but uses a hash of prototype properties and
1555 // class properties to be extended.
1556 var extend = function(protoProps, staticProps) {
1557 var parent = this;
1558 var child;
1559
1560 // The constructor function for the new subclass is either defined by you
1561 // (the "constructor" property in your `extend` definition), or defaulted
1562 // by us to simply call the parent's constructor.
1563 if (protoProps && _.has(protoProps, 'constructor')) {
1564 child = protoProps.constructor;
1565 } else {
1566 child = function(){ return parent.apply(this, arguments); };
1567 }
1568
1569 // Add static properties to the constructor function, if supplied.
1570 _.extend(child, parent, staticProps);
1571
1572 // Set the prototype chain to inherit from `parent`, without calling
1573 // `parent`'s constructor function.
1574 var Surrogate = function(){ this.constructor = child; };
1575 Surrogate.prototype = parent.prototype;
1576 child.prototype = new Surrogate;
1577
1578 // Add prototype properties (instance properties) to the subclass,
1579 // if supplied.
1580 if (protoProps) _.extend(child.prototype, protoProps);
1581
1582 // Set a convenience property in case the parent's prototype is needed
1583 // later.
1584 child.__super__ = parent.prototype;
1585
1586 return child;
1587 };
1588
1589 // Set up inheritance for the model, collection, router, view and history.
1590 Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
1591
1592 // Throw an error when a URL is needed, and none is supplied.
1593 var urlError = function() {
1594 throw new Error('A "url" property or function must be specified');
1595 };
1596
1597 // Wrap an optional error callback with a fallback error event.
1598 var wrapError = function(model, options) {
1599 var error = options.error;
1600 options.error = function(resp) {
1601 if (error) error(model, resp, options);
1602 model.trigger('error', model, resp, options);
1603 };
1604 };
1605
1606 return Backbone;
1607
1608}));
diff --git a/webapp/vendor/html5-boilerplate-4.3.0/.gitattributes b/webapp/vendor/html5-boilerplate-4.3.0/.gitattributes
new file mode 100755
index 0000000..2125666
--- /dev/null
+++ b/webapp/vendor/html5-boilerplate-4.3.0/.gitattributes
@@ -0,0 +1 @@
* text=auto \ No newline at end of file
diff --git a/webapp/vendor/html5-boilerplate-4.3.0/.gitignore b/webapp/vendor/html5-boilerplate-4.3.0/.gitignore
new file mode 100755
index 0000000..16b2d7d
--- /dev/null
+++ b/webapp/vendor/html5-boilerplate-4.3.0/.gitignore
@@ -0,0 +1,2 @@
1# Include your project-specific ignores in this file
2# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files
diff --git a/webapp/vendor/html5-boilerplate-4.3.0/.htaccess b/webapp/vendor/html5-boilerplate-4.3.0/.htaccess
new file mode 100755
index 0000000..6861ada
--- /dev/null
+++ b/webapp/vendor/html5-boilerplate-4.3.0/.htaccess
@@ -0,0 +1,551 @@
1# Apache Server Configs v1.1.0 | MIT License
2# https://github.com/h5bp/server-configs-apache
3
4# (!) Using `.htaccess` files slows down Apache, therefore, if you have access
5# to the main server config file (usually called `httpd.conf`), you should add
6# this logic there: http://httpd.apache.org/docs/current/howto/htaccess.html.
7
8# ##############################################################################
9# # CROSS-ORIGIN RESOURCE SHARING (CORS) #
10# ##############################################################################
11
12# ------------------------------------------------------------------------------
13# | Cross-domain AJAX requests |
14# ------------------------------------------------------------------------------
15
16# Enable cross-origin AJAX requests.
17# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
18# http://enable-cors.org/
19
20# <IfModule mod_headers.c>
21# Header set Access-Control-Allow-Origin "*"
22# </IfModule>
23
24# ------------------------------------------------------------------------------
25# | CORS-enabled images |
26# ------------------------------------------------------------------------------
27
28# Send the CORS header for images when browsers request it.
29# https://developer.mozilla.org/en/CORS_Enabled_Image
30# http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
31# http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/
32
33<IfModule mod_setenvif.c>
34 <IfModule mod_headers.c>
35 <FilesMatch "\.(gif|ico|jpe?g|png|svgz?|webp)$">
36 SetEnvIf Origin ":" IS_CORS
37 Header set Access-Control-Allow-Origin "*" env=IS_CORS
38 </FilesMatch>
39 </IfModule>
40</IfModule>
41
42# ------------------------------------------------------------------------------
43# | Web fonts access |
44# ------------------------------------------------------------------------------
45
46# Allow access from all domains for web fonts
47
48<IfModule mod_headers.c>
49 <FilesMatch "\.(eot|font.css|otf|ttc|ttf|woff)$">
50 Header set Access-Control-Allow-Origin "*"
51 </FilesMatch>
52</IfModule>
53
54
55# ##############################################################################
56# # ERRORS #
57# ##############################################################################
58
59# ------------------------------------------------------------------------------
60# | 404 error prevention for non-existing redirected folders |
61# ------------------------------------------------------------------------------
62
63# Prevent Apache from returning a 404 error for a rewrite if a directory
64# with the same name does not exist.
65# http://httpd.apache.org/docs/current/content-negotiation.html#multiviews
66# http://www.webmasterworld.com/apache/3808792.htm
67
68Options -MultiViews
69
70# ------------------------------------------------------------------------------
71# | Custom error messages / pages |
72# ------------------------------------------------------------------------------
73
74# You can customize what Apache returns to the client in case of an error (see
75# http://httpd.apache.org/docs/current/mod/core.html#errordocument), e.g.:
76
77ErrorDocument 404 /404.html
78
79
80# ##############################################################################
81# # INTERNET EXPLORER #
82# ##############################################################################
83
84# ------------------------------------------------------------------------------
85# | Better website experience |
86# ------------------------------------------------------------------------------
87
88# Force IE to render pages in the highest available mode in the various
89# cases when it may not: http://hsivonen.iki.fi/doctype/ie-mode.pdf.
90
91<IfModule mod_headers.c>
92 Header set X-UA-Compatible "IE=edge"
93 # `mod_headers` can't match based on the content-type, however, we only
94 # want to send this header for HTML pages and not for the other resources
95 <FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svgz?|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$">
96 Header unset X-UA-Compatible
97 </FilesMatch>
98</IfModule>
99
100# ------------------------------------------------------------------------------
101# | Cookie setting from iframes |
102# ------------------------------------------------------------------------------
103
104# Allow cookies to be set from iframes in IE.
105
106# <IfModule mod_headers.c>
107# Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
108# </IfModule>
109
110# ------------------------------------------------------------------------------
111# | Screen flicker |
112# ------------------------------------------------------------------------------
113
114# Stop screen flicker in IE on CSS rollovers (this only works in
115# combination with the `ExpiresByType` directives for images from below).
116
117# BrowserMatch "MSIE" brokenvary=1
118# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
119# BrowserMatch "Opera" !brokenvary
120# SetEnvIf brokenvary 1 force-no-vary
121
122
123# ##############################################################################
124# # MIME TYPES AND ENCODING #
125# ##############################################################################
126
127# ------------------------------------------------------------------------------
128# | Proper MIME types for all files |
129# ------------------------------------------------------------------------------
130
131<IfModule mod_mime.c>
132
133 # Audio
134 AddType audio/mp4 m4a f4a f4b
135 AddType audio/ogg oga ogg
136
137 # JavaScript
138 # Normalize to standard type (it's sniffed in IE anyways):
139 # http://tools.ietf.org/html/rfc4329#section-7.2
140 AddType application/javascript js
141 AddType application/json json
142
143 # Video
144 AddType video/mp4 mp4 m4v f4v f4p
145 AddType video/ogg ogv
146 AddType video/webm webm
147 AddType video/x-flv flv
148
149 # Web fonts
150 AddType application/font-woff woff
151 AddType application/vnd.ms-fontobject eot
152
153 # Browsers usually ignore the font MIME types and sniff the content,
154 # however, Chrome shows a warning if other MIME types are used for the
155 # following fonts.
156 AddType application/x-font-ttf ttc ttf
157 AddType font/opentype otf
158
159 # Make SVGZ fonts work on iPad:
160 # https://twitter.com/FontSquirrel/status/14855840545
161 AddType image/svg+xml svg svgz
162 AddEncoding gzip svgz
163
164 # Other
165 AddType application/octet-stream safariextz
166 AddType application/x-chrome-extension crx
167 AddType application/x-opera-extension oex
168 AddType application/x-shockwave-flash swf
169 AddType application/x-web-app-manifest+json webapp
170 AddType application/x-xpinstall xpi
171 AddType application/xml atom rdf rss xml
172 AddType image/webp webp
173 AddType image/x-icon ico
174 AddType text/cache-manifest appcache manifest
175 AddType text/vtt vtt
176 AddType text/x-component htc
177 AddType text/x-vcard vcf
178
179</IfModule>
180
181# ------------------------------------------------------------------------------
182# | UTF-8 encoding |
183# ------------------------------------------------------------------------------
184
185# Use UTF-8 encoding for anything served as `text/html` or `text/plain`.
186AddDefaultCharset utf-8
187
188# Force UTF-8 for certain file formats.
189<IfModule mod_mime.c>
190 AddCharset utf-8 .atom .css .js .json .rss .vtt .webapp .xml
191</IfModule>
192
193
194# ##############################################################################
195# # URL REWRITES #
196# ##############################################################################
197
198# ------------------------------------------------------------------------------
199# | Rewrite engine |
200# ------------------------------------------------------------------------------
201
202# Turning on the rewrite engine and enabling the `FollowSymLinks` option is
203# necessary for the following directives to work.
204
205# If your web host doesn't allow the `FollowSymlinks` option, you may need to
206# comment it out and use `Options +SymLinksIfOwnerMatch` but, be aware of the
207# performance impact: http://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks
208
209# Also, some cloud hosting services require `RewriteBase` to be set:
210# http://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-mod-rewrite-not-working-on-my-site
211
212<IfModule mod_rewrite.c>
213 Options +FollowSymlinks
214 # Options +SymLinksIfOwnerMatch
215 RewriteEngine On
216 # RewriteBase /
217</IfModule>
218
219# ------------------------------------------------------------------------------
220# | Suppressing / Forcing the "www." at the beginning of URLs |
221# ------------------------------------------------------------------------------
222
223# The same content should never be available under two different URLs especially
224# not with and without "www." at the beginning. This can cause SEO problems
225# (duplicate content), therefore, you should choose one of the alternatives and
226# redirect the other one.
227
228# By default option 1 (no "www.") is activated:
229# http://no-www.org/faq.php?q=class_b
230
231# If you'd prefer to use option 2, just comment out all the lines from option 1
232# and uncomment the ones from option 2.
233
234# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME!
235
236# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
237
238# Option 1: rewrite www.example.com → example.com
239
240<IfModule mod_rewrite.c>
241 RewriteCond %{HTTPS} !=on
242 RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
243 RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
244</IfModule>
245
246# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
247
248# Option 2: rewrite example.com → www.example.com
249
250# Be aware that the following might not be a good idea if you use "real"
251# subdomains for certain parts of your website.
252
253# <IfModule mod_rewrite.c>
254# RewriteCond %{HTTPS} !=on
255# RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
256# RewriteCond %{HTTP_HOST} !=localhost [NC]
257# RewriteCond %{HTTP_HOST} !=127.0.0.1
258# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
259# </IfModule>
260
261
262# ##############################################################################
263# # SECURITY #
264# ##############################################################################
265
266# ------------------------------------------------------------------------------
267# | Content Security Policy (CSP) |
268# ------------------------------------------------------------------------------
269
270# You can mitigate the risk of cross-site scripting and other content-injection
271# attacks by setting a Content Security Policy which whitelists trusted sources
272# of content for your site.
273
274# The example header below allows ONLY scripts that are loaded from the current
275# site's origin (no inline scripts, no CDN, etc). This almost certainly won't
276# work as-is for your site!
277
278# To get all the details you'll need to craft a reasonable policy for your site,
279# read: http://html5rocks.com/en/tutorials/security/content-security-policy (or
280# see the specification: http://w3.org/TR/CSP).
281
282# <IfModule mod_headers.c>
283# Header set Content-Security-Policy "script-src 'self'; object-src 'self'"
284# <FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svgz?|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$">
285# Header unset Content-Security-Policy
286# </FilesMatch>
287# </IfModule>
288
289# ------------------------------------------------------------------------------
290# | File access |
291# ------------------------------------------------------------------------------
292
293# Block access to directories without a default document.
294# Usually you should leave this uncommented because you shouldn't allow anyone
295# to surf through every directory on your server (which may includes rather
296# private places like the CMS's directories).
297
298<IfModule mod_autoindex.c>
299 Options -Indexes
300</IfModule>
301
302# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
303
304# Block access to hidden files and directories.
305# This includes directories used by version control systems such as Git and SVN.
306
307<IfModule mod_rewrite.c>
308 RewriteCond %{SCRIPT_FILENAME} -d [OR]
309 RewriteCond %{SCRIPT_FILENAME} -f
310 RewriteRule "(^|/)\." - [F]
311</IfModule>
312
313# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
314
315# Block access to backup and source files.
316# These files may be left by some text editors and can pose a great security
317# danger when anyone has access to them.
318
319<FilesMatch "(^#.*#|\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|sw[op])|~)$">
320 Order allow,deny
321 Deny from all
322 Satisfy All
323</FilesMatch>
324
325# ------------------------------------------------------------------------------
326# | Secure Sockets Layer (SSL) |
327# ------------------------------------------------------------------------------
328
329# Rewrite secure requests properly to prevent SSL certificate warnings, e.g.:
330# prevent `https://www.example.com` when your certificate only allows
331# `https://secure.example.com`.
332
333# <IfModule mod_rewrite.c>
334# RewriteCond %{SERVER_PORT} !^443
335# RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L]
336# </IfModule>
337
338# ------------------------------------------------------------------------------
339# | HTTP Strict Transport Security (HSTS) |
340# ------------------------------------------------------------------------------
341
342# Force client-side SSL redirection.
343
344# If a user types "example.com" in his browser, the above rule will redirect
345# him to the secure version of the site. That still leaves a window of oppor-
346# tunity (the initial HTTP connection) for an attacker to downgrade or redirect
347# the request. The following header ensures that browser will ONLY connect to
348# your server via HTTPS, regardless of what the users type in the address bar.
349# http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-14#section-6.1
350# http://www.html5rocks.com/en/tutorials/security/transport-layer-security/
351
352# (!) Remove the `includeSubDomains` optional directive if the subdomains are
353# not using HTTPS.
354
355# <IfModule mod_headers.c>
356# Header set Strict-Transport-Security "max-age=16070400; includeSubDomains"
357# </IfModule>
358
359# ------------------------------------------------------------------------------
360# | Server software information |
361# ------------------------------------------------------------------------------
362
363# Avoid displaying the exact Apache version number, the description of the
364# generic OS-type and the information about Apache's compiled-in modules.
365
366# ADD THIS DIRECTIVE IN THE `httpd.conf` AS IT WILL NOT WORK IN THE `.htaccess`!
367
368# ServerTokens Prod
369
370
371# ##############################################################################
372# # WEB PERFORMANCE #
373# ##############################################################################
374
375# ------------------------------------------------------------------------------
376# | Compression |
377# ------------------------------------------------------------------------------
378
379<IfModule mod_deflate.c>
380
381 # Force compression for mangled headers.
382 # http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping
383 <IfModule mod_setenvif.c>
384 <IfModule mod_headers.c>
385 SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
386 RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
387 </IfModule>
388 </IfModule>
389
390 # Compress all output labeled with one of the following MIME-types
391 # (for Apache versions below 2.3.7, you don't need to enable `mod_filter`
392 # and can remove the `<IfModule mod_filter.c>` and `</IfModule>` lines
393 # as `AddOutputFilterByType` is still in the core directives).
394 <IfModule mod_filter.c>
395 AddOutputFilterByType DEFLATE application/atom+xml \
396 application/javascript \
397 application/json \
398 application/rss+xml \
399 application/vnd.ms-fontobject \
400 application/x-font-ttf \
401 application/x-web-app-manifest+json \
402 application/xhtml+xml \
403 application/xml \
404 font/opentype \
405 image/svg+xml \
406 image/x-icon \
407 text/css \
408 text/html \
409 text/plain \
410 text/x-component \
411 text/xml
412 </IfModule>
413
414</IfModule>
415
416# ------------------------------------------------------------------------------
417# | Content transformations |
418# ------------------------------------------------------------------------------
419
420# Prevent some of the mobile network providers from modifying the content of
421# your site: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5.
422
423# <IfModule mod_headers.c>
424# Header set Cache-Control "no-transform"
425# </IfModule>
426
427# ------------------------------------------------------------------------------
428# | ETag removal |
429# ------------------------------------------------------------------------------
430
431# Since we're sending far-future expires headers (see below), ETags can
432# be removed: http://developer.yahoo.com/performance/rules.html#etags.
433
434# `FileETag None` is not enough for every server.
435<IfModule mod_headers.c>
436 Header unset ETag
437</IfModule>
438
439FileETag None
440
441# ------------------------------------------------------------------------------
442# | Expires headers (for better cache control) |
443# ------------------------------------------------------------------------------
444
445# The following expires headers are set pretty far in the future. If you don't
446# control versioning with filename-based cache busting, consider lowering the
447# cache time for resources like CSS and JS to something like 1 week.
448
449<IfModule mod_expires.c>
450
451 ExpiresActive on
452 ExpiresDefault "access plus 1 month"
453
454 # CSS
455 ExpiresByType text/css "access plus 1 year"
456
457 # Data interchange
458 ExpiresByType application/json "access plus 0 seconds"
459 ExpiresByType application/xml "access plus 0 seconds"
460 ExpiresByType text/xml "access plus 0 seconds"
461
462 # Favicon (cannot be renamed!)
463 ExpiresByType image/x-icon "access plus 1 week"
464
465 # HTML components (HTCs)
466 ExpiresByType text/x-component "access plus 1 month"
467
468 # HTML
469 ExpiresByType text/html "access plus 0 seconds"
470
471 # JavaScript
472 ExpiresByType application/javascript "access plus 1 year"
473
474 # Manifest files
475 ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
476 ExpiresByType text/cache-manifest "access plus 0 seconds"
477
478 # Media
479 ExpiresByType audio/ogg "access plus 1 month"
480 ExpiresByType image/gif "access plus 1 month"
481 ExpiresByType image/jpeg "access plus 1 month"
482 ExpiresByType image/png "access plus 1 month"
483 ExpiresByType video/mp4 "access plus 1 month"
484 ExpiresByType video/ogg "access plus 1 month"
485 ExpiresByType video/webm "access plus 1 month"
486
487 # Web feeds
488 ExpiresByType application/atom+xml "access plus 1 hour"
489 ExpiresByType application/rss+xml "access plus 1 hour"
490
491 # Web fonts
492 ExpiresByType application/font-woff "access plus 1 month"
493 ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
494 ExpiresByType application/x-font-ttf "access plus 1 month"
495 ExpiresByType font/opentype "access plus 1 month"
496 ExpiresByType image/svg+xml "access plus 1 month"
497
498</IfModule>
499
500# ------------------------------------------------------------------------------
501# | Filename-based cache busting |
502# ------------------------------------------------------------------------------
503
504# If you're not using a build process to manage your filename version revving,
505# you might want to consider enabling the following directives to route all
506# requests such as `/css/style.12345.css` to `/css/style.css`.
507
508# To understand why this is important and a better idea than `*.css?v231`, read:
509# http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring
510
511# <IfModule mod_rewrite.c>
512# RewriteCond %{REQUEST_FILENAME} !-f
513# RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L]
514# </IfModule>
515
516# ------------------------------------------------------------------------------
517# | File concatenation |
518# ------------------------------------------------------------------------------
519
520# Allow concatenation from within specific CSS and JS files, e.g.:
521# Inside of `script.combined.js` you could have
522# <!--#include file="libs/jquery.js" -->
523# <!--#include file="plugins/jquery.idletimer.js" -->
524# and they would be included into this single file.
525
526# <IfModule mod_include.c>
527# <FilesMatch "\.combined\.js$">
528# Options +Includes
529# AddOutputFilterByType INCLUDES application/javascript application/json
530# SetOutputFilter INCLUDES
531# </FilesMatch>
532# <FilesMatch "\.combined\.css$">
533# Options +Includes
534# AddOutputFilterByType INCLUDES text/css
535# SetOutputFilter INCLUDES
536# </FilesMatch>
537# </IfModule>
538
539# ------------------------------------------------------------------------------
540# | Persistent connections |
541# ------------------------------------------------------------------------------
542
543# Allow multiple requests to be sent over the same TCP connection:
544# http://httpd.apache.org/docs/current/en/mod/core.html#keepalive.
545
546# Enable if you serve a lot of static content but, be aware of the
547# possible disadvantages!
548
549# <IfModule mod_headers.c>
550# Header set Connection Keep-Alive
551# </IfModule>
diff --git a/webapp/vendor/html5-boilerplate-4.3.0/css/main.css b/webapp/vendor/html5-boilerplate-4.3.0/css/main.css
new file mode 100755
index 0000000..294e019
--- /dev/null
+++ b/webapp/vendor/html5-boilerplate-4.3.0/css/main.css
@@ -0,0 +1,304 @@
1/*! HTML5 Boilerplate v4.3.0 | MIT License | http://h5bp.com/ */
2
3/*
4 * What follows is the result of much research on cross-browser styling.
5 * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
6 * Kroc Camen, and the H5BP dev community and team.
7 */
8
9/* ==========================================================================
10 Base styles: opinionated defaults
11 ========================================================================== */
12
13html,
14button,
15input,
16select,
17textarea {
18 color: #222;
19}
20
21html {
22 font-size: 1em;
23 line-height: 1.4;
24}
25
26/*
27 * Remove text-shadow in selection highlight: h5bp.com/i
28 * These selection rule sets have to be separate.
29 * Customize the background color to match your design.
30 */
31
32::-moz-selection {
33 background: #b3d4fc;
34 text-shadow: none;
35}
36
37::selection {
38 background: #b3d4fc;
39 text-shadow: none;
40}
41
42/*
43 * A better looking default horizontal rule
44 */
45
46hr {
47 display: block;
48 height: 1px;
49 border: 0;
50 border-top: 1px solid #ccc;
51 margin: 1em 0;
52 padding: 0;
53}
54
55/*
56 * Remove the gap between images, videos, audio and canvas and the bottom of
57 * their containers: h5bp.com/i/440
58 */
59
60audio,
61canvas,
62img,
63video {
64 vertical-align: middle;
65}
66
67/*
68 * Remove default fieldset styles.
69 */
70
71fieldset {
72 border: 0;
73 margin: 0;
74 padding: 0;
75}
76
77/*
78 * Allow only vertical resizing of textareas.
79 */
80
81textarea {
82 resize: vertical;
83}
84
85/* ==========================================================================
86 Browse Happy prompt
87 ========================================================================== */
88
89.browsehappy {
90 margin: 0.2em 0;
91 background: #ccc;
92 color: #000;
93 padding: 0.2em 0;
94}
95
96/* ==========================================================================
97 Author's custom styles
98 ========================================================================== */
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116/* ==========================================================================
117 Helper classes
118 ========================================================================== */
119
120/*
121 * Image replacement
122 */
123
124.ir {
125 background-color: transparent;
126 border: 0;
127 overflow: hidden;
128 /* IE 6/7 fallback */
129 *text-indent: -9999px;
130}
131
132.ir:before {
133 content: "";
134 display: block;
135 width: 0;
136 height: 150%;
137}
138
139/*
140 * Hide from both screenreaders and browsers: h5bp.com/u
141 */
142
143.hidden {
144 display: none !important;
145 visibility: hidden;
146}
147
148/*
149 * Hide only visually, but have it available for screenreaders: h5bp.com/v
150 */
151
152.visuallyhidden {
153 border: 0;
154 clip: rect(0 0 0 0);
155 height: 1px;
156 margin: -1px;
157 overflow: hidden;
158 padding: 0;
159 position: absolute;
160 width: 1px;
161}
162
163/*
164 * Extends the .visuallyhidden class to allow the element to be focusable
165 * when navigated to via the keyboard: h5bp.com/p
166 */
167
168.visuallyhidden.focusable:active,
169.visuallyhidden.focusable:focus {
170 clip: auto;
171 height: auto;
172 margin: 0;
173 overflow: visible;
174 position: static;
175 width: auto;
176}
177
178/*
179 * Hide visually and from screenreaders, but maintain layout
180 */
181
182.invisible {
183 visibility: hidden;
184}
185
186/*
187 * Clearfix: contain floats
188 *
189 * For modern browsers
190 * 1. The space content is one way to avoid an Opera bug when the
191 * `contenteditable` attribute is included anywhere else in the document.
192 * Otherwise it causes space to appear at the top and bottom of elements
193 * that receive the `clearfix` class.
194 * 2. The use of `table` rather than `block` is only necessary if using
195 * `:before` to contain the top-margins of child elements.
196 */
197
198.clearfix:before,
199.clearfix:after {
200 content: " "; /* 1 */
201 display: table; /* 2 */
202}
203
204.clearfix:after {
205 clear: both;
206}
207
208/*
209 * For IE 6/7 only
210 * Include this rule to trigger hasLayout and contain floats.
211 */
212
213.clearfix {
214 *zoom: 1;
215}
216
217/* ==========================================================================
218 EXAMPLE Media Queries for Responsive Design.
219 These examples override the primary ('mobile first') styles.
220 Modify as content requires.
221 ========================================================================== */
222
223@media only screen and (min-width: 35em) {
224 /* Style adjustments for viewports that meet the condition */
225}
226
227@media print,
228 (-o-min-device-pixel-ratio: 5/4),
229 (-webkit-min-device-pixel-ratio: 1.25),
230 (min-resolution: 120dpi) {
231 /* Style adjustments for high resolution devices */
232}
233
234/* ==========================================================================
235 Print styles.
236 Inlined to avoid required HTTP connection: h5bp.com/r
237 ========================================================================== */
238
239@media print {
240 * {
241 background: transparent !important;
242 color: #000 !important; /* Black prints faster: h5bp.com/s */
243 box-shadow: none !important;
244 text-shadow: none !important;
245 }
246
247 a,
248 a:visited {
249 text-decoration: underline;
250 }
251
252 a[href]:after {
253 content: " (" attr(href) ")";
254 }
255
256 abbr[title]:after {
257 content: " (" attr(title) ")";
258 }
259
260 /*
261 * Don't show links for images, or javascript/internal links
262 */
263
264 .ir a:after,
265 a[href^="javascript:"]:after,
266 a[href^="#"]:after {
267 content: "";
268 }
269
270 pre,
271 blockquote {
272 border: 1px solid #999;
273 page-break-inside: avoid;
274 }
275
276 thead {
277 display: table-header-group; /* h5bp.com/t */
278 }
279
280 tr,
281 img {
282 page-break-inside: avoid;
283 }
284
285 img {
286 max-width: 100% !important;
287 }
288
289 @page {
290 margin: 0.5cm;
291 }
292
293 p,
294 h2,
295 h3 {
296 orphans: 3;
297 widows: 3;
298 }
299
300 h2,
301 h3 {
302 page-break-after: avoid;
303 }
304}
diff --git a/webapp/vendor/html5-boilerplate-4.3.0/css/normalize.css b/webapp/vendor/html5-boilerplate-4.3.0/css/normalize.css
new file mode 100755
index 0000000..42e24d6
--- /dev/null
+++ b/webapp/vendor/html5-boilerplate-4.3.0/css/normalize.css
@@ -0,0 +1,527 @@
1/*! normalize.css v1.1.3 | MIT License | git.io/normalize */
2
3/* ==========================================================================
4 HTML5 display definitions
5 ========================================================================== */
6
7/**
8 * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3.
9 */
10
11article,
12aside,
13details,
14figcaption,
15figure,
16footer,
17header,
18hgroup,
19main,
20nav,
21section,
22summary {
23 display: block;
24}
25
26/**
27 * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.
28 */
29
30audio,
31canvas,
32video {
33 display: inline-block;
34 *display: inline;
35 *zoom: 1;
36}
37
38/**
39 * Prevent modern browsers from displaying `audio` without controls.
40 * Remove excess height in iOS 5 devices.
41 */
42
43audio:not([controls]) {
44 display: none;
45 height: 0;
46}
47
48/**
49 * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4.
50 * Known issue: no IE 6 support.
51 */
52
53[hidden] {
54 display: none;
55}
56
57/* ==========================================================================
58 Base
59 ========================================================================== */
60
61/**
62 * 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using
63 * `em` units.
64 * 2. Prevent iOS text size adjust after orientation change, without disabling
65 * user zoom.
66 */
67
68html {
69 font-size: 100%; /* 1 */
70 -ms-text-size-adjust: 100%; /* 2 */
71 -webkit-text-size-adjust: 100%; /* 2 */
72}
73
74/**
75 * Address `font-family` inconsistency between `textarea` and other form
76 * elements.
77 */
78
79html,
80button,
81input,
82select,
83textarea {
84 font-family: sans-serif;
85}
86
87/**
88 * Address margins handled incorrectly in IE 6/7.
89 */
90
91body {
92 margin: 0;
93}
94
95/* ==========================================================================
96 Links
97 ========================================================================== */
98
99/**
100 * Address `outline` inconsistency between Chrome and other browsers.
101 */
102
103a:focus {
104 outline: thin dotted;
105}
106
107/**
108 * Improve readability when focused and also mouse hovered in all browsers.
109 */
110
111a:active,
112a:hover {
113 outline: 0;
114}
115
116/* ==========================================================================
117 Typography
118 ========================================================================== */
119
120/**
121 * Address font sizes and margins set differently in IE 6/7.
122 * Address font sizes within `section` and `article` in Firefox 4+, Safari 5,
123 * and Chrome.
124 */
125
126h1 {
127 font-size: 2em;
128 margin: 0.67em 0;
129}
130
131h2 {
132 font-size: 1.5em;
133 margin: 0.83em 0;
134}
135
136h3 {
137 font-size: 1.17em;
138 margin: 1em 0;
139}
140
141h4 {
142 font-size: 1em;
143 margin: 1.33em 0;
144}
145
146h5 {
147 font-size: 0.83em;
148 margin: 1.67em 0;
149}
150
151h6 {
152 font-size: 0.67em;
153 margin: 2.33em 0;
154}
155
156/**
157 * Address styling not present in IE 7/8/9, Safari 5, and Chrome.
158 */
159
160abbr[title] {
161 border-bottom: 1px dotted;
162}
163
164/**
165 * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome.
166 */
167
168b,
169strong {
170 font-weight: bold;
171}
172
173blockquote {
174 margin: 1em 40px;
175}
176
177/**
178 * Address styling not present in Safari 5 and Chrome.
179 */
180
181dfn {
182 font-style: italic;
183}
184
185/**
186 * Address differences between Firefox and other browsers.
187 * Known issue: no IE 6/7 normalization.
188 */
189
190hr {
191 -moz-box-sizing: content-box;
192 box-sizing: content-box;
193 height: 0;
194}
195
196/**
197 * Address styling not present in IE 6/7/8/9.
198 */
199
200mark {
201 background: #ff0;
202 color: #000;
203}
204
205/**
206 * Address margins set differently in IE 6/7.
207 */
208
209p,
210pre {
211 margin: 1em 0;
212}
213
214/**
215 * Correct font family set oddly in IE 6, Safari 4/5, and Chrome.
216 */
217
218code,
219kbd,
220pre,
221samp {
222 font-family: monospace, serif;
223 _font-family: 'courier new', monospace;
224 font-size: 1em;
225}
226
227/**
228 * Improve readability of pre-formatted text in all browsers.
229 */
230
231pre {
232 white-space: pre;
233 white-space: pre-wrap;
234 word-wrap: break-word;
235}
236
237/**
238 * Address CSS quotes not supported in IE 6/7.
239 */
240
241q {
242 quotes: none;
243}
244
245/**
246 * Address `quotes` property not supported in Safari 4.
247 */
248
249q:before,
250q:after {
251 content: '';
252 content: none;
253}
254
255/**
256 * Address inconsistent and variable font size in all browsers.
257 */
258
259small {
260 font-size: 80%;
261}
262
263/**
264 * Prevent `sub` and `sup` affecting `line-height` in all browsers.
265 */
266
267sub,
268sup {
269 font-size: 75%;
270 line-height: 0;
271 position: relative;
272 vertical-align: baseline;
273}
274
275sup {
276 top: -0.5em;
277}
278
279sub {
280 bottom: -0.25em;
281}
282
283/* ==========================================================================
284 Lists
285 ========================================================================== */
286
287/**
288 * Address margins set differently in IE 6/7.
289 */
290
291dl,
292menu,
293ol,
294ul {
295 margin: 1em 0;
296}
297
298dd {
299 margin: 0 0 0 40px;
300}
301
302/**
303 * Address paddings set differently in IE 6/7.
304 */
305
306menu,
307ol,
308ul {
309 padding: 0 0 0 40px;
310}
311
312/**
313 * Correct list images handled incorrectly in IE 7.
314 */
315
316nav ul,
317nav ol {
318 list-style: none;
319 list-style-image: none;
320}
321
322/* ==========================================================================
323 Embedded content
324 ========================================================================== */
325
326/**
327 * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3.
328 * 2. Improve image quality when scaled in IE 7.
329 */
330
331img {
332 border: 0; /* 1 */
333 -ms-interpolation-mode: bicubic; /* 2 */
334}
335
336/**
337 * Correct overflow displayed oddly in IE 9.
338 */
339
340svg:not(:root) {
341 overflow: hidden;
342}
343
344/* ==========================================================================
345 Figures
346 ========================================================================== */
347
348/**
349 * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11.
350 */
351
352figure {
353 margin: 0;
354}
355
356/* ==========================================================================
357 Forms
358 ========================================================================== */
359
360/**
361 * Correct margin displayed oddly in IE 6/7.
362 */
363
364form {
365 margin: 0;
366}
367
368/**
369 * Define consistent border, margin, and padding.
370 */
371
372fieldset {
373 border: 1px solid #c0c0c0;
374 margin: 0 2px;
375 padding: 0.35em 0.625em 0.75em;
376}
377
378/**
379 * 1. Correct color not being inherited in IE 6/7/8/9.
380 * 2. Correct text not wrapping in Firefox 3.
381 * 3. Correct alignment displayed oddly in IE 6/7.
382 */
383
384legend {
385 border: 0; /* 1 */
386 padding: 0;
387 white-space: normal; /* 2 */
388 *margin-left: -7px; /* 3 */
389}
390
391/**
392 * 1. Correct font size not being inherited in all browsers.
393 * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5,
394 * and Chrome.
395 * 3. Improve appearance and consistency in all browsers.
396 */
397
398button,
399input,
400select,
401textarea {
402 font-size: 100%; /* 1 */
403 margin: 0; /* 2 */
404 vertical-align: baseline; /* 3 */
405 *vertical-align: middle; /* 3 */
406}
407
408/**
409 * Address Firefox 3+ setting `line-height` on `input` using `!important` in
410 * the UA stylesheet.
411 */
412
413button,
414input {
415 line-height: normal;
416}
417
418/**
419 * Address inconsistent `text-transform` inheritance for `button` and `select`.
420 * All other form control elements do not inherit `text-transform` values.
421 * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+.
422 * Correct `select` style inheritance in Firefox 4+ and Opera.
423 */
424
425button,
426select {
427 text-transform: none;
428}
429
430/**
431 * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
432 * and `video` controls.
433 * 2. Correct inability to style clickable `input` types in iOS.
434 * 3. Improve usability and consistency of cursor style between image-type
435 * `input` and others.
436 * 4. Remove inner spacing in IE 7 without affecting normal text inputs.
437 * Known issue: inner spacing remains in IE 6.
438 */
439
440button,
441html input[type="button"], /* 1 */
442input[type="reset"],
443input[type="submit"] {
444 -webkit-appearance: button; /* 2 */
445 cursor: pointer; /* 3 */
446 *overflow: visible; /* 4 */
447}
448
449/**
450 * Re-set default cursor for disabled elements.
451 */
452
453button[disabled],
454html input[disabled] {
455 cursor: default;
456}
457
458/**
459 * 1. Address box sizing set to content-box in IE 8/9.
460 * 2. Remove excess padding in IE 8/9.
461 * 3. Remove excess padding in IE 7.
462 * Known issue: excess padding remains in IE 6.
463 */
464
465input[type="checkbox"],
466input[type="radio"] {
467 box-sizing: border-box; /* 1 */
468 padding: 0; /* 2 */
469 *height: 13px; /* 3 */
470 *width: 13px; /* 3 */
471}
472
473/**
474 * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
475 * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
476 * (include `-moz` to future-proof).
477 */
478
479input[type="search"] {
480 -webkit-appearance: textfield; /* 1 */
481 -moz-box-sizing: content-box;
482 -webkit-box-sizing: content-box; /* 2 */
483 box-sizing: content-box;
484}
485
486/**
487 * Remove inner padding and search cancel button in Safari 5 and Chrome
488 * on OS X.
489 */
490
491input[type="search"]::-webkit-search-cancel-button,
492input[type="search"]::-webkit-search-decoration {
493 -webkit-appearance: none;
494}
495
496/**
497 * Remove inner padding and border in Firefox 3+.
498 */
499
500button::-moz-focus-inner,
501input::-moz-focus-inner {
502 border: 0;
503 padding: 0;
504}
505
506/**
507 * 1. Remove default vertical scrollbar in IE 6/7/8/9.
508 * 2. Improve readability and alignment in all browsers.
509 */
510
511textarea {
512 overflow: auto; /* 1 */
513 vertical-align: top; /* 2 */
514}
515
516/* ==========================================================================
517 Tables
518 ========================================================================== */
519
520/**
521 * Remove most spacing between table cells.
522 */
523
524table {
525 border-collapse: collapse;
526 border-spacing: 0;
527}
diff --git a/webapp/vendor/jquery-2.1.1.js b/webapp/vendor/jquery-2.1.1.js
new file mode 100644
index 0000000..9f7b3d3
--- /dev/null
+++ b/webapp/vendor/jquery-2.1.1.js
@@ -0,0 +1,9190 @@
1/*!
2 * jQuery JavaScript Library v2.1.1
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: 2014-05-01T17:11Z
13 */
14
15(function( global, factory ) {
16
17 if ( typeof module === "object" && typeof module.exports === "object" ) {
18 // For CommonJS and CommonJS-like environments where a proper window is present,
19 // execute the factory and get jQuery
20 // For environments that do not inherently posses a window with a document
21 // (such as Node.js), expose a jQuery-making factory as module.exports
22 // This accentuates the need for the creation of a real window
23 // e.g. var jQuery = require("jquery")(window);
24 // See ticket #14549 for more info
25 module.exports = global.document ?
26 factory( global, true ) :
27 function( w ) {
28 if ( !w.document ) {
29 throw new Error( "jQuery requires a window with a document" );
30 }
31 return factory( w );
32 };
33 } else {
34 factory( global );
35 }
36
37// Pass this if window is not defined yet
38}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
40// Can't do this because several apps including ASP.NET trace
41// the stack via arguments.caller.callee and Firefox dies if
42// you try to trace through "use strict" call chains. (#13335)
43// Support: Firefox 18+
44//
45
46var arr = [];
47
48var slice = arr.slice;
49
50var concat = arr.concat;
51
52var push = arr.push;
53
54var indexOf = arr.indexOf;
55
56var class2type = {};
57
58var toString = class2type.toString;
59
60var hasOwn = class2type.hasOwnProperty;
61
62var support = {};
63
64
65
66var
67 // Use the correct document accordingly with window argument (sandbox)
68 document = window.document,
69
70 version = "2.1.1",
71
72 // Define a local copy of jQuery
73 jQuery = function( selector, context ) {
74 // The jQuery object is actually just the init constructor 'enhanced'
75 // Need init if jQuery is called (just allow error to be thrown if not included)
76 return new jQuery.fn.init( selector, context );
77 },
78
79 // Support: Android<4.1
80 // Make sure we trim BOM and NBSP
81 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
82
83 // Matches dashed string for camelizing
84 rmsPrefix = /^-ms-/,
85 rdashAlpha = /-([\da-z])/gi,
86
87 // Used by jQuery.camelCase as callback to replace()
88 fcamelCase = function( all, letter ) {
89 return letter.toUpperCase();
90 };
91
92jQuery.fn = jQuery.prototype = {
93 // The current version of jQuery being used
94 jquery: version,
95
96 constructor: jQuery,
97
98 // Start with an empty selector
99 selector: "",
100
101 // The default length of a jQuery object is 0
102 length: 0,
103
104 toArray: function() {
105 return slice.call( this );
106 },
107
108 // Get the Nth element in the matched element set OR
109 // Get the whole matched element set as a clean array
110 get: function( num ) {
111 return num != null ?
112
113 // Return just the one element from the set
114 ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
115
116 // Return all the elements in a clean array
117 slice.call( this );
118 },
119
120 // Take an array of elements and push it onto the stack
121 // (returning the new matched element set)
122 pushStack: function( elems ) {
123
124 // Build a new jQuery matched element set
125 var ret = jQuery.merge( this.constructor(), elems );
126
127 // Add the old object onto the stack (as a reference)
128 ret.prevObject = this;
129 ret.context = this.context;
130
131 // Return the newly-formed element set
132 return ret;
133 },
134
135 // Execute a callback for every element in the matched set.
136 // (You can seed the arguments with an array of args, but this is
137 // only used internally.)
138 each: function( callback, args ) {
139 return jQuery.each( this, callback, args );
140 },
141
142 map: function( callback ) {
143 return this.pushStack( jQuery.map(this, function( elem, i ) {
144 return callback.call( elem, i, elem );
145 }));
146 },
147
148 slice: function() {
149 return this.pushStack( slice.apply( this, arguments ) );
150 },
151
152 first: function() {
153 return this.eq( 0 );
154 },
155
156 last: function() {
157 return this.eq( -1 );
158 },
159
160 eq: function( i ) {
161 var len = this.length,
162 j = +i + ( i < 0 ? len : 0 );
163 return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
164 },
165
166 end: function() {
167 return this.prevObject || this.constructor(null);
168 },
169
170 // For internal use only.
171 // Behaves like an Array's method, not like a jQuery method.
172 push: push,
173 sort: arr.sort,
174 splice: arr.splice
175};
176
177jQuery.extend = jQuery.fn.extend = function() {
178 var options, name, src, copy, copyIsArray, clone,
179 target = arguments[0] || {},
180 i = 1,
181 length = arguments.length,
182 deep = false;
183
184 // Handle a deep copy situation
185 if ( typeof target === "boolean" ) {
186 deep = target;
187
188 // skip the boolean and the target
189 target = arguments[ i ] || {};
190 i++;
191 }
192
193 // Handle case when target is a string or something (possible in deep copy)
194 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
195 target = {};
196 }
197
198 // extend jQuery itself if only one argument is passed
199 if ( i === length ) {
200 target = this;
201 i--;
202 }
203
204 for ( ; i < length; i++ ) {
205 // Only deal with non-null/undefined values
206 if ( (options = arguments[ i ]) != null ) {
207 // Extend the base object
208 for ( name in options ) {
209 src = target[ name ];
210 copy = options[ name ];
211
212 // Prevent never-ending loop
213 if ( target === copy ) {
214 continue;
215 }
216
217 // Recurse if we're merging plain objects or arrays
218 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
219 if ( copyIsArray ) {
220 copyIsArray = false;
221 clone = src && jQuery.isArray(src) ? src : [];
222
223 } else {
224 clone = src && jQuery.isPlainObject(src) ? src : {};
225 }
226
227 // Never move original objects, clone them
228 target[ name ] = jQuery.extend( deep, clone, copy );
229
230 // Don't bring in undefined values
231 } else if ( copy !== undefined ) {
232 target[ name ] = copy;
233 }
234 }
235 }
236 }
237
238 // Return the modified object
239 return target;
240};
241
242jQuery.extend({
243 // Unique for each copy of jQuery on the page
244 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
245
246 // Assume jQuery is ready without the ready module
247 isReady: true,
248
249 error: function( msg ) {
250 throw new Error( msg );
251 },
252
253 noop: function() {},
254
255 // See test/unit/core.js for details concerning isFunction.
256 // Since version 1.3, DOM methods and functions like alert
257 // aren't supported. They return false on IE (#2968).
258 isFunction: function( obj ) {
259 return jQuery.type(obj) === "function";
260 },
261
262 isArray: Array.isArray,
263
264 isWindow: function( obj ) {
265 return obj != null && obj === obj.window;
266 },
267
268 isNumeric: function( obj ) {
269 // parseFloat NaNs numeric-cast false positives (null|true|false|"")
270 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
271 // subtraction forces infinities to NaN
272 return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
273 },
274
275 isPlainObject: function( obj ) {
276 // Not plain objects:
277 // - Any object or value whose internal [[Class]] property is not "[object Object]"
278 // - DOM nodes
279 // - window
280 if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
281 return false;
282 }
283
284 if ( obj.constructor &&
285 !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
286 return false;
287 }
288
289 // If the function hasn't returned already, we're confident that
290 // |obj| is a plain object, created by {} or constructed with new Object
291 return true;
292 },
293
294 isEmptyObject: function( obj ) {
295 var name;
296 for ( name in obj ) {
297 return false;
298 }
299 return true;
300 },
301
302 type: function( obj ) {
303 if ( obj == null ) {
304 return obj + "";
305 }
306 // Support: Android < 4.0, iOS < 6 (functionish RegExp)
307 return typeof obj === "object" || typeof obj === "function" ?
308 class2type[ toString.call(obj) ] || "object" :
309 typeof obj;
310 },
311
312 // Evaluates a script in a global context
313 globalEval: function( code ) {
314 var script,
315 indirect = eval;
316
317 code = jQuery.trim( code );
318
319 if ( code ) {
320 // If the code includes a valid, prologue position
321 // strict mode pragma, execute code by injecting a
322 // script tag into the document.
323 if ( code.indexOf("use strict") === 1 ) {
324 script = document.createElement("script");
325 script.text = code;
326 document.head.appendChild( script ).parentNode.removeChild( script );
327 } else {
328 // Otherwise, avoid the DOM node creation, insertion
329 // and removal by using an indirect global eval
330 indirect( code );
331 }
332 }
333 },
334
335 // Convert dashed to camelCase; used by the css and data modules
336 // Microsoft forgot to hump their vendor prefix (#9572)
337 camelCase: function( string ) {
338 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
339 },
340
341 nodeName: function( elem, name ) {
342 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
343 },
344
345 // args is for internal usage only
346 each: function( obj, callback, args ) {
347 var value,
348 i = 0,
349 length = obj.length,
350 isArray = isArraylike( obj );
351
352 if ( args ) {
353 if ( isArray ) {
354 for ( ; i < length; i++ ) {
355 value = callback.apply( obj[ i ], args );
356
357 if ( value === false ) {
358 break;
359 }
360 }
361 } else {
362 for ( i in obj ) {
363 value = callback.apply( obj[ i ], args );
364
365 if ( value === false ) {
366 break;
367 }
368 }
369 }
370
371 // A special, fast, case for the most common use of each
372 } else {
373 if ( isArray ) {
374 for ( ; i < length; i++ ) {
375 value = callback.call( obj[ i ], i, obj[ i ] );
376
377 if ( value === false ) {
378 break;
379 }
380 }
381 } else {
382 for ( i in obj ) {
383 value = callback.call( obj[ i ], i, obj[ i ] );
384
385 if ( value === false ) {
386 break;
387 }
388 }
389 }
390 }
391
392 return obj;
393 },
394
395 // Support: Android<4.1
396 trim: function( text ) {
397 return text == null ?
398 "" :
399 ( text + "" ).replace( rtrim, "" );
400 },
401
402 // results is for internal usage only
403 makeArray: function( arr, results ) {
404 var ret = results || [];
405
406 if ( arr != null ) {
407 if ( isArraylike( Object(arr) ) ) {
408 jQuery.merge( ret,
409 typeof arr === "string" ?
410 [ arr ] : arr
411 );
412 } else {
413 push.call( ret, arr );
414 }
415 }
416
417 return ret;
418 },
419
420 inArray: function( elem, arr, i ) {
421 return arr == null ? -1 : indexOf.call( arr, elem, i );
422 },
423
424 merge: function( first, second ) {
425 var len = +second.length,
426 j = 0,
427 i = first.length;
428
429 for ( ; j < len; j++ ) {
430 first[ i++ ] = second[ j ];
431 }
432
433 first.length = i;
434
435 return first;
436 },
437
438 grep: function( elems, callback, invert ) {
439 var callbackInverse,
440 matches = [],
441 i = 0,
442 length = elems.length,
443 callbackExpect = !invert;
444
445 // Go through the array, only saving the items
446 // that pass the validator function
447 for ( ; i < length; i++ ) {
448 callbackInverse = !callback( elems[ i ], i );
449 if ( callbackInverse !== callbackExpect ) {
450 matches.push( elems[ i ] );
451 }
452 }
453
454 return matches;
455 },
456
457 // arg is for internal usage only
458 map: function( elems, callback, arg ) {
459 var value,
460 i = 0,
461 length = elems.length,
462 isArray = isArraylike( elems ),
463 ret = [];
464
465 // Go through the array, translating each of the items to their new values
466 if ( isArray ) {
467 for ( ; i < length; i++ ) {
468 value = callback( elems[ i ], i, arg );
469
470 if ( value != null ) {
471 ret.push( value );
472 }
473 }
474
475 // Go through every key on the object,
476 } else {
477 for ( i in elems ) {
478 value = callback( elems[ i ], i, arg );
479
480 if ( value != null ) {
481 ret.push( value );
482 }
483 }
484 }
485
486 // Flatten any nested arrays
487 return concat.apply( [], ret );
488 },
489
490 // A global GUID counter for objects
491 guid: 1,
492
493 // Bind a function to a context, optionally partially applying any
494 // arguments.
495 proxy: function( fn, context ) {
496 var tmp, args, proxy;
497
498 if ( typeof context === "string" ) {
499 tmp = fn[ context ];
500 context = fn;
501 fn = tmp;
502 }
503
504 // Quick check to determine if target is callable, in the spec
505 // this throws a TypeError, but we will just return undefined.
506 if ( !jQuery.isFunction( fn ) ) {
507 return undefined;
508 }
509
510 // Simulated bind
511 args = slice.call( arguments, 2 );
512 proxy = function() {
513 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
514 };
515
516 // Set the guid of unique handler to the same of original handler, so it can be removed
517 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
518
519 return proxy;
520 },
521
522 now: Date.now,
523
524 // jQuery.support is not used in Core but other projects attach their
525 // properties to it so it needs to exist.
526 support: support
527});
528
529// Populate the class2type map
530jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
531 class2type[ "[object " + name + "]" ] = name.toLowerCase();
532});
533
534function isArraylike( obj ) {
535 var length = obj.length,
536 type = jQuery.type( obj );
537
538 if ( type === "function" || jQuery.isWindow( obj ) ) {
539 return false;
540 }
541
542 if ( obj.nodeType === 1 && length ) {
543 return true;
544 }
545
546 return type === "array" || length === 0 ||
547 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
548}
549var Sizzle =
550/*!
551 * Sizzle CSS Selector Engine v1.10.19
552 * http://sizzlejs.com/
553 *
554 * Copyright 2013 jQuery Foundation, Inc. and other contributors
555 * Released under the MIT license
556 * http://jquery.org/license
557 *
558 * Date: 2014-04-18
559 */
560(function( window ) {
561
562var i,
563 support,
564 Expr,
565 getText,
566 isXML,
567 tokenize,
568 compile,
569 select,
570 outermostContext,
571 sortInput,
572 hasDuplicate,
573
574 // Local document vars
575 setDocument,
576 document,
577 docElem,
578 documentIsHTML,
579 rbuggyQSA,
580 rbuggyMatches,
581 matches,
582 contains,
583
584 // Instance-specific data
585 expando = "sizzle" + -(new Date()),
586 preferredDoc = window.document,
587 dirruns = 0,
588 done = 0,
589 classCache = createCache(),
590 tokenCache = createCache(),
591 compilerCache = createCache(),
592 sortOrder = function( a, b ) {
593 if ( a === b ) {
594 hasDuplicate = true;
595 }
596 return 0;
597 },
598
599 // General-purpose constants
600 strundefined = typeof undefined,
601 MAX_NEGATIVE = 1 << 31,
602
603 // Instance methods
604 hasOwn = ({}).hasOwnProperty,
605 arr = [],
606 pop = arr.pop,
607 push_native = arr.push,
608 push = arr.push,
609 slice = arr.slice,
610 // Use a stripped-down indexOf if we can't use a native one
611 indexOf = arr.indexOf || function( elem ) {
612 var i = 0,
613 len = this.length;
614 for ( ; i < len; i++ ) {
615 if ( this[i] === elem ) {
616 return i;
617 }
618 }
619 return -1;
620 },
621
622 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
623
624 // Regular expressions
625
626 // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
627 whitespace = "[\\x20\\t\\r\\n\\f]",
628 // http://www.w3.org/TR/css3-syntax/#characters
629 characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
630
631 // Loosely modeled on CSS identifier characters
632 // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
633 // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
634 identifier = characterEncoding.replace( "w", "w#" ),
635
636 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
637 attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
638 // Operator (capture 2)
639 "*([*^$|!~]?=)" + whitespace +
640 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
641 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
642 "*\\]",
643
644 pseudos = ":(" + characterEncoding + ")(?:\\((" +
645 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
646 // 1. quoted (capture 3; capture 4 or capture 5)
647 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
648 // 2. simple (capture 6)
649 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
650 // 3. anything else (capture 2)
651 ".*" +
652 ")\\)|)",
653
654 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
655 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
656
657 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
658 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
659
660 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
661
662 rpseudo = new RegExp( pseudos ),
663 ridentifier = new RegExp( "^" + identifier + "$" ),
664
665 matchExpr = {
666 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
667 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
668 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
669 "ATTR": new RegExp( "^" + attributes ),
670 "PSEUDO": new RegExp( "^" + pseudos ),
671 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
672 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
673 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
674 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
675 // For use in libraries implementing .is()
676 // We use this for POS matching in `select`
677 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
678 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
679 },
680
681 rinputs = /^(?:input|select|textarea|button)$/i,
682 rheader = /^h\d$/i,
683
684 rnative = /^[^{]+\{\s*\[native \w/,
685
686 // Easily-parseable/retrievable ID or TAG or CLASS selectors
687 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
688
689 rsibling = /[+~]/,
690 rescape = /'|\\/g,
691
692 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
693 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
694 funescape = function( _, escaped, escapedWhitespace ) {
695 var high = "0x" + escaped - 0x10000;
696 // NaN means non-codepoint
697 // Support: Firefox<24
698 // Workaround erroneous numeric interpretation of +"0x"
699 return high !== high || escapedWhitespace ?
700 escaped :
701 high < 0 ?
702 // BMP codepoint
703 String.fromCharCode( high + 0x10000 ) :
704 // Supplemental Plane codepoint (surrogate pair)
705 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
706 };
707
708// Optimize for push.apply( _, NodeList )
709try {
710 push.apply(
711 (arr = slice.call( preferredDoc.childNodes )),
712 preferredDoc.childNodes
713 );
714 // Support: Android<4.0
715 // Detect silently failing push.apply
716 arr[ preferredDoc.childNodes.length ].nodeType;
717} catch ( e ) {
718 push = { apply: arr.length ?
719
720 // Leverage slice if possible
721 function( target, els ) {
722 push_native.apply( target, slice.call(els) );
723 } :
724
725 // Support: IE<9
726 // Otherwise append directly
727 function( target, els ) {
728 var j = target.length,
729 i = 0;
730 // Can't trust NodeList.length
731 while ( (target[j++] = els[i++]) ) {}
732 target.length = j - 1;
733 }
734 };
735}
736
737function Sizzle( selector, context, results, seed ) {
738 var match, elem, m, nodeType,
739 // QSA vars
740 i, groups, old, nid, newContext, newSelector;
741
742 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
743 setDocument( context );
744 }
745
746 context = context || document;
747 results = results || [];
748
749 if ( !selector || typeof selector !== "string" ) {
750 return results;
751 }
752
753 if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
754 return [];
755 }
756
757 if ( documentIsHTML && !seed ) {
758
759 // Shortcuts
760 if ( (match = rquickExpr.exec( selector )) ) {
761 // Speed-up: Sizzle("#ID")
762 if ( (m = match[1]) ) {
763 if ( nodeType === 9 ) {
764 elem = context.getElementById( m );
765 // Check parentNode to catch when Blackberry 4.6 returns
766 // nodes that are no longer in the document (jQuery #6963)
767 if ( elem && elem.parentNode ) {
768 // Handle the case where IE, Opera, and Webkit return items
769 // by name instead of ID
770 if ( elem.id === m ) {
771 results.push( elem );
772 return results;
773 }
774 } else {
775 return results;
776 }
777 } else {
778 // Context is not a document
779 if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
780 contains( context, elem ) && elem.id === m ) {
781 results.push( elem );
782 return results;
783 }
784 }
785
786 // Speed-up: Sizzle("TAG")
787 } else if ( match[2] ) {
788 push.apply( results, context.getElementsByTagName( selector ) );
789 return results;
790
791 // Speed-up: Sizzle(".CLASS")
792 } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
793 push.apply( results, context.getElementsByClassName( m ) );
794 return results;
795 }
796 }
797
798 // QSA path
799 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
800 nid = old = expando;
801 newContext = context;
802 newSelector = nodeType === 9 && selector;
803
804 // qSA works strangely on Element-rooted queries
805 // We can work around this by specifying an extra ID on the root
806 // and working up from there (Thanks to Andrew Dupont for the technique)
807 // IE 8 doesn't work on object elements
808 if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
809 groups = tokenize( selector );
810
811 if ( (old = context.getAttribute("id")) ) {
812 nid = old.replace( rescape, "\\$&" );
813 } else {
814 context.setAttribute( "id", nid );
815 }
816 nid = "[id='" + nid + "'] ";
817
818 i = groups.length;
819 while ( i-- ) {
820 groups[i] = nid + toSelector( groups[i] );
821 }
822 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
823 newSelector = groups.join(",");
824 }
825
826 if ( newSelector ) {
827 try {
828 push.apply( results,
829 newContext.querySelectorAll( newSelector )
830 );
831 return results;
832 } catch(qsaError) {
833 } finally {
834 if ( !old ) {
835 context.removeAttribute("id");
836 }
837 }
838 }
839 }
840 }
841
842 // All others
843 return select( selector.replace( rtrim, "$1" ), context, results, seed );
844}
845
846/**
847 * Create key-value caches of limited size
848 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
849 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
850 * deleting the oldest entry
851 */
852function createCache() {
853 var keys = [];
854
855 function cache( key, value ) {
856 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
857 if ( keys.push( key + " " ) > Expr.cacheLength ) {
858 // Only keep the most recent entries
859 delete cache[ keys.shift() ];
860 }
861 return (cache[ key + " " ] = value);
862 }
863 return cache;
864}
865
866/**
867 * Mark a function for special use by Sizzle
868 * @param {Function} fn The function to mark
869 */
870function markFunction( fn ) {
871 fn[ expando ] = true;
872 return fn;
873}
874
875/**
876 * Support testing using an element
877 * @param {Function} fn Passed the created div and expects a boolean result
878 */
879function assert( fn ) {
880 var div = document.createElement("div");
881
882 try {
883 return !!fn( div );
884 } catch (e) {
885 return false;
886 } finally {
887 // Remove from its parent by default
888 if ( div.parentNode ) {
889 div.parentNode.removeChild( div );
890 }
891 // release memory in IE
892 div = null;
893 }
894}
895
896/**
897 * Adds the same handler for all of the specified attrs
898 * @param {String} attrs Pipe-separated list of attributes
899 * @param {Function} handler The method that will be applied
900 */
901function addHandle( attrs, handler ) {
902 var arr = attrs.split("|"),
903 i = attrs.length;
904
905 while ( i-- ) {
906 Expr.attrHandle[ arr[i] ] = handler;
907 }
908}
909
910/**
911 * Checks document order of two siblings
912 * @param {Element} a
913 * @param {Element} b
914 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
915 */
916function siblingCheck( a, b ) {
917 var cur = b && a,
918 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
919 ( ~b.sourceIndex || MAX_NEGATIVE ) -
920 ( ~a.sourceIndex || MAX_NEGATIVE );
921
922 // Use IE sourceIndex if available on both nodes
923 if ( diff ) {
924 return diff;
925 }
926
927 // Check if b follows a
928 if ( cur ) {
929 while ( (cur = cur.nextSibling) ) {
930 if ( cur === b ) {
931 return -1;
932 }
933 }
934 }
935
936 return a ? 1 : -1;
937}
938
939/**
940 * Returns a function to use in pseudos for input types
941 * @param {String} type
942 */
943function createInputPseudo( type ) {
944 return function( elem ) {
945 var name = elem.nodeName.toLowerCase();
946 return name === "input" && elem.type === type;
947 };
948}
949
950/**
951 * Returns a function to use in pseudos for buttons
952 * @param {String} type
953 */
954function createButtonPseudo( type ) {
955 return function( elem ) {
956 var name = elem.nodeName.toLowerCase();
957 return (name === "input" || name === "button") && elem.type === type;
958 };
959}
960
961/**
962 * Returns a function to use in pseudos for positionals
963 * @param {Function} fn
964 */
965function createPositionalPseudo( fn ) {
966 return markFunction(function( argument ) {
967 argument = +argument;
968 return markFunction(function( seed, matches ) {
969 var j,
970 matchIndexes = fn( [], seed.length, argument ),
971 i = matchIndexes.length;
972
973 // Match elements found at the specified indexes
974 while ( i-- ) {
975 if ( seed[ (j = matchIndexes[i]) ] ) {
976 seed[j] = !(matches[j] = seed[j]);
977 }
978 }
979 });
980 });
981}
982
983/**
984 * Checks a node for validity as a Sizzle context
985 * @param {Element|Object=} context
986 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
987 */
988function testContext( context ) {
989 return context && typeof context.getElementsByTagName !== strundefined && context;
990}
991
992// Expose support vars for convenience
993support = Sizzle.support = {};
994
995/**
996 * Detects XML nodes
997 * @param {Element|Object} elem An element or a document
998 * @returns {Boolean} True iff elem is a non-HTML XML node
999 */
1000isXML = Sizzle.isXML = function( elem ) {
1001 // documentElement is verified for cases where it doesn't yet exist
1002 // (such as loading iframes in IE - #4833)
1003 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1004 return documentElement ? documentElement.nodeName !== "HTML" : false;
1005};
1006
1007/**
1008 * Sets document-related variables once based on the current document
1009 * @param {Element|Object} [doc] An element or document object to use to set the document
1010 * @returns {Object} Returns the current document
1011 */
1012setDocument = Sizzle.setDocument = function( node ) {
1013 var hasCompare,
1014 doc = node ? node.ownerDocument || node : preferredDoc,
1015 parent = doc.defaultView;
1016
1017 // If no document and documentElement is available, return
1018 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1019 return document;
1020 }
1021
1022 // Set our document
1023 document = doc;
1024 docElem = doc.documentElement;
1025
1026 // Support tests
1027 documentIsHTML = !isXML( doc );
1028
1029 // Support: IE>8
1030 // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1031 // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1032 // IE6-8 do not support the defaultView property so parent will be undefined
1033 if ( parent && parent !== parent.top ) {
1034 // IE11 does not have attachEvent, so all must suffer
1035 if ( parent.addEventListener ) {
1036 parent.addEventListener( "unload", function() {
1037 setDocument();
1038 }, false );
1039 } else if ( parent.attachEvent ) {
1040 parent.attachEvent( "onunload", function() {
1041 setDocument();
1042 });
1043 }
1044 }
1045
1046 /* Attributes
1047 ---------------------------------------------------------------------- */
1048
1049 // Support: IE<8
1050 // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
1051 support.attributes = assert(function( div ) {
1052 div.className = "i";
1053 return !div.getAttribute("className");
1054 });
1055
1056 /* getElement(s)By*
1057 ---------------------------------------------------------------------- */
1058
1059 // Check if getElementsByTagName("*") returns only elements
1060 support.getElementsByTagName = assert(function( div ) {
1061 div.appendChild( doc.createComment("") );
1062 return !div.getElementsByTagName("*").length;
1063 });
1064
1065 // Check if getElementsByClassName can be trusted
1066 support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
1067 div.innerHTML = "<div class='a'></div><div class='a i'></div>";
1068
1069 // Support: Safari<4
1070 // Catch class over-caching
1071 div.firstChild.className = "i";
1072 // Support: Opera<10
1073 // Catch gEBCN failure to find non-leading classes
1074 return div.getElementsByClassName("i").length === 2;
1075 });
1076
1077 // Support: IE<10
1078 // Check if getElementById returns elements by name
1079 // The broken getElementById methods don't pick up programatically-set names,
1080 // so use a roundabout getElementsByName test
1081 support.getById = assert(function( div ) {
1082 docElem.appendChild( div ).id = expando;
1083 return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1084 });
1085
1086 // ID find and filter
1087 if ( support.getById ) {
1088 Expr.find["ID"] = function( id, context ) {
1089 if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
1090 var m = context.getElementById( id );
1091 // Check parentNode to catch when Blackberry 4.6 returns
1092 // nodes that are no longer in the document #6963
1093 return m && m.parentNode ? [ m ] : [];
1094 }
1095 };
1096 Expr.filter["ID"] = function( id ) {
1097 var attrId = id.replace( runescape, funescape );
1098 return function( elem ) {
1099 return elem.getAttribute("id") === attrId;
1100 };
1101 };
1102 } else {
1103 // Support: IE6/7
1104 // getElementById is not reliable as a find shortcut
1105 delete Expr.find["ID"];
1106
1107 Expr.filter["ID"] = function( id ) {
1108 var attrId = id.replace( runescape, funescape );
1109 return function( elem ) {
1110 var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
1111 return node && node.value === attrId;
1112 };
1113 };
1114 }
1115
1116 // Tag
1117 Expr.find["TAG"] = support.getElementsByTagName ?
1118 function( tag, context ) {
1119 if ( typeof context.getElementsByTagName !== strundefined ) {
1120 return context.getElementsByTagName( tag );
1121 }
1122 } :
1123 function( tag, context ) {
1124 var elem,
1125 tmp = [],
1126 i = 0,
1127 results = context.getElementsByTagName( tag );
1128
1129 // Filter out possible comments
1130 if ( tag === "*" ) {
1131 while ( (elem = results[i++]) ) {
1132 if ( elem.nodeType === 1 ) {
1133 tmp.push( elem );
1134 }
1135 }
1136
1137 return tmp;
1138 }
1139 return results;
1140 };
1141
1142 // Class
1143 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1144 if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
1145 return context.getElementsByClassName( className );
1146 }
1147 };
1148
1149 /* QSA/matchesSelector
1150 ---------------------------------------------------------------------- */
1151
1152 // QSA and matchesSelector support
1153
1154 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1155 rbuggyMatches = [];
1156
1157 // qSa(:focus) reports false when true (Chrome 21)
1158 // We allow this because of a bug in IE8/9 that throws an error
1159 // whenever `document.activeElement` is accessed on an iframe
1160 // So, we allow :focus to pass through QSA all the time to avoid the IE error
1161 // See http://bugs.jquery.com/ticket/13378
1162 rbuggyQSA = [];
1163
1164 if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1165 // Build QSA regex
1166 // Regex strategy adopted from Diego Perini
1167 assert(function( div ) {
1168 // Select is set to empty string on purpose
1169 // This is to test IE's treatment of not explicitly
1170 // setting a boolean content attribute,
1171 // since its presence should be enough
1172 // http://bugs.jquery.com/ticket/12359
1173 div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
1174
1175 // Support: IE8, Opera 11-12.16
1176 // Nothing should be selected when empty strings follow ^= or $= or *=
1177 // The test attribute must be unknown in Opera but "safe" for WinRT
1178 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1179 if ( div.querySelectorAll("[msallowclip^='']").length ) {
1180 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1181 }
1182
1183 // Support: IE8
1184 // Boolean attributes and "value" are not treated correctly
1185 if ( !div.querySelectorAll("[selected]").length ) {
1186 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1187 }
1188
1189 // Webkit/Opera - :checked should return selected option elements
1190 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1191 // IE8 throws error here and will not see later tests
1192 if ( !div.querySelectorAll(":checked").length ) {
1193 rbuggyQSA.push(":checked");
1194 }
1195 });
1196
1197 assert(function( div ) {
1198 // Support: Windows 8 Native Apps
1199 // The type and name attributes are restricted during .innerHTML assignment
1200 var input = doc.createElement("input");
1201 input.setAttribute( "type", "hidden" );
1202 div.appendChild( input ).setAttribute( "name", "D" );
1203
1204 // Support: IE8
1205 // Enforce case-sensitivity of name attribute
1206 if ( div.querySelectorAll("[name=d]").length ) {
1207 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1208 }
1209
1210 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1211 // IE8 throws error here and will not see later tests
1212 if ( !div.querySelectorAll(":enabled").length ) {
1213 rbuggyQSA.push( ":enabled", ":disabled" );
1214 }
1215
1216 // Opera 10-11 does not throw on post-comma invalid pseudos
1217 div.querySelectorAll("*,:x");
1218 rbuggyQSA.push(",.*:");
1219 });
1220 }
1221
1222 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1223 docElem.webkitMatchesSelector ||
1224 docElem.mozMatchesSelector ||
1225 docElem.oMatchesSelector ||
1226 docElem.msMatchesSelector) )) ) {
1227
1228 assert(function( div ) {
1229 // Check to see if it's possible to do matchesSelector
1230 // on a disconnected node (IE 9)
1231 support.disconnectedMatch = matches.call( div, "div" );
1232
1233 // This should fail with an exception
1234 // Gecko does not error, returns false instead
1235 matches.call( div, "[s!='']:x" );
1236 rbuggyMatches.push( "!=", pseudos );
1237 });
1238 }
1239
1240 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1241 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1242
1243 /* Contains
1244 ---------------------------------------------------------------------- */
1245 hasCompare = rnative.test( docElem.compareDocumentPosition );
1246
1247 // Element contains another
1248 // Purposefully does not implement inclusive descendent
1249 // As in, an element does not contain itself
1250 contains = hasCompare || rnative.test( docElem.contains ) ?
1251 function( a, b ) {
1252 var adown = a.nodeType === 9 ? a.documentElement : a,
1253 bup = b && b.parentNode;
1254 return a === bup || !!( bup && bup.nodeType === 1 && (
1255 adown.contains ?
1256 adown.contains( bup ) :
1257 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1258 ));
1259 } :
1260 function( a, b ) {
1261 if ( b ) {
1262 while ( (b = b.parentNode) ) {
1263 if ( b === a ) {
1264 return true;
1265 }
1266 }
1267 }
1268 return false;
1269 };
1270
1271 /* Sorting
1272 ---------------------------------------------------------------------- */
1273
1274 // Document order sorting
1275 sortOrder = hasCompare ?
1276 function( a, b ) {
1277
1278 // Flag for duplicate removal
1279 if ( a === b ) {
1280 hasDuplicate = true;
1281 return 0;
1282 }
1283
1284 // Sort on method existence if only one input has compareDocumentPosition
1285 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1286 if ( compare ) {
1287 return compare;
1288 }
1289
1290 // Calculate position if both inputs belong to the same document
1291 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1292 a.compareDocumentPosition( b ) :
1293
1294 // Otherwise we know they are disconnected
1295 1;
1296
1297 // Disconnected nodes
1298 if ( compare & 1 ||
1299 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1300
1301 // Choose the first element that is related to our preferred document
1302 if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1303 return -1;
1304 }
1305 if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1306 return 1;
1307 }
1308
1309 // Maintain original order
1310 return sortInput ?
1311 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1312 0;
1313 }
1314
1315 return compare & 4 ? -1 : 1;
1316 } :
1317 function( a, b ) {
1318 // Exit early if the nodes are identical
1319 if ( a === b ) {
1320 hasDuplicate = true;
1321 return 0;
1322 }
1323
1324 var cur,
1325 i = 0,
1326 aup = a.parentNode,
1327 bup = b.parentNode,
1328 ap = [ a ],
1329 bp = [ b ];
1330
1331 // Parentless nodes are either documents or disconnected
1332 if ( !aup || !bup ) {
1333 return a === doc ? -1 :
1334 b === doc ? 1 :
1335 aup ? -1 :
1336 bup ? 1 :
1337 sortInput ?
1338 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1339 0;
1340
1341 // If the nodes are siblings, we can do a quick check
1342 } else if ( aup === bup ) {
1343 return siblingCheck( a, b );
1344 }
1345
1346 // Otherwise we need full lists of their ancestors for comparison
1347 cur = a;
1348 while ( (cur = cur.parentNode) ) {
1349 ap.unshift( cur );
1350 }
1351 cur = b;
1352 while ( (cur = cur.parentNode) ) {
1353 bp.unshift( cur );
1354 }
1355
1356 // Walk down the tree looking for a discrepancy
1357 while ( ap[i] === bp[i] ) {
1358 i++;
1359 }
1360
1361 return i ?
1362 // Do a sibling check if the nodes have a common ancestor
1363 siblingCheck( ap[i], bp[i] ) :
1364
1365 // Otherwise nodes in our document sort first
1366 ap[i] === preferredDoc ? -1 :
1367 bp[i] === preferredDoc ? 1 :
1368 0;
1369 };
1370
1371 return doc;
1372};
1373
1374Sizzle.matches = function( expr, elements ) {
1375 return Sizzle( expr, null, null, elements );
1376};
1377
1378Sizzle.matchesSelector = function( elem, expr ) {
1379 // Set document vars if needed
1380 if ( ( elem.ownerDocument || elem ) !== document ) {
1381 setDocument( elem );
1382 }
1383
1384 // Make sure that attribute selectors are quoted
1385 expr = expr.replace( rattributeQuotes, "='$1']" );
1386
1387 if ( support.matchesSelector && documentIsHTML &&
1388 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1389 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1390
1391 try {
1392 var ret = matches.call( elem, expr );
1393
1394 // IE 9's matchesSelector returns false on disconnected nodes
1395 if ( ret || support.disconnectedMatch ||
1396 // As well, disconnected nodes are said to be in a document
1397 // fragment in IE 9
1398 elem.document && elem.document.nodeType !== 11 ) {
1399 return ret;
1400 }
1401 } catch(e) {}
1402 }
1403
1404 return Sizzle( expr, document, null, [ elem ] ).length > 0;
1405};
1406
1407Sizzle.contains = function( context, elem ) {
1408 // Set document vars if needed
1409 if ( ( context.ownerDocument || context ) !== document ) {
1410 setDocument( context );
1411 }
1412 return contains( context, elem );
1413};
1414
1415Sizzle.attr = function( elem, name ) {
1416 // Set document vars if needed
1417 if ( ( elem.ownerDocument || elem ) !== document ) {
1418 setDocument( elem );
1419 }
1420
1421 var fn = Expr.attrHandle[ name.toLowerCase() ],
1422 // Don't get fooled by Object.prototype properties (jQuery #13807)
1423 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1424 fn( elem, name, !documentIsHTML ) :
1425 undefined;
1426
1427 return val !== undefined ?
1428 val :
1429 support.attributes || !documentIsHTML ?
1430 elem.getAttribute( name ) :
1431 (val = elem.getAttributeNode(name)) && val.specified ?
1432 val.value :
1433 null;
1434};
1435
1436Sizzle.error = function( msg ) {
1437 throw new Error( "Syntax error, unrecognized expression: " + msg );
1438};
1439
1440/**
1441 * Document sorting and removing duplicates
1442 * @param {ArrayLike} results
1443 */
1444Sizzle.uniqueSort = function( results ) {
1445 var elem,
1446 duplicates = [],
1447 j = 0,
1448 i = 0;
1449
1450 // Unless we *know* we can detect duplicates, assume their presence
1451 hasDuplicate = !support.detectDuplicates;
1452 sortInput = !support.sortStable && results.slice( 0 );
1453 results.sort( sortOrder );
1454
1455 if ( hasDuplicate ) {
1456 while ( (elem = results[i++]) ) {
1457 if ( elem === results[ i ] ) {
1458 j = duplicates.push( i );
1459 }
1460 }
1461 while ( j-- ) {
1462 results.splice( duplicates[ j ], 1 );
1463 }
1464 }
1465
1466 // Clear input after sorting to release objects
1467 // See https://github.com/jquery/sizzle/pull/225
1468 sortInput = null;
1469
1470 return results;
1471};
1472
1473/**
1474 * Utility function for retrieving the text value of an array of DOM nodes
1475 * @param {Array|Element} elem
1476 */
1477getText = Sizzle.getText = function( elem ) {
1478 var node,
1479 ret = "",
1480 i = 0,
1481 nodeType = elem.nodeType;
1482
1483 if ( !nodeType ) {
1484 // If no nodeType, this is expected to be an array
1485 while ( (node = elem[i++]) ) {
1486 // Do not traverse comment nodes
1487 ret += getText( node );
1488 }
1489 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1490 // Use textContent for elements
1491 // innerText usage removed for consistency of new lines (jQuery #11153)
1492 if ( typeof elem.textContent === "string" ) {
1493 return elem.textContent;
1494 } else {
1495 // Traverse its children
1496 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1497 ret += getText( elem );
1498 }
1499 }
1500 } else if ( nodeType === 3 || nodeType === 4 ) {
1501 return elem.nodeValue;
1502 }
1503 // Do not include comment or processing instruction nodes
1504
1505 return ret;
1506};
1507
1508Expr = Sizzle.selectors = {
1509
1510 // Can be adjusted by the user
1511 cacheLength: 50,
1512
1513 createPseudo: markFunction,
1514
1515 match: matchExpr,
1516
1517 attrHandle: {},
1518
1519 find: {},
1520
1521 relative: {
1522 ">": { dir: "parentNode", first: true },
1523 " ": { dir: "parentNode" },
1524 "+": { dir: "previousSibling", first: true },
1525 "~": { dir: "previousSibling" }
1526 },
1527
1528 preFilter: {
1529 "ATTR": function( match ) {
1530 match[1] = match[1].replace( runescape, funescape );
1531
1532 // Move the given value to match[3] whether quoted or unquoted
1533 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1534
1535 if ( match[2] === "~=" ) {
1536 match[3] = " " + match[3] + " ";
1537 }
1538
1539 return match.slice( 0, 4 );
1540 },
1541
1542 "CHILD": function( match ) {
1543 /* matches from matchExpr["CHILD"]
1544 1 type (only|nth|...)
1545 2 what (child|of-type)
1546 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1547 4 xn-component of xn+y argument ([+-]?\d*n|)
1548 5 sign of xn-component
1549 6 x of xn-component
1550 7 sign of y-component
1551 8 y of y-component
1552 */
1553 match[1] = match[1].toLowerCase();
1554
1555 if ( match[1].slice( 0, 3 ) === "nth" ) {
1556 // nth-* requires argument
1557 if ( !match[3] ) {
1558 Sizzle.error( match[0] );
1559 }
1560
1561 // numeric x and y parameters for Expr.filter.CHILD
1562 // remember that false/true cast respectively to 0/1
1563 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1564 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1565
1566 // other types prohibit arguments
1567 } else if ( match[3] ) {
1568 Sizzle.error( match[0] );
1569 }
1570
1571 return match;
1572 },
1573
1574 "PSEUDO": function( match ) {
1575 var excess,
1576 unquoted = !match[6] && match[2];
1577
1578 if ( matchExpr["CHILD"].test( match[0] ) ) {
1579 return null;
1580 }
1581
1582 // Accept quoted arguments as-is
1583 if ( match[3] ) {
1584 match[2] = match[4] || match[5] || "";
1585
1586 // Strip excess characters from unquoted arguments
1587 } else if ( unquoted && rpseudo.test( unquoted ) &&
1588 // Get excess from tokenize (recursively)
1589 (excess = tokenize( unquoted, true )) &&
1590 // advance to the next closing parenthesis
1591 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1592
1593 // excess is a negative index
1594 match[0] = match[0].slice( 0, excess );
1595 match[2] = unquoted.slice( 0, excess );
1596 }
1597
1598 // Return only captures needed by the pseudo filter method (type and argument)
1599 return match.slice( 0, 3 );
1600 }
1601 },
1602
1603 filter: {
1604
1605 "TAG": function( nodeNameSelector ) {
1606 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1607 return nodeNameSelector === "*" ?
1608 function() { return true; } :
1609 function( elem ) {
1610 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1611 };
1612 },
1613
1614 "CLASS": function( className ) {
1615 var pattern = classCache[ className + " " ];
1616
1617 return pattern ||
1618 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1619 classCache( className, function( elem ) {
1620 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1621 });
1622 },
1623
1624 "ATTR": function( name, operator, check ) {
1625 return function( elem ) {
1626 var result = Sizzle.attr( elem, name );
1627
1628 if ( result == null ) {
1629 return operator === "!=";
1630 }
1631 if ( !operator ) {
1632 return true;
1633 }
1634
1635 result += "";
1636
1637 return operator === "=" ? result === check :
1638 operator === "!=" ? result !== check :
1639 operator === "^=" ? check && result.indexOf( check ) === 0 :
1640 operator === "*=" ? check && result.indexOf( check ) > -1 :
1641 operator === "$=" ? check && result.slice( -check.length ) === check :
1642 operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1643 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1644 false;
1645 };
1646 },
1647
1648 "CHILD": function( type, what, argument, first, last ) {
1649 var simple = type.slice( 0, 3 ) !== "nth",
1650 forward = type.slice( -4 ) !== "last",
1651 ofType = what === "of-type";
1652
1653 return first === 1 && last === 0 ?
1654
1655 // Shortcut for :nth-*(n)
1656 function( elem ) {
1657 return !!elem.parentNode;
1658 } :
1659
1660 function( elem, context, xml ) {
1661 var cache, outerCache, node, diff, nodeIndex, start,
1662 dir = simple !== forward ? "nextSibling" : "previousSibling",
1663 parent = elem.parentNode,
1664 name = ofType && elem.nodeName.toLowerCase(),
1665 useCache = !xml && !ofType;
1666
1667 if ( parent ) {
1668
1669 // :(first|last|only)-(child|of-type)
1670 if ( simple ) {
1671 while ( dir ) {
1672 node = elem;
1673 while ( (node = node[ dir ]) ) {
1674 if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1675 return false;
1676 }
1677 }
1678 // Reverse direction for :only-* (if we haven't yet done so)
1679 start = dir = type === "only" && !start && "nextSibling";
1680 }
1681 return true;
1682 }
1683
1684 start = [ forward ? parent.firstChild : parent.lastChild ];
1685
1686 // non-xml :nth-child(...) stores cache data on `parent`
1687 if ( forward && useCache ) {
1688 // Seek `elem` from a previously-cached index
1689 outerCache = parent[ expando ] || (parent[ expando ] = {});
1690 cache = outerCache[ type ] || [];
1691 nodeIndex = cache[0] === dirruns && cache[1];
1692 diff = cache[0] === dirruns && cache[2];
1693 node = nodeIndex && parent.childNodes[ nodeIndex ];
1694
1695 while ( (node = ++nodeIndex && node && node[ dir ] ||
1696
1697 // Fallback to seeking `elem` from the start
1698 (diff = nodeIndex = 0) || start.pop()) ) {
1699
1700 // When found, cache indexes on `parent` and break
1701 if ( node.nodeType === 1 && ++diff && node === elem ) {
1702 outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1703 break;
1704 }
1705 }
1706
1707 // Use previously-cached element index if available
1708 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1709 diff = cache[1];
1710
1711 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1712 } else {
1713 // Use the same loop as above to seek `elem` from the start
1714 while ( (node = ++nodeIndex && node && node[ dir ] ||
1715 (diff = nodeIndex = 0) || start.pop()) ) {
1716
1717 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1718 // Cache the index of each encountered element
1719 if ( useCache ) {
1720 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1721 }
1722
1723 if ( node === elem ) {
1724 break;
1725 }
1726 }
1727 }
1728 }
1729
1730 // Incorporate the offset, then check against cycle size
1731 diff -= last;
1732 return diff === first || ( diff % first === 0 && diff / first >= 0 );
1733 }
1734 };
1735 },
1736
1737 "PSEUDO": function( pseudo, argument ) {
1738 // pseudo-class names are case-insensitive
1739 // http://www.w3.org/TR/selectors/#pseudo-classes
1740 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1741 // Remember that setFilters inherits from pseudos
1742 var args,
1743 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1744 Sizzle.error( "unsupported pseudo: " + pseudo );
1745
1746 // The user may use createPseudo to indicate that
1747 // arguments are needed to create the filter function
1748 // just as Sizzle does
1749 if ( fn[ expando ] ) {
1750 return fn( argument );
1751 }
1752
1753 // But maintain support for old signatures
1754 if ( fn.length > 1 ) {
1755 args = [ pseudo, pseudo, "", argument ];
1756 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1757 markFunction(function( seed, matches ) {
1758 var idx,
1759 matched = fn( seed, argument ),
1760 i = matched.length;
1761 while ( i-- ) {
1762 idx = indexOf.call( seed, matched[i] );
1763 seed[ idx ] = !( matches[ idx ] = matched[i] );
1764 }
1765 }) :
1766 function( elem ) {
1767 return fn( elem, 0, args );
1768 };
1769 }
1770
1771 return fn;
1772 }
1773 },
1774
1775 pseudos: {
1776 // Potentially complex pseudos
1777 "not": markFunction(function( selector ) {
1778 // Trim the selector passed to compile
1779 // to avoid treating leading and trailing
1780 // spaces as combinators
1781 var input = [],
1782 results = [],
1783 matcher = compile( selector.replace( rtrim, "$1" ) );
1784
1785 return matcher[ expando ] ?
1786 markFunction(function( seed, matches, context, xml ) {
1787 var elem,
1788 unmatched = matcher( seed, null, xml, [] ),
1789 i = seed.length;
1790
1791 // Match elements unmatched by `matcher`
1792 while ( i-- ) {
1793 if ( (elem = unmatched[i]) ) {
1794 seed[i] = !(matches[i] = elem);
1795 }
1796 }
1797 }) :
1798 function( elem, context, xml ) {
1799 input[0] = elem;
1800 matcher( input, null, xml, results );
1801 return !results.pop();
1802 };
1803 }),
1804
1805 "has": markFunction(function( selector ) {
1806 return function( elem ) {
1807 return Sizzle( selector, elem ).length > 0;
1808 };
1809 }),
1810
1811 "contains": markFunction(function( text ) {
1812 return function( elem ) {
1813 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1814 };
1815 }),
1816
1817 // "Whether an element is represented by a :lang() selector
1818 // is based solely on the element's language value
1819 // being equal to the identifier C,
1820 // or beginning with the identifier C immediately followed by "-".
1821 // The matching of C against the element's language value is performed case-insensitively.
1822 // The identifier C does not have to be a valid language name."
1823 // http://www.w3.org/TR/selectors/#lang-pseudo
1824 "lang": markFunction( function( lang ) {
1825 // lang value must be a valid identifier
1826 if ( !ridentifier.test(lang || "") ) {
1827 Sizzle.error( "unsupported lang: " + lang );
1828 }
1829 lang = lang.replace( runescape, funescape ).toLowerCase();
1830 return function( elem ) {
1831 var elemLang;
1832 do {
1833 if ( (elemLang = documentIsHTML ?
1834 elem.lang :
1835 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1836
1837 elemLang = elemLang.toLowerCase();
1838 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1839 }
1840 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1841 return false;
1842 };
1843 }),
1844
1845 // Miscellaneous
1846 "target": function( elem ) {
1847 var hash = window.location && window.location.hash;
1848 return hash && hash.slice( 1 ) === elem.id;
1849 },
1850
1851 "root": function( elem ) {
1852 return elem === docElem;
1853 },
1854
1855 "focus": function( elem ) {
1856 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1857 },
1858
1859 // Boolean properties
1860 "enabled": function( elem ) {
1861 return elem.disabled === false;
1862 },
1863
1864 "disabled": function( elem ) {
1865 return elem.disabled === true;
1866 },
1867
1868 "checked": function( elem ) {
1869 // In CSS3, :checked should return both checked and selected elements
1870 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1871 var nodeName = elem.nodeName.toLowerCase();
1872 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1873 },
1874
1875 "selected": function( elem ) {
1876 // Accessing this property makes selected-by-default
1877 // options in Safari work properly
1878 if ( elem.parentNode ) {
1879 elem.parentNode.selectedIndex;
1880 }
1881
1882 return elem.selected === true;
1883 },
1884
1885 // Contents
1886 "empty": function( elem ) {
1887 // http://www.w3.org/TR/selectors/#empty-pseudo
1888 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1889 // but not by others (comment: 8; processing instruction: 7; etc.)
1890 // nodeType < 6 works because attributes (2) do not appear as children
1891 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1892 if ( elem.nodeType < 6 ) {
1893 return false;
1894 }
1895 }
1896 return true;
1897 },
1898
1899 "parent": function( elem ) {
1900 return !Expr.pseudos["empty"]( elem );
1901 },
1902
1903 // Element/input types
1904 "header": function( elem ) {
1905 return rheader.test( elem.nodeName );
1906 },
1907
1908 "input": function( elem ) {
1909 return rinputs.test( elem.nodeName );
1910 },
1911
1912 "button": function( elem ) {
1913 var name = elem.nodeName.toLowerCase();
1914 return name === "input" && elem.type === "button" || name === "button";
1915 },
1916
1917 "text": function( elem ) {
1918 var attr;
1919 return elem.nodeName.toLowerCase() === "input" &&
1920 elem.type === "text" &&
1921
1922 // Support: IE<8
1923 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1924 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1925 },
1926
1927 // Position-in-collection
1928 "first": createPositionalPseudo(function() {
1929 return [ 0 ];
1930 }),
1931
1932 "last": createPositionalPseudo(function( matchIndexes, length ) {
1933 return [ length - 1 ];
1934 }),
1935
1936 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1937 return [ argument < 0 ? argument + length : argument ];
1938 }),
1939
1940 "even": createPositionalPseudo(function( matchIndexes, length ) {
1941 var i = 0;
1942 for ( ; i < length; i += 2 ) {
1943 matchIndexes.push( i );
1944 }
1945 return matchIndexes;
1946 }),
1947
1948 "odd": createPositionalPseudo(function( matchIndexes, length ) {
1949 var i = 1;
1950 for ( ; i < length; i += 2 ) {
1951 matchIndexes.push( i );
1952 }
1953 return matchIndexes;
1954 }),
1955
1956 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1957 var i = argument < 0 ? argument + length : argument;
1958 for ( ; --i >= 0; ) {
1959 matchIndexes.push( i );
1960 }
1961 return matchIndexes;
1962 }),
1963
1964 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1965 var i = argument < 0 ? argument + length : argument;
1966 for ( ; ++i < length; ) {
1967 matchIndexes.push( i );
1968 }
1969 return matchIndexes;
1970 })
1971 }
1972};
1973
1974Expr.pseudos["nth"] = Expr.pseudos["eq"];
1975
1976// Add button/input type pseudos
1977for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
1978 Expr.pseudos[ i ] = createInputPseudo( i );
1979}
1980for ( i in { submit: true, reset: true } ) {
1981 Expr.pseudos[ i ] = createButtonPseudo( i );
1982}
1983
1984// Easy API for creating new setFilters
1985function setFilters() {}
1986setFilters.prototype = Expr.filters = Expr.pseudos;
1987Expr.setFilters = new setFilters();
1988
1989tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
1990 var matched, match, tokens, type,
1991 soFar, groups, preFilters,
1992 cached = tokenCache[ selector + " " ];
1993
1994 if ( cached ) {
1995 return parseOnly ? 0 : cached.slice( 0 );
1996 }
1997
1998 soFar = selector;
1999 groups = [];
2000 preFilters = Expr.preFilter;
2001
2002 while ( soFar ) {
2003
2004 // Comma and first run
2005 if ( !matched || (match = rcomma.exec( soFar )) ) {
2006 if ( match ) {
2007 // Don't consume trailing commas as valid
2008 soFar = soFar.slice( match[0].length ) || soFar;
2009 }
2010 groups.push( (tokens = []) );
2011 }
2012
2013 matched = false;
2014
2015 // Combinators
2016 if ( (match = rcombinators.exec( soFar )) ) {
2017 matched = match.shift();
2018 tokens.push({
2019 value: matched,
2020 // Cast descendant combinators to space
2021 type: match[0].replace( rtrim, " " )
2022 });
2023 soFar = soFar.slice( matched.length );
2024 }
2025
2026 // Filters
2027 for ( type in Expr.filter ) {
2028 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2029 (match = preFilters[ type ]( match ))) ) {
2030 matched = match.shift();
2031 tokens.push({
2032 value: matched,
2033 type: type,
2034 matches: match
2035 });
2036 soFar = soFar.slice( matched.length );
2037 }
2038 }
2039
2040 if ( !matched ) {
2041 break;
2042 }
2043 }
2044
2045 // Return the length of the invalid excess
2046 // if we're just parsing
2047 // Otherwise, throw an error or return tokens
2048 return parseOnly ?
2049 soFar.length :
2050 soFar ?
2051 Sizzle.error( selector ) :
2052 // Cache the tokens
2053 tokenCache( selector, groups ).slice( 0 );
2054};
2055
2056function toSelector( tokens ) {
2057 var i = 0,
2058 len = tokens.length,
2059 selector = "";
2060 for ( ; i < len; i++ ) {
2061 selector += tokens[i].value;
2062 }
2063 return selector;
2064}
2065
2066function addCombinator( matcher, combinator, base ) {
2067 var dir = combinator.dir,
2068 checkNonElements = base && dir === "parentNode",
2069 doneName = done++;
2070
2071 return combinator.first ?
2072 // Check against closest ancestor/preceding element
2073 function( elem, context, xml ) {
2074 while ( (elem = elem[ dir ]) ) {
2075 if ( elem.nodeType === 1 || checkNonElements ) {
2076 return matcher( elem, context, xml );
2077 }
2078 }
2079 } :
2080
2081 // Check against all ancestor/preceding elements
2082 function( elem, context, xml ) {
2083 var oldCache, outerCache,
2084 newCache = [ dirruns, doneName ];
2085
2086 // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2087 if ( xml ) {
2088 while ( (elem = elem[ dir ]) ) {
2089 if ( elem.nodeType === 1 || checkNonElements ) {
2090 if ( matcher( elem, context, xml ) ) {
2091 return true;
2092 }
2093 }
2094 }
2095 } else {
2096 while ( (elem = elem[ dir ]) ) {
2097 if ( elem.nodeType === 1 || checkNonElements ) {
2098 outerCache = elem[ expando ] || (elem[ expando ] = {});
2099 if ( (oldCache = outerCache[ dir ]) &&
2100 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2101
2102 // Assign to newCache so results back-propagate to previous elements
2103 return (newCache[ 2 ] = oldCache[ 2 ]);
2104 } else {
2105 // Reuse newcache so results back-propagate to previous elements
2106 outerCache[ dir ] = newCache;
2107
2108 // A match means we're done; a fail means we have to keep checking
2109 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2110 return true;
2111 }
2112 }
2113 }
2114 }
2115 }
2116 };
2117}
2118
2119function elementMatcher( matchers ) {
2120 return matchers.length > 1 ?
2121 function( elem, context, xml ) {
2122 var i = matchers.length;
2123 while ( i-- ) {
2124 if ( !matchers[i]( elem, context, xml ) ) {
2125 return false;
2126 }
2127 }
2128 return true;
2129 } :
2130 matchers[0];
2131}
2132
2133function multipleContexts( selector, contexts, results ) {
2134 var i = 0,
2135 len = contexts.length;
2136 for ( ; i < len; i++ ) {
2137 Sizzle( selector, contexts[i], results );
2138 }
2139 return results;
2140}
2141
2142function condense( unmatched, map, filter, context, xml ) {
2143 var elem,
2144 newUnmatched = [],
2145 i = 0,
2146 len = unmatched.length,
2147 mapped = map != null;
2148
2149 for ( ; i < len; i++ ) {
2150 if ( (elem = unmatched[i]) ) {
2151 if ( !filter || filter( elem, context, xml ) ) {
2152 newUnmatched.push( elem );
2153 if ( mapped ) {
2154 map.push( i );
2155 }
2156 }
2157 }
2158 }
2159
2160 return newUnmatched;
2161}
2162
2163function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2164 if ( postFilter && !postFilter[ expando ] ) {
2165 postFilter = setMatcher( postFilter );
2166 }
2167 if ( postFinder && !postFinder[ expando ] ) {
2168 postFinder = setMatcher( postFinder, postSelector );
2169 }
2170 return markFunction(function( seed, results, context, xml ) {
2171 var temp, i, elem,
2172 preMap = [],
2173 postMap = [],
2174 preexisting = results.length,
2175
2176 // Get initial elements from seed or context
2177 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2178
2179 // Prefilter to get matcher input, preserving a map for seed-results synchronization
2180 matcherIn = preFilter && ( seed || !selector ) ?
2181 condense( elems, preMap, preFilter, context, xml ) :
2182 elems,
2183
2184 matcherOut = matcher ?
2185 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2186 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2187
2188 // ...intermediate processing is necessary
2189 [] :
2190
2191 // ...otherwise use results directly
2192 results :
2193 matcherIn;
2194
2195 // Find primary matches
2196 if ( matcher ) {
2197 matcher( matcherIn, matcherOut, context, xml );
2198 }
2199
2200 // Apply postFilter
2201 if ( postFilter ) {
2202 temp = condense( matcherOut, postMap );
2203 postFilter( temp, [], context, xml );
2204
2205 // Un-match failing elements by moving them back to matcherIn
2206 i = temp.length;
2207 while ( i-- ) {
2208 if ( (elem = temp[i]) ) {
2209 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2210 }
2211 }
2212 }
2213
2214 if ( seed ) {
2215 if ( postFinder || preFilter ) {
2216 if ( postFinder ) {
2217 // Get the final matcherOut by condensing this intermediate into postFinder contexts
2218 temp = [];
2219 i = matcherOut.length;
2220 while ( i-- ) {
2221 if ( (elem = matcherOut[i]) ) {
2222 // Restore matcherIn since elem is not yet a final match
2223 temp.push( (matcherIn[i] = elem) );
2224 }
2225 }
2226 postFinder( null, (matcherOut = []), temp, xml );
2227 }
2228
2229 // Move matched elements from seed to results to keep them synchronized
2230 i = matcherOut.length;
2231 while ( i-- ) {
2232 if ( (elem = matcherOut[i]) &&
2233 (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
2234
2235 seed[temp] = !(results[temp] = elem);
2236 }
2237 }
2238 }
2239
2240 // Add elements to results, through postFinder if defined
2241 } else {
2242 matcherOut = condense(
2243 matcherOut === results ?
2244 matcherOut.splice( preexisting, matcherOut.length ) :
2245 matcherOut
2246 );
2247 if ( postFinder ) {
2248 postFinder( null, results, matcherOut, xml );
2249 } else {
2250 push.apply( results, matcherOut );
2251 }
2252 }
2253 });
2254}
2255
2256function matcherFromTokens( tokens ) {
2257 var checkContext, matcher, j,
2258 len = tokens.length,
2259 leadingRelative = Expr.relative[ tokens[0].type ],
2260 implicitRelative = leadingRelative || Expr.relative[" "],
2261 i = leadingRelative ? 1 : 0,
2262
2263 // The foundational matcher ensures that elements are reachable from top-level context(s)
2264 matchContext = addCombinator( function( elem ) {
2265 return elem === checkContext;
2266 }, implicitRelative, true ),
2267 matchAnyContext = addCombinator( function( elem ) {
2268 return indexOf.call( checkContext, elem ) > -1;
2269 }, implicitRelative, true ),
2270 matchers = [ function( elem, context, xml ) {
2271 return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2272 (checkContext = context).nodeType ?
2273 matchContext( elem, context, xml ) :
2274 matchAnyContext( elem, context, xml ) );
2275 } ];
2276
2277 for ( ; i < len; i++ ) {
2278 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2279 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2280 } else {
2281 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2282
2283 // Return special upon seeing a positional matcher
2284 if ( matcher[ expando ] ) {
2285 // Find the next relative operator (if any) for proper handling
2286 j = ++i;
2287 for ( ; j < len; j++ ) {
2288 if ( Expr.relative[ tokens[j].type ] ) {
2289 break;
2290 }
2291 }
2292 return setMatcher(
2293 i > 1 && elementMatcher( matchers ),
2294 i > 1 && toSelector(
2295 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2296 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2297 ).replace( rtrim, "$1" ),
2298 matcher,
2299 i < j && matcherFromTokens( tokens.slice( i, j ) ),
2300 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2301 j < len && toSelector( tokens )
2302 );
2303 }
2304 matchers.push( matcher );
2305 }
2306 }
2307
2308 return elementMatcher( matchers );
2309}
2310
2311function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2312 var bySet = setMatchers.length > 0,
2313 byElement = elementMatchers.length > 0,
2314 superMatcher = function( seed, context, xml, results, outermost ) {
2315 var elem, j, matcher,
2316 matchedCount = 0,
2317 i = "0",
2318 unmatched = seed && [],
2319 setMatched = [],
2320 contextBackup = outermostContext,
2321 // We must always have either seed elements or outermost context
2322 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2323 // Use integer dirruns iff this is the outermost matcher
2324 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2325 len = elems.length;
2326
2327 if ( outermost ) {
2328 outermostContext = context !== document && context;
2329 }
2330
2331 // Add elements passing elementMatchers directly to results
2332 // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2333 // Support: IE<9, Safari
2334 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2335 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2336 if ( byElement && elem ) {
2337 j = 0;
2338 while ( (matcher = elementMatchers[j++]) ) {
2339 if ( matcher( elem, context, xml ) ) {
2340 results.push( elem );
2341 break;
2342 }
2343 }
2344 if ( outermost ) {
2345 dirruns = dirrunsUnique;
2346 }
2347 }
2348
2349 // Track unmatched elements for set filters
2350 if ( bySet ) {
2351 // They will have gone through all possible matchers
2352 if ( (elem = !matcher && elem) ) {
2353 matchedCount--;
2354 }
2355
2356 // Lengthen the array for every element, matched or not
2357 if ( seed ) {
2358 unmatched.push( elem );
2359 }
2360 }
2361 }
2362
2363 // Apply set filters to unmatched elements
2364 matchedCount += i;
2365 if ( bySet && i !== matchedCount ) {
2366 j = 0;
2367 while ( (matcher = setMatchers[j++]) ) {
2368 matcher( unmatched, setMatched, context, xml );
2369 }
2370
2371 if ( seed ) {
2372 // Reintegrate element matches to eliminate the need for sorting
2373 if ( matchedCount > 0 ) {
2374 while ( i-- ) {
2375 if ( !(unmatched[i] || setMatched[i]) ) {
2376 setMatched[i] = pop.call( results );
2377 }
2378 }
2379 }
2380
2381 // Discard index placeholder values to get only actual matches
2382 setMatched = condense( setMatched );
2383 }
2384
2385 // Add matches to results
2386 push.apply( results, setMatched );
2387
2388 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2389 if ( outermost && !seed && setMatched.length > 0 &&
2390 ( matchedCount + setMatchers.length ) > 1 ) {
2391
2392 Sizzle.uniqueSort( results );
2393 }
2394 }
2395
2396 // Override manipulation of globals by nested matchers
2397 if ( outermost ) {
2398 dirruns = dirrunsUnique;
2399 outermostContext = contextBackup;
2400 }
2401
2402 return unmatched;
2403 };
2404
2405 return bySet ?
2406 markFunction( superMatcher ) :
2407 superMatcher;
2408}
2409
2410compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2411 var i,
2412 setMatchers = [],
2413 elementMatchers = [],
2414 cached = compilerCache[ selector + " " ];
2415
2416 if ( !cached ) {
2417 // Generate a function of recursive functions that can be used to check each element
2418 if ( !match ) {
2419 match = tokenize( selector );
2420 }
2421 i = match.length;
2422 while ( i-- ) {
2423 cached = matcherFromTokens( match[i] );
2424 if ( cached[ expando ] ) {
2425 setMatchers.push( cached );
2426 } else {
2427 elementMatchers.push( cached );
2428 }
2429 }
2430
2431 // Cache the compiled function
2432 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2433
2434 // Save selector and tokenization
2435 cached.selector = selector;
2436 }
2437 return cached;
2438};
2439
2440/**
2441 * A low-level selection function that works with Sizzle's compiled
2442 * selector functions
2443 * @param {String|Function} selector A selector or a pre-compiled
2444 * selector function built with Sizzle.compile
2445 * @param {Element} context
2446 * @param {Array} [results]
2447 * @param {Array} [seed] A set of elements to match against
2448 */
2449select = Sizzle.select = function( selector, context, results, seed ) {
2450 var i, tokens, token, type, find,
2451 compiled = typeof selector === "function" && selector,
2452 match = !seed && tokenize( (selector = compiled.selector || selector) );
2453
2454 results = results || [];
2455
2456 // Try to minimize operations if there is no seed and only one group
2457 if ( match.length === 1 ) {
2458
2459 // Take a shortcut and set the context if the root selector is an ID
2460 tokens = match[0] = match[0].slice( 0 );
2461 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2462 support.getById && context.nodeType === 9 && documentIsHTML &&
2463 Expr.relative[ tokens[1].type ] ) {
2464
2465 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2466 if ( !context ) {
2467 return results;
2468
2469 // Precompiled matchers will still verify ancestry, so step up a level
2470 } else if ( compiled ) {
2471 context = context.parentNode;
2472 }
2473
2474 selector = selector.slice( tokens.shift().value.length );
2475 }
2476
2477 // Fetch a seed set for right-to-left matching
2478 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2479 while ( i-- ) {
2480 token = tokens[i];
2481
2482 // Abort if we hit a combinator
2483 if ( Expr.relative[ (type = token.type) ] ) {
2484 break;
2485 }
2486 if ( (find = Expr.find[ type ]) ) {
2487 // Search, expanding context for leading sibling combinators
2488 if ( (seed = find(
2489 token.matches[0].replace( runescape, funescape ),
2490 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2491 )) ) {
2492
2493 // If seed is empty or no tokens remain, we can return early
2494 tokens.splice( i, 1 );
2495 selector = seed.length && toSelector( tokens );
2496 if ( !selector ) {
2497 push.apply( results, seed );
2498 return results;
2499 }
2500
2501 break;
2502 }
2503 }
2504 }
2505 }
2506
2507 // Compile and execute a filtering function if one is not provided
2508 // Provide `match` to avoid retokenization if we modified the selector above
2509 ( compiled || compile( selector, match ) )(
2510 seed,
2511 context,
2512 !documentIsHTML,
2513 results,
2514 rsibling.test( selector ) && testContext( context.parentNode ) || context
2515 );
2516 return results;
2517};
2518
2519// One-time assignments
2520
2521// Sort stability
2522support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2523
2524// Support: Chrome<14
2525// Always assume duplicates if they aren't passed to the comparison function
2526support.detectDuplicates = !!hasDuplicate;
2527
2528// Initialize against the default document
2529setDocument();
2530
2531// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2532// Detached nodes confoundingly follow *each other*
2533support.sortDetached = assert(function( div1 ) {
2534 // Should return 1, but returns 4 (following)
2535 return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2536});
2537
2538// Support: IE<8
2539// Prevent attribute/property "interpolation"
2540// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2541if ( !assert(function( div ) {
2542 div.innerHTML = "<a href='#'></a>";
2543 return div.firstChild.getAttribute("href") === "#" ;
2544}) ) {
2545 addHandle( "type|href|height|width", function( elem, name, isXML ) {
2546 if ( !isXML ) {
2547 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2548 }
2549 });
2550}
2551
2552// Support: IE<9
2553// Use defaultValue in place of getAttribute("value")
2554if ( !support.attributes || !assert(function( div ) {
2555 div.innerHTML = "<input/>";
2556 div.firstChild.setAttribute( "value", "" );
2557 return div.firstChild.getAttribute( "value" ) === "";
2558}) ) {
2559 addHandle( "value", function( elem, name, isXML ) {
2560 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2561 return elem.defaultValue;
2562 }
2563 });
2564}
2565
2566// Support: IE<9
2567// Use getAttributeNode to fetch booleans when getAttribute lies
2568if ( !assert(function( div ) {
2569 return div.getAttribute("disabled") == null;
2570}) ) {
2571 addHandle( booleans, function( elem, name, isXML ) {
2572 var val;
2573 if ( !isXML ) {
2574 return elem[ name ] === true ? name.toLowerCase() :
2575 (val = elem.getAttributeNode( name )) && val.specified ?
2576 val.value :
2577 null;
2578 }
2579 });
2580}
2581
2582return Sizzle;
2583
2584})( window );
2585
2586
2587
2588jQuery.find = Sizzle;
2589jQuery.expr = Sizzle.selectors;
2590jQuery.expr[":"] = jQuery.expr.pseudos;
2591jQuery.unique = Sizzle.uniqueSort;
2592jQuery.text = Sizzle.getText;
2593jQuery.isXMLDoc = Sizzle.isXML;
2594jQuery.contains = Sizzle.contains;
2595
2596
2597
2598var rneedsContext = jQuery.expr.match.needsContext;
2599
2600var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
2601
2602
2603
2604var risSimple = /^.[^:#\[\.,]*$/;
2605
2606// Implement the identical functionality for filter and not
2607function winnow( elements, qualifier, not ) {
2608 if ( jQuery.isFunction( qualifier ) ) {
2609 return jQuery.grep( elements, function( elem, i ) {
2610 /* jshint -W018 */
2611 return !!qualifier.call( elem, i, elem ) !== not;
2612 });
2613
2614 }
2615
2616 if ( qualifier.nodeType ) {
2617 return jQuery.grep( elements, function( elem ) {
2618 return ( elem === qualifier ) !== not;
2619 });
2620
2621 }
2622
2623 if ( typeof qualifier === "string" ) {
2624 if ( risSimple.test( qualifier ) ) {
2625 return jQuery.filter( qualifier, elements, not );
2626 }
2627
2628 qualifier = jQuery.filter( qualifier, elements );
2629 }
2630
2631 return jQuery.grep( elements, function( elem ) {
2632 return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
2633 });
2634}
2635
2636jQuery.filter = function( expr, elems, not ) {
2637 var elem = elems[ 0 ];
2638
2639 if ( not ) {
2640 expr = ":not(" + expr + ")";
2641 }
2642
2643 return elems.length === 1 && elem.nodeType === 1 ?
2644 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2645 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2646 return elem.nodeType === 1;
2647 }));
2648};
2649
2650jQuery.fn.extend({
2651 find: function( selector ) {
2652 var i,
2653 len = this.length,
2654 ret = [],
2655 self = this;
2656
2657 if ( typeof selector !== "string" ) {
2658 return this.pushStack( jQuery( selector ).filter(function() {
2659 for ( i = 0; i < len; i++ ) {
2660 if ( jQuery.contains( self[ i ], this ) ) {
2661 return true;
2662 }
2663 }
2664 }) );
2665 }
2666
2667 for ( i = 0; i < len; i++ ) {
2668 jQuery.find( selector, self[ i ], ret );
2669 }
2670
2671 // Needed because $( selector, context ) becomes $( context ).find( selector )
2672 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2673 ret.selector = this.selector ? this.selector + " " + selector : selector;
2674 return ret;
2675 },
2676 filter: function( selector ) {
2677 return this.pushStack( winnow(this, selector || [], false) );
2678 },
2679 not: function( selector ) {
2680 return this.pushStack( winnow(this, selector || [], true) );
2681 },
2682 is: function( selector ) {
2683 return !!winnow(
2684 this,
2685
2686 // If this is a positional/relative selector, check membership in the returned set
2687 // so $("p:first").is("p:last") won't return true for a doc with two "p".
2688 typeof selector === "string" && rneedsContext.test( selector ) ?
2689 jQuery( selector ) :
2690 selector || [],
2691 false
2692 ).length;
2693 }
2694});
2695
2696
2697// Initialize a jQuery object
2698
2699
2700// A central reference to the root jQuery(document)
2701var rootjQuery,
2702
2703 // A simple way to check for HTML strings
2704 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2705 // Strict HTML recognition (#11290: must start with <)
2706 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2707
2708 init = jQuery.fn.init = function( selector, context ) {
2709 var match, elem;
2710
2711 // HANDLE: $(""), $(null), $(undefined), $(false)
2712 if ( !selector ) {
2713 return this;
2714 }
2715
2716 // Handle HTML strings
2717 if ( typeof selector === "string" ) {
2718 if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
2719 // Assume that strings that start and end with <> are HTML and skip the regex check
2720 match = [ null, selector, null ];
2721
2722 } else {
2723 match = rquickExpr.exec( selector );
2724 }
2725
2726 // Match html or make sure no context is specified for #id
2727 if ( match && (match[1] || !context) ) {
2728
2729 // HANDLE: $(html) -> $(array)
2730 if ( match[1] ) {
2731 context = context instanceof jQuery ? context[0] : context;
2732
2733 // scripts is true for back-compat
2734 // Intentionally let the error be thrown if parseHTML is not present
2735 jQuery.merge( this, jQuery.parseHTML(
2736 match[1],
2737 context && context.nodeType ? context.ownerDocument || context : document,
2738 true
2739 ) );
2740
2741 // HANDLE: $(html, props)
2742 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
2743 for ( match in context ) {
2744 // Properties of context are called as methods if possible
2745 if ( jQuery.isFunction( this[ match ] ) ) {
2746 this[ match ]( context[ match ] );
2747
2748 // ...and otherwise set as attributes
2749 } else {
2750 this.attr( match, context[ match ] );
2751 }
2752 }
2753 }
2754
2755 return this;
2756
2757 // HANDLE: $(#id)
2758 } else {
2759 elem = document.getElementById( match[2] );
2760
2761 // Check parentNode to catch when Blackberry 4.6 returns
2762 // nodes that are no longer in the document #6963
2763 if ( elem && elem.parentNode ) {
2764 // Inject the element directly into the jQuery object
2765 this.length = 1;
2766 this[0] = elem;
2767 }
2768
2769 this.context = document;
2770 this.selector = selector;
2771 return this;
2772 }
2773
2774 // HANDLE: $(expr, $(...))
2775 } else if ( !context || context.jquery ) {
2776 return ( context || rootjQuery ).find( selector );
2777
2778 // HANDLE: $(expr, context)
2779 // (which is just equivalent to: $(context).find(expr)
2780 } else {
2781 return this.constructor( context ).find( selector );
2782 }
2783
2784 // HANDLE: $(DOMElement)
2785 } else if ( selector.nodeType ) {
2786 this.context = this[0] = selector;
2787 this.length = 1;
2788 return this;
2789
2790 // HANDLE: $(function)
2791 // Shortcut for document ready
2792 } else if ( jQuery.isFunction( selector ) ) {
2793 return typeof rootjQuery.ready !== "undefined" ?
2794 rootjQuery.ready( selector ) :
2795 // Execute immediately if ready is not present
2796 selector( jQuery );
2797 }
2798
2799 if ( selector.selector !== undefined ) {
2800 this.selector = selector.selector;
2801 this.context = selector.context;
2802 }
2803
2804 return jQuery.makeArray( selector, this );
2805 };
2806
2807// Give the init function the jQuery prototype for later instantiation
2808init.prototype = jQuery.fn;
2809
2810// Initialize central reference
2811rootjQuery = jQuery( document );
2812
2813
2814var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2815 // methods guaranteed to produce a unique set when starting from a unique set
2816 guaranteedUnique = {
2817 children: true,
2818 contents: true,
2819 next: true,
2820 prev: true
2821 };
2822
2823jQuery.extend({
2824 dir: function( elem, dir, until ) {
2825 var matched = [],
2826 truncate = until !== undefined;
2827
2828 while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
2829 if ( elem.nodeType === 1 ) {
2830 if ( truncate && jQuery( elem ).is( until ) ) {
2831 break;
2832 }
2833 matched.push( elem );
2834 }
2835 }
2836 return matched;
2837 },
2838
2839 sibling: function( n, elem ) {
2840 var matched = [];
2841
2842 for ( ; n; n = n.nextSibling ) {
2843 if ( n.nodeType === 1 && n !== elem ) {
2844 matched.push( n );
2845 }
2846 }
2847
2848 return matched;
2849 }
2850});
2851
2852jQuery.fn.extend({
2853 has: function( target ) {
2854 var targets = jQuery( target, this ),
2855 l = targets.length;
2856
2857 return this.filter(function() {
2858 var i = 0;
2859 for ( ; i < l; i++ ) {
2860 if ( jQuery.contains( this, targets[i] ) ) {
2861 return true;
2862 }
2863 }
2864 });
2865 },
2866
2867 closest: function( selectors, context ) {
2868 var cur,
2869 i = 0,
2870 l = this.length,
2871 matched = [],
2872 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2873 jQuery( selectors, context || this.context ) :
2874 0;
2875
2876 for ( ; i < l; i++ ) {
2877 for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
2878 // Always skip document fragments
2879 if ( cur.nodeType < 11 && (pos ?
2880 pos.index(cur) > -1 :
2881
2882 // Don't pass non-elements to Sizzle
2883 cur.nodeType === 1 &&
2884 jQuery.find.matchesSelector(cur, selectors)) ) {
2885
2886 matched.push( cur );
2887 break;
2888 }
2889 }
2890 }
2891
2892 return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
2893 },
2894
2895 // Determine the position of an element within
2896 // the matched set of elements
2897 index: function( elem ) {
2898
2899 // No argument, return index in parent
2900 if ( !elem ) {
2901 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
2902 }
2903
2904 // index in selector
2905 if ( typeof elem === "string" ) {
2906 return indexOf.call( jQuery( elem ), this[ 0 ] );
2907 }
2908
2909 // Locate the position of the desired element
2910 return indexOf.call( this,
2911
2912 // If it receives a jQuery object, the first element is used
2913 elem.jquery ? elem[ 0 ] : elem
2914 );
2915 },
2916
2917 add: function( selector, context ) {
2918 return this.pushStack(
2919 jQuery.unique(
2920 jQuery.merge( this.get(), jQuery( selector, context ) )
2921 )
2922 );
2923 },
2924
2925 addBack: function( selector ) {
2926 return this.add( selector == null ?
2927 this.prevObject : this.prevObject.filter(selector)
2928 );
2929 }
2930});
2931
2932function sibling( cur, dir ) {
2933 while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
2934 return cur;
2935}
2936
2937jQuery.each({
2938 parent: function( elem ) {
2939 var parent = elem.parentNode;
2940 return parent && parent.nodeType !== 11 ? parent : null;
2941 },
2942 parents: function( elem ) {
2943 return jQuery.dir( elem, "parentNode" );
2944 },
2945 parentsUntil: function( elem, i, until ) {
2946 return jQuery.dir( elem, "parentNode", until );
2947 },
2948 next: function( elem ) {
2949 return sibling( elem, "nextSibling" );
2950 },
2951 prev: function( elem ) {
2952 return sibling( elem, "previousSibling" );
2953 },
2954 nextAll: function( elem ) {
2955 return jQuery.dir( elem, "nextSibling" );
2956 },
2957 prevAll: function( elem ) {
2958 return jQuery.dir( elem, "previousSibling" );
2959 },
2960 nextUntil: function( elem, i, until ) {
2961 return jQuery.dir( elem, "nextSibling", until );
2962 },
2963 prevUntil: function( elem, i, until ) {
2964 return jQuery.dir( elem, "previousSibling", until );
2965 },
2966 siblings: function( elem ) {
2967 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
2968 },
2969 children: function( elem ) {
2970 return jQuery.sibling( elem.firstChild );
2971 },
2972 contents: function( elem ) {
2973 return elem.contentDocument || jQuery.merge( [], elem.childNodes );
2974 }
2975}, function( name, fn ) {
2976 jQuery.fn[ name ] = function( until, selector ) {
2977 var matched = jQuery.map( this, fn, until );
2978
2979 if ( name.slice( -5 ) !== "Until" ) {
2980 selector = until;
2981 }
2982
2983 if ( selector && typeof selector === "string" ) {
2984 matched = jQuery.filter( selector, matched );
2985 }
2986
2987 if ( this.length > 1 ) {
2988 // Remove duplicates
2989 if ( !guaranteedUnique[ name ] ) {
2990 jQuery.unique( matched );
2991 }
2992
2993 // Reverse order for parents* and prev-derivatives
2994 if ( rparentsprev.test( name ) ) {
2995 matched.reverse();
2996 }
2997 }
2998
2999 return this.pushStack( matched );
3000 };
3001});
3002var rnotwhite = (/\S+/g);
3003
3004
3005
3006// String to Object options format cache
3007var optionsCache = {};
3008
3009// Convert String-formatted options into Object-formatted ones and store in cache
3010function createOptions( options ) {
3011 var object = optionsCache[ options ] = {};
3012 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3013 object[ flag ] = true;
3014 });
3015 return object;
3016}
3017
3018/*
3019 * Create a callback list using the following parameters:
3020 *
3021 * options: an optional list of space-separated options that will change how
3022 * the callback list behaves or a more traditional option object
3023 *
3024 * By default a callback list will act like an event callback list and can be
3025 * "fired" multiple times.
3026 *
3027 * Possible options:
3028 *
3029 * once: will ensure the callback list can only be fired once (like a Deferred)
3030 *
3031 * memory: will keep track of previous values and will call any callback added
3032 * after the list has been fired right away with the latest "memorized"
3033 * values (like a Deferred)
3034 *
3035 * unique: will ensure a callback can only be added once (no duplicate in the list)
3036 *
3037 * stopOnFalse: interrupt callings when a callback returns false
3038 *
3039 */
3040jQuery.Callbacks = function( options ) {
3041
3042 // Convert options from String-formatted to Object-formatted if needed
3043 // (we check in cache first)
3044 options = typeof options === "string" ?
3045 ( optionsCache[ options ] || createOptions( options ) ) :
3046 jQuery.extend( {}, options );
3047
3048 var // Last fire value (for non-forgettable lists)
3049 memory,
3050 // Flag to know if list was already fired
3051 fired,
3052 // Flag to know if list is currently firing
3053 firing,
3054 // First callback to fire (used internally by add and fireWith)
3055 firingStart,
3056 // End of the loop when firing
3057 firingLength,
3058 // Index of currently firing callback (modified by remove if needed)
3059 firingIndex,
3060 // Actual callback list
3061 list = [],
3062 // Stack of fire calls for repeatable lists
3063 stack = !options.once && [],
3064 // Fire callbacks
3065 fire = function( data ) {
3066 memory = options.memory && data;
3067 fired = true;
3068 firingIndex = firingStart || 0;
3069 firingStart = 0;
3070 firingLength = list.length;
3071 firing = true;
3072 for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3073 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3074 memory = false; // To prevent further calls using add
3075 break;
3076 }
3077 }
3078 firing = false;
3079 if ( list ) {
3080 if ( stack ) {
3081 if ( stack.length ) {
3082 fire( stack.shift() );
3083 }
3084 } else if ( memory ) {
3085 list = [];
3086 } else {
3087 self.disable();
3088 }
3089 }
3090 },
3091 // Actual Callbacks object
3092 self = {
3093 // Add a callback or a collection of callbacks to the list
3094 add: function() {
3095 if ( list ) {
3096 // First, we save the current length
3097 var start = list.length;
3098 (function add( args ) {
3099 jQuery.each( args, function( _, arg ) {
3100 var type = jQuery.type( arg );
3101 if ( type === "function" ) {
3102 if ( !options.unique || !self.has( arg ) ) {
3103 list.push( arg );
3104 }
3105 } else if ( arg && arg.length && type !== "string" ) {
3106 // Inspect recursively
3107 add( arg );
3108 }
3109 });
3110 })( arguments );
3111 // Do we need to add the callbacks to the
3112 // current firing batch?
3113 if ( firing ) {
3114 firingLength = list.length;
3115 // With memory, if we're not firing then
3116 // we should call right away
3117 } else if ( memory ) {
3118 firingStart = start;
3119 fire( memory );
3120 }
3121 }
3122 return this;
3123 },
3124 // Remove a callback from the list
3125 remove: function() {
3126 if ( list ) {
3127 jQuery.each( arguments, function( _, arg ) {
3128 var index;
3129 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3130 list.splice( index, 1 );
3131 // Handle firing indexes
3132 if ( firing ) {
3133 if ( index <= firingLength ) {
3134 firingLength--;
3135 }
3136 if ( index <= firingIndex ) {
3137 firingIndex--;
3138 }
3139 }
3140 }
3141 });
3142 }
3143 return this;
3144 },
3145 // Check if a given callback is in the list.
3146 // If no argument is given, return whether or not list has callbacks attached.
3147 has: function( fn ) {
3148 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3149 },
3150 // Remove all callbacks from the list
3151 empty: function() {
3152 list = [];
3153 firingLength = 0;
3154 return this;
3155 },
3156 // Have the list do nothing anymore
3157 disable: function() {
3158 list = stack = memory = undefined;
3159 return this;
3160 },
3161 // Is it disabled?
3162 disabled: function() {
3163 return !list;
3164 },
3165 // Lock the list in its current state
3166 lock: function() {
3167 stack = undefined;
3168 if ( !memory ) {
3169 self.disable();
3170 }
3171 return this;
3172 },
3173 // Is it locked?
3174 locked: function() {
3175 return !stack;
3176 },
3177 // Call all callbacks with the given context and arguments
3178 fireWith: function( context, args ) {
3179 if ( list && ( !fired || stack ) ) {
3180 args = args || [];
3181 args = [ context, args.slice ? args.slice() : args ];
3182 if ( firing ) {
3183 stack.push( args );
3184 } else {
3185 fire( args );
3186 }
3187 }
3188 return this;
3189 },
3190 // Call all the callbacks with the given arguments
3191 fire: function() {
3192 self.fireWith( this, arguments );
3193 return this;
3194 },
3195 // To know if the callbacks have already been called at least once
3196 fired: function() {
3197 return !!fired;
3198 }
3199 };
3200
3201 return self;
3202};
3203
3204
3205jQuery.extend({
3206
3207 Deferred: function( func ) {
3208 var tuples = [
3209 // action, add listener, listener list, final state
3210 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3211 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3212 [ "notify", "progress", jQuery.Callbacks("memory") ]
3213 ],
3214 state = "pending",
3215 promise = {
3216 state: function() {
3217 return state;
3218 },
3219 always: function() {
3220 deferred.done( arguments ).fail( arguments );
3221 return this;
3222 },
3223 then: function( /* fnDone, fnFail, fnProgress */ ) {
3224 var fns = arguments;
3225 return jQuery.Deferred(function( newDefer ) {
3226 jQuery.each( tuples, function( i, tuple ) {
3227 var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3228 // deferred[ done | fail | progress ] for forwarding actions to newDefer
3229 deferred[ tuple[1] ](function() {
3230 var returned = fn && fn.apply( this, arguments );
3231 if ( returned && jQuery.isFunction( returned.promise ) ) {
3232 returned.promise()
3233 .done( newDefer.resolve )
3234 .fail( newDefer.reject )
3235 .progress( newDefer.notify );
3236 } else {
3237 newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3238 }
3239 });
3240 });
3241 fns = null;
3242 }).promise();
3243 },
3244 // Get a promise for this deferred
3245 // If obj is provided, the promise aspect is added to the object
3246 promise: function( obj ) {
3247 return obj != null ? jQuery.extend( obj, promise ) : promise;
3248 }
3249 },
3250 deferred = {};
3251
3252 // Keep pipe for back-compat
3253 promise.pipe = promise.then;
3254
3255 // Add list-specific methods
3256 jQuery.each( tuples, function( i, tuple ) {
3257 var list = tuple[ 2 ],
3258 stateString = tuple[ 3 ];
3259
3260 // promise[ done | fail | progress ] = list.add
3261 promise[ tuple[1] ] = list.add;
3262
3263 // Handle state
3264 if ( stateString ) {
3265 list.add(function() {
3266 // state = [ resolved | rejected ]
3267 state = stateString;
3268
3269 // [ reject_list | resolve_list ].disable; progress_list.lock
3270 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3271 }
3272
3273 // deferred[ resolve | reject | notify ]
3274 deferred[ tuple[0] ] = function() {
3275 deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3276 return this;
3277 };
3278 deferred[ tuple[0] + "With" ] = list.fireWith;
3279 });
3280
3281 // Make the deferred a promise
3282 promise.promise( deferred );
3283
3284 // Call given func if any
3285 if ( func ) {
3286 func.call( deferred, deferred );
3287 }
3288
3289 // All done!
3290 return deferred;
3291 },
3292
3293 // Deferred helper
3294 when: function( subordinate /* , ..., subordinateN */ ) {
3295 var i = 0,
3296 resolveValues = slice.call( arguments ),
3297 length = resolveValues.length,
3298
3299 // the count of uncompleted subordinates
3300 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3301
3302 // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3303 deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3304
3305 // Update function for both resolve and progress values
3306 updateFunc = function( i, contexts, values ) {
3307 return function( value ) {
3308 contexts[ i ] = this;
3309 values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3310 if ( values === progressValues ) {
3311 deferred.notifyWith( contexts, values );
3312 } else if ( !( --remaining ) ) {
3313 deferred.resolveWith( contexts, values );
3314 }
3315 };
3316 },
3317
3318 progressValues, progressContexts, resolveContexts;
3319
3320 // add listeners to Deferred subordinates; treat others as resolved
3321 if ( length > 1 ) {
3322 progressValues = new Array( length );
3323 progressContexts = new Array( length );
3324 resolveContexts = new Array( length );
3325 for ( ; i < length; i++ ) {
3326 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3327 resolveValues[ i ].promise()
3328 .done( updateFunc( i, resolveContexts, resolveValues ) )
3329 .fail( deferred.reject )
3330 .progress( updateFunc( i, progressContexts, progressValues ) );
3331 } else {
3332 --remaining;
3333 }
3334 }
3335 }
3336
3337 // if we're not waiting on anything, resolve the master
3338 if ( !remaining ) {
3339 deferred.resolveWith( resolveContexts, resolveValues );
3340 }
3341
3342 return deferred.promise();
3343 }
3344});
3345
3346
3347// The deferred used on DOM ready
3348var readyList;
3349
3350jQuery.fn.ready = function( fn ) {
3351 // Add the callback
3352 jQuery.ready.promise().done( fn );
3353
3354 return this;
3355};
3356
3357jQuery.extend({
3358 // Is the DOM ready to be used? Set to true once it occurs.
3359 isReady: false,
3360
3361 // A counter to track how many items to wait for before
3362 // the ready event fires. See #6781
3363 readyWait: 1,
3364
3365 // Hold (or release) the ready event
3366 holdReady: function( hold ) {
3367 if ( hold ) {
3368 jQuery.readyWait++;
3369 } else {
3370 jQuery.ready( true );
3371 }
3372 },
3373
3374 // Handle when the DOM is ready
3375 ready: function( wait ) {
3376
3377 // Abort if there are pending holds or we're already ready
3378 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3379 return;
3380 }
3381
3382 // Remember that the DOM is ready
3383 jQuery.isReady = true;
3384
3385 // If a normal DOM Ready event fired, decrement, and wait if need be
3386 if ( wait !== true && --jQuery.readyWait > 0 ) {
3387 return;
3388 }
3389
3390 // If there are functions bound, to execute
3391 readyList.resolveWith( document, [ jQuery ] );
3392
3393 // Trigger any bound ready events
3394 if ( jQuery.fn.triggerHandler ) {
3395 jQuery( document ).triggerHandler( "ready" );
3396 jQuery( document ).off( "ready" );
3397 }
3398 }
3399});
3400
3401/**
3402 * The ready event handler and self cleanup method
3403 */
3404function completed() {
3405 document.removeEventListener( "DOMContentLoaded", completed, false );
3406 window.removeEventListener( "load", completed, false );
3407 jQuery.ready();
3408}
3409
3410jQuery.ready.promise = function( obj ) {
3411 if ( !readyList ) {
3412
3413 readyList = jQuery.Deferred();
3414
3415 // Catch cases where $(document).ready() is called after the browser event has already occurred.
3416 // we once tried to use readyState "interactive" here, but it caused issues like the one
3417 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
3418 if ( document.readyState === "complete" ) {
3419 // Handle it asynchronously to allow scripts the opportunity to delay ready
3420 setTimeout( jQuery.ready );
3421
3422 } else {
3423
3424 // Use the handy event callback
3425 document.addEventListener( "DOMContentLoaded", completed, false );
3426
3427 // A fallback to window.onload, that will always work
3428 window.addEventListener( "load", completed, false );
3429 }
3430 }
3431 return readyList.promise( obj );
3432};
3433
3434// Kick off the DOM ready check even if the user does not
3435jQuery.ready.promise();
3436
3437
3438
3439
3440// Multifunctional method to get and set values of a collection
3441// The value/s can optionally be executed if it's a function
3442var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3443 var i = 0,
3444 len = elems.length,
3445 bulk = key == null;
3446
3447 // Sets many values
3448 if ( jQuery.type( key ) === "object" ) {
3449 chainable = true;
3450 for ( i in key ) {
3451 jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
3452 }
3453
3454 // Sets one value
3455 } else if ( value !== undefined ) {
3456 chainable = true;
3457
3458 if ( !jQuery.isFunction( value ) ) {
3459 raw = true;
3460 }
3461
3462 if ( bulk ) {
3463 // Bulk operations run against the entire set
3464 if ( raw ) {
3465 fn.call( elems, value );
3466 fn = null;
3467
3468 // ...except when executing function values
3469 } else {
3470 bulk = fn;
3471 fn = function( elem, key, value ) {
3472 return bulk.call( jQuery( elem ), value );
3473 };
3474 }
3475 }
3476
3477 if ( fn ) {
3478 for ( ; i < len; i++ ) {
3479 fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
3480 }
3481 }
3482 }
3483
3484 return chainable ?
3485 elems :
3486
3487 // Gets
3488 bulk ?
3489 fn.call( elems ) :
3490 len ? fn( elems[0], key ) : emptyGet;
3491};
3492
3493
3494/**
3495 * Determines whether an object can have data
3496 */
3497jQuery.acceptData = function( owner ) {
3498 // Accepts only:
3499 // - Node
3500 // - Node.ELEMENT_NODE
3501 // - Node.DOCUMENT_NODE
3502 // - Object
3503 // - Any
3504 /* jshint -W018 */
3505 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3506};
3507
3508
3509function Data() {
3510 // Support: Android < 4,
3511 // Old WebKit does not have Object.preventExtensions/freeze method,
3512 // return new empty object instead with no [[set]] accessor
3513 Object.defineProperty( this.cache = {}, 0, {
3514 get: function() {
3515 return {};
3516 }
3517 });
3518
3519 this.expando = jQuery.expando + Math.random();
3520}
3521
3522Data.uid = 1;
3523Data.accepts = jQuery.acceptData;
3524
3525Data.prototype = {
3526 key: function( owner ) {
3527 // We can accept data for non-element nodes in modern browsers,
3528 // but we should not, see #8335.
3529 // Always return the key for a frozen object.
3530 if ( !Data.accepts( owner ) ) {
3531 return 0;
3532 }
3533
3534 var descriptor = {},
3535 // Check if the owner object already has a cache key
3536 unlock = owner[ this.expando ];
3537
3538 // If not, create one
3539 if ( !unlock ) {
3540 unlock = Data.uid++;
3541
3542 // Secure it in a non-enumerable, non-writable property
3543 try {
3544 descriptor[ this.expando ] = { value: unlock };
3545 Object.defineProperties( owner, descriptor );
3546
3547 // Support: Android < 4
3548 // Fallback to a less secure definition
3549 } catch ( e ) {
3550 descriptor[ this.expando ] = unlock;
3551 jQuery.extend( owner, descriptor );
3552 }
3553 }
3554
3555 // Ensure the cache object
3556 if ( !this.cache[ unlock ] ) {
3557 this.cache[ unlock ] = {};
3558 }
3559
3560 return unlock;
3561 },
3562 set: function( owner, data, value ) {
3563 var prop,
3564 // There may be an unlock assigned to this node,
3565 // if there is no entry for this "owner", create one inline
3566 // and set the unlock as though an owner entry had always existed
3567 unlock = this.key( owner ),
3568 cache = this.cache[ unlock ];
3569
3570 // Handle: [ owner, key, value ] args
3571 if ( typeof data === "string" ) {
3572 cache[ data ] = value;
3573
3574 // Handle: [ owner, { properties } ] args
3575 } else {
3576 // Fresh assignments by object are shallow copied
3577 if ( jQuery.isEmptyObject( cache ) ) {
3578 jQuery.extend( this.cache[ unlock ], data );
3579 // Otherwise, copy the properties one-by-one to the cache object
3580 } else {
3581 for ( prop in data ) {
3582 cache[ prop ] = data[ prop ];
3583 }
3584 }
3585 }
3586 return cache;
3587 },
3588 get: function( owner, key ) {
3589 // Either a valid cache is found, or will be created.
3590 // New caches will be created and the unlock returned,
3591 // allowing direct access to the newly created
3592 // empty data object. A valid owner object must be provided.
3593 var cache = this.cache[ this.key( owner ) ];
3594
3595 return key === undefined ?
3596 cache : cache[ key ];
3597 },
3598 access: function( owner, key, value ) {
3599 var stored;
3600 // In cases where either:
3601 //
3602 // 1. No key was specified
3603 // 2. A string key was specified, but no value provided
3604 //
3605 // Take the "read" path and allow the get method to determine
3606 // which value to return, respectively either:
3607 //
3608 // 1. The entire cache object
3609 // 2. The data stored at the key
3610 //
3611 if ( key === undefined ||
3612 ((key && typeof key === "string") && value === undefined) ) {
3613
3614 stored = this.get( owner, key );
3615
3616 return stored !== undefined ?
3617 stored : this.get( owner, jQuery.camelCase(key) );
3618 }
3619
3620 // [*]When the key is not a string, or both a key and value
3621 // are specified, set or extend (existing objects) with either:
3622 //
3623 // 1. An object of properties
3624 // 2. A key and value
3625 //
3626 this.set( owner, key, value );
3627
3628 // Since the "set" path can have two possible entry points
3629 // return the expected data based on which path was taken[*]
3630 return value !== undefined ? value : key;
3631 },
3632 remove: function( owner, key ) {
3633 var i, name, camel,
3634 unlock = this.key( owner ),
3635 cache = this.cache[ unlock ];
3636
3637 if ( key === undefined ) {
3638 this.cache[ unlock ] = {};
3639
3640 } else {
3641 // Support array or space separated string of keys
3642 if ( jQuery.isArray( key ) ) {
3643 // If "name" is an array of keys...
3644 // When data is initially created, via ("key", "val") signature,
3645 // keys will be converted to camelCase.
3646 // Since there is no way to tell _how_ a key was added, remove
3647 // both plain key and camelCase key. #12786
3648 // This will only penalize the array argument path.
3649 name = key.concat( key.map( jQuery.camelCase ) );
3650 } else {
3651 camel = jQuery.camelCase( key );
3652 // Try the string as a key before any manipulation
3653 if ( key in cache ) {
3654 name = [ key, camel ];
3655 } else {
3656 // If a key with the spaces exists, use it.
3657 // Otherwise, create an array by matching non-whitespace
3658 name = camel;
3659 name = name in cache ?
3660 [ name ] : ( name.match( rnotwhite ) || [] );
3661 }
3662 }
3663
3664 i = name.length;
3665 while ( i-- ) {
3666 delete cache[ name[ i ] ];
3667 }
3668 }
3669 },
3670 hasData: function( owner ) {
3671 return !jQuery.isEmptyObject(
3672 this.cache[ owner[ this.expando ] ] || {}
3673 );
3674 },
3675 discard: function( owner ) {
3676 if ( owner[ this.expando ] ) {
3677 delete this.cache[ owner[ this.expando ] ];
3678 }
3679 }
3680};
3681var data_priv = new Data();
3682
3683var data_user = new Data();
3684
3685
3686
3687/*
3688 Implementation Summary
3689
3690 1. Enforce API surface and semantic compatibility with 1.9.x branch
3691 2. Improve the module's maintainability by reducing the storage
3692 paths to a single mechanism.
3693 3. Use the same single mechanism to support "private" and "user" data.
3694 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3695 5. Avoid exposing implementation details on user objects (eg. expando properties)
3696 6. Provide a clear path for implementation upgrade to WeakMap in 2014
3697*/
3698var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3699 rmultiDash = /([A-Z])/g;
3700
3701function dataAttr( elem, key, data ) {
3702 var name;
3703
3704 // If nothing was found internally, try to fetch any
3705 // data from the HTML5 data-* attribute
3706 if ( data === undefined && elem.nodeType === 1 ) {
3707 name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3708 data = elem.getAttribute( name );
3709
3710 if ( typeof data === "string" ) {
3711 try {
3712 data = data === "true" ? true :
3713 data === "false" ? false :
3714 data === "null" ? null :
3715 // Only convert to a number if it doesn't change the string
3716 +data + "" === data ? +data :
3717 rbrace.test( data ) ? jQuery.parseJSON( data ) :
3718 data;
3719 } catch( e ) {}
3720
3721 // Make sure we set the data so it isn't changed later
3722 data_user.set( elem, key, data );
3723 } else {
3724 data = undefined;
3725 }
3726 }
3727 return data;
3728}
3729
3730jQuery.extend({
3731 hasData: function( elem ) {
3732 return data_user.hasData( elem ) || data_priv.hasData( elem );
3733 },
3734
3735 data: function( elem, name, data ) {
3736 return data_user.access( elem, name, data );
3737 },
3738
3739 removeData: function( elem, name ) {
3740 data_user.remove( elem, name );
3741 },
3742
3743 // TODO: Now that all calls to _data and _removeData have been replaced
3744 // with direct calls to data_priv methods, these can be deprecated.
3745 _data: function( elem, name, data ) {
3746 return data_priv.access( elem, name, data );
3747 },
3748
3749 _removeData: function( elem, name ) {
3750 data_priv.remove( elem, name );
3751 }
3752});
3753
3754jQuery.fn.extend({
3755 data: function( key, value ) {
3756 var i, name, data,
3757 elem = this[ 0 ],
3758 attrs = elem && elem.attributes;
3759
3760 // Gets all values
3761 if ( key === undefined ) {
3762 if ( this.length ) {
3763 data = data_user.get( elem );
3764
3765 if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
3766 i = attrs.length;
3767 while ( i-- ) {
3768
3769 // Support: IE11+
3770 // The attrs elements can be null (#14894)
3771 if ( attrs[ i ] ) {
3772 name = attrs[ i ].name;
3773 if ( name.indexOf( "data-" ) === 0 ) {
3774 name = jQuery.camelCase( name.slice(5) );
3775 dataAttr( elem, name, data[ name ] );
3776 }
3777 }
3778 }
3779 data_priv.set( elem, "hasDataAttrs", true );
3780 }
3781 }
3782
3783 return data;
3784 }
3785
3786 // Sets multiple values
3787 if ( typeof key === "object" ) {
3788 return this.each(function() {
3789 data_user.set( this, key );
3790 });
3791 }
3792
3793 return access( this, function( value ) {
3794 var data,
3795 camelKey = jQuery.camelCase( key );
3796
3797 // The calling jQuery object (element matches) is not empty
3798 // (and therefore has an element appears at this[ 0 ]) and the
3799 // `value` parameter was not undefined. An empty jQuery object
3800 // will result in `undefined` for elem = this[ 0 ] which will
3801 // throw an exception if an attempt to read a data cache is made.
3802 if ( elem && value === undefined ) {
3803 // Attempt to get data from the cache
3804 // with the key as-is
3805 data = data_user.get( elem, key );
3806 if ( data !== undefined ) {
3807 return data;
3808 }
3809
3810 // Attempt to get data from the cache
3811 // with the key camelized
3812 data = data_user.get( elem, camelKey );
3813 if ( data !== undefined ) {
3814 return data;
3815 }
3816
3817 // Attempt to "discover" the data in
3818 // HTML5 custom data-* attrs
3819 data = dataAttr( elem, camelKey, undefined );
3820 if ( data !== undefined ) {
3821 return data;
3822 }
3823
3824 // We tried really hard, but the data doesn't exist.
3825 return;
3826 }
3827
3828 // Set the data...
3829 this.each(function() {
3830 // First, attempt to store a copy or reference of any
3831 // data that might've been store with a camelCased key.
3832 var data = data_user.get( this, camelKey );
3833
3834 // For HTML5 data-* attribute interop, we have to
3835 // store property names with dashes in a camelCase form.
3836 // This might not apply to all properties...*
3837 data_user.set( this, camelKey, value );
3838
3839 // *... In the case of properties that might _actually_
3840 // have dashes, we need to also store a copy of that
3841 // unchanged property.
3842 if ( key.indexOf("-") !== -1 && data !== undefined ) {
3843 data_user.set( this, key, value );
3844 }
3845 });
3846 }, null, value, arguments.length > 1, null, true );
3847 },
3848
3849 removeData: function( key ) {
3850 return this.each(function() {
3851 data_user.remove( this, key );
3852 });
3853 }
3854});
3855
3856
3857jQuery.extend({
3858 queue: function( elem, type, data ) {
3859 var queue;
3860
3861 if ( elem ) {
3862 type = ( type || "fx" ) + "queue";
3863 queue = data_priv.get( elem, type );
3864
3865 // Speed up dequeue by getting out quickly if this is just a lookup
3866 if ( data ) {
3867 if ( !queue || jQuery.isArray( data ) ) {
3868 queue = data_priv.access( elem, type, jQuery.makeArray(data) );
3869 } else {
3870 queue.push( data );
3871 }
3872 }
3873 return queue || [];
3874 }
3875 },
3876
3877 dequeue: function( elem, type ) {
3878 type = type || "fx";
3879
3880 var queue = jQuery.queue( elem, type ),
3881 startLength = queue.length,
3882 fn = queue.shift(),
3883 hooks = jQuery._queueHooks( elem, type ),
3884 next = function() {
3885 jQuery.dequeue( elem, type );
3886 };
3887
3888 // If the fx queue is dequeued, always remove the progress sentinel
3889 if ( fn === "inprogress" ) {
3890 fn = queue.shift();
3891 startLength--;
3892 }
3893
3894 if ( fn ) {
3895
3896 // Add a progress sentinel to prevent the fx queue from being
3897 // automatically dequeued
3898 if ( type === "fx" ) {
3899 queue.unshift( "inprogress" );
3900 }
3901
3902 // clear up the last queue stop function
3903 delete hooks.stop;
3904 fn.call( elem, next, hooks );
3905 }
3906
3907 if ( !startLength && hooks ) {
3908 hooks.empty.fire();
3909 }
3910 },
3911
3912 // not intended for public consumption - generates a queueHooks object, or returns the current one
3913 _queueHooks: function( elem, type ) {
3914 var key = type + "queueHooks";
3915 return data_priv.get( elem, key ) || data_priv.access( elem, key, {
3916 empty: jQuery.Callbacks("once memory").add(function() {
3917 data_priv.remove( elem, [ type + "queue", key ] );
3918 })
3919 });
3920 }
3921});
3922
3923jQuery.fn.extend({
3924 queue: function( type, data ) {
3925 var setter = 2;
3926
3927 if ( typeof type !== "string" ) {
3928 data = type;
3929 type = "fx";
3930 setter--;
3931 }
3932
3933 if ( arguments.length < setter ) {
3934 return jQuery.queue( this[0], type );
3935 }
3936
3937 return data === undefined ?
3938 this :
3939 this.each(function() {
3940 var queue = jQuery.queue( this, type, data );
3941
3942 // ensure a hooks for this queue
3943 jQuery._queueHooks( this, type );
3944
3945 if ( type === "fx" && queue[0] !== "inprogress" ) {
3946 jQuery.dequeue( this, type );
3947 }
3948 });
3949 },
3950 dequeue: function( type ) {
3951 return this.each(function() {
3952 jQuery.dequeue( this, type );
3953 });
3954 },
3955 clearQueue: function( type ) {
3956 return this.queue( type || "fx", [] );
3957 },
3958 // Get a promise resolved when queues of a certain type
3959 // are emptied (fx is the type by default)
3960 promise: function( type, obj ) {
3961 var tmp,
3962 count = 1,
3963 defer = jQuery.Deferred(),
3964 elements = this,
3965 i = this.length,
3966 resolve = function() {
3967 if ( !( --count ) ) {
3968 defer.resolveWith( elements, [ elements ] );
3969 }
3970 };
3971
3972 if ( typeof type !== "string" ) {
3973 obj = type;
3974 type = undefined;
3975 }
3976 type = type || "fx";
3977
3978 while ( i-- ) {
3979 tmp = data_priv.get( elements[ i ], type + "queueHooks" );
3980 if ( tmp && tmp.empty ) {
3981 count++;
3982 tmp.empty.add( resolve );
3983 }
3984 }
3985 resolve();
3986 return defer.promise( obj );
3987 }
3988});
3989var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
3990
3991var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
3992
3993var isHidden = function( elem, el ) {
3994 // isHidden might be called from jQuery#filter function;
3995 // in that case, element will be second argument
3996 elem = el || elem;
3997 return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
3998 };
3999
4000var rcheckableType = (/^(?:checkbox|radio)$/i);
4001
4002
4003
4004(function() {
4005 var fragment = document.createDocumentFragment(),
4006 div = fragment.appendChild( document.createElement( "div" ) ),
4007 input = document.createElement( "input" );
4008
4009 // #11217 - WebKit loses check when the name is after the checked attribute
4010 // Support: Windows Web Apps (WWA)
4011 // `name` and `type` need .setAttribute for WWA
4012 input.setAttribute( "type", "radio" );
4013 input.setAttribute( "checked", "checked" );
4014 input.setAttribute( "name", "t" );
4015
4016 div.appendChild( input );
4017
4018 // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4019 // old WebKit doesn't clone checked state correctly in fragments
4020 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4021
4022 // Make sure textarea (and checkbox) defaultValue is properly cloned
4023 // Support: IE9-IE11+
4024 div.innerHTML = "<textarea>x</textarea>";
4025 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4026})();
4027var strundefined = typeof undefined;
4028
4029
4030
4031support.focusinBubbles = "onfocusin" in window;
4032
4033
4034var
4035 rkeyEvent = /^key/,
4036 rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
4037 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4038 rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4039
4040function returnTrue() {
4041 return true;
4042}
4043
4044function returnFalse() {
4045 return false;
4046}
4047
4048function safeActiveElement() {
4049 try {
4050 return document.activeElement;
4051 } catch ( err ) { }
4052}
4053
4054/*
4055 * Helper functions for managing events -- not part of the public interface.
4056 * Props to Dean Edwards' addEvent library for many of the ideas.
4057 */
4058jQuery.event = {
4059
4060 global: {},
4061
4062 add: function( elem, types, handler, data, selector ) {
4063
4064 var handleObjIn, eventHandle, tmp,
4065 events, t, handleObj,
4066 special, handlers, type, namespaces, origType,
4067 elemData = data_priv.get( elem );
4068
4069 // Don't attach events to noData or text/comment nodes (but allow plain objects)
4070 if ( !elemData ) {
4071 return;
4072 }
4073
4074 // Caller can pass in an object of custom data in lieu of the handler
4075 if ( handler.handler ) {
4076 handleObjIn = handler;
4077 handler = handleObjIn.handler;
4078 selector = handleObjIn.selector;
4079 }
4080
4081 // Make sure that the handler has a unique ID, used to find/remove it later
4082 if ( !handler.guid ) {
4083 handler.guid = jQuery.guid++;
4084 }
4085
4086 // Init the element's event structure and main handler, if this is the first
4087 if ( !(events = elemData.events) ) {
4088 events = elemData.events = {};
4089 }
4090 if ( !(eventHandle = elemData.handle) ) {
4091 eventHandle = elemData.handle = function( e ) {
4092 // Discard the second event of a jQuery.event.trigger() and
4093 // when an event is called after a page has unloaded
4094 return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
4095 jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4096 };
4097 }
4098
4099 // Handle multiple events separated by a space
4100 types = ( types || "" ).match( rnotwhite ) || [ "" ];
4101 t = types.length;
4102 while ( t-- ) {
4103 tmp = rtypenamespace.exec( types[t] ) || [];
4104 type = origType = tmp[1];
4105 namespaces = ( tmp[2] || "" ).split( "." ).sort();
4106
4107 // There *must* be a type, no attaching namespace-only handlers
4108 if ( !type ) {
4109 continue;
4110 }
4111
4112 // If event changes its type, use the special event handlers for the changed type
4113 special = jQuery.event.special[ type ] || {};
4114
4115 // If selector defined, determine special event api type, otherwise given type
4116 type = ( selector ? special.delegateType : special.bindType ) || type;
4117
4118 // Update special based on newly reset type
4119 special = jQuery.event.special[ type ] || {};
4120
4121 // handleObj is passed to all event handlers
4122 handleObj = jQuery.extend({
4123 type: type,
4124 origType: origType,
4125 data: data,
4126 handler: handler,
4127 guid: handler.guid,
4128 selector: selector,
4129 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4130 namespace: namespaces.join(".")
4131 }, handleObjIn );
4132
4133 // Init the event handler queue if we're the first
4134 if ( !(handlers = events[ type ]) ) {
4135 handlers = events[ type ] = [];
4136 handlers.delegateCount = 0;
4137
4138 // Only use addEventListener if the special events handler returns false
4139 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4140 if ( elem.addEventListener ) {
4141 elem.addEventListener( type, eventHandle, false );
4142 }
4143 }
4144 }
4145
4146 if ( special.add ) {
4147 special.add.call( elem, handleObj );
4148
4149 if ( !handleObj.handler.guid ) {
4150 handleObj.handler.guid = handler.guid;
4151 }
4152 }
4153
4154 // Add to the element's handler list, delegates in front
4155 if ( selector ) {
4156 handlers.splice( handlers.delegateCount++, 0, handleObj );
4157 } else {
4158 handlers.push( handleObj );
4159 }
4160
4161 // Keep track of which events have ever been used, for event optimization
4162 jQuery.event.global[ type ] = true;
4163 }
4164
4165 },
4166
4167 // Detach an event or set of events from an element
4168 remove: function( elem, types, handler, selector, mappedTypes ) {
4169
4170 var j, origCount, tmp,
4171 events, t, handleObj,
4172 special, handlers, type, namespaces, origType,
4173 elemData = data_priv.hasData( elem ) && data_priv.get( elem );
4174
4175 if ( !elemData || !(events = elemData.events) ) {
4176 return;
4177 }
4178
4179 // Once for each type.namespace in types; type may be omitted
4180 types = ( types || "" ).match( rnotwhite ) || [ "" ];
4181 t = types.length;
4182 while ( t-- ) {
4183 tmp = rtypenamespace.exec( types[t] ) || [];
4184 type = origType = tmp[1];
4185 namespaces = ( tmp[2] || "" ).split( "." ).sort();
4186
4187 // Unbind all events (on this namespace, if provided) for the element
4188 if ( !type ) {
4189 for ( type in events ) {
4190 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4191 }
4192 continue;
4193 }
4194
4195 special = jQuery.event.special[ type ] || {};
4196 type = ( selector ? special.delegateType : special.bindType ) || type;
4197 handlers = events[ type ] || [];
4198 tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4199
4200 // Remove matching events
4201 origCount = j = handlers.length;
4202 while ( j-- ) {
4203 handleObj = handlers[ j ];
4204
4205 if ( ( mappedTypes || origType === handleObj.origType ) &&
4206 ( !handler || handler.guid === handleObj.guid ) &&
4207 ( !tmp || tmp.test( handleObj.namespace ) ) &&
4208 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4209 handlers.splice( j, 1 );
4210
4211 if ( handleObj.selector ) {
4212 handlers.delegateCount--;
4213 }
4214 if ( special.remove ) {
4215 special.remove.call( elem, handleObj );
4216 }
4217 }
4218 }
4219
4220 // Remove generic event handler if we removed something and no more handlers exist
4221 // (avoids potential for endless recursion during removal of special event handlers)
4222 if ( origCount && !handlers.length ) {
4223 if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4224 jQuery.removeEvent( elem, type, elemData.handle );
4225 }
4226
4227 delete events[ type ];
4228 }
4229 }
4230
4231 // Remove the expando if it's no longer used
4232 if ( jQuery.isEmptyObject( events ) ) {
4233 delete elemData.handle;
4234 data_priv.remove( elem, "events" );
4235 }
4236 },
4237
4238 trigger: function( event, data, elem, onlyHandlers ) {
4239
4240 var i, cur, tmp, bubbleType, ontype, handle, special,
4241 eventPath = [ elem || document ],
4242 type = hasOwn.call( event, "type" ) ? event.type : event,
4243 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4244
4245 cur = tmp = elem = elem || document;
4246
4247 // Don't do events on text and comment nodes
4248 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4249 return;
4250 }
4251
4252 // focus/blur morphs to focusin/out; ensure we're not firing them right now
4253 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4254 return;
4255 }
4256
4257 if ( type.indexOf(".") >= 0 ) {
4258 // Namespaced trigger; create a regexp to match event type in handle()
4259 namespaces = type.split(".");
4260 type = namespaces.shift();
4261 namespaces.sort();
4262 }
4263 ontype = type.indexOf(":") < 0 && "on" + type;
4264
4265 // Caller can pass in a jQuery.Event object, Object, or just an event type string
4266 event = event[ jQuery.expando ] ?
4267 event :
4268 new jQuery.Event( type, typeof event === "object" && event );
4269
4270 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4271 event.isTrigger = onlyHandlers ? 2 : 3;
4272 event.namespace = namespaces.join(".");
4273 event.namespace_re = event.namespace ?
4274 new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4275 null;
4276
4277 // Clean up the event in case it is being reused
4278 event.result = undefined;
4279 if ( !event.target ) {
4280 event.target = elem;
4281 }
4282
4283 // Clone any incoming data and prepend the event, creating the handler arg list
4284 data = data == null ?
4285 [ event ] :
4286 jQuery.makeArray( data, [ event ] );
4287
4288 // Allow special events to draw outside the lines
4289 special = jQuery.event.special[ type ] || {};
4290 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4291 return;
4292 }
4293
4294 // Determine event propagation path in advance, per W3C events spec (#9951)
4295 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4296 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4297
4298 bubbleType = special.delegateType || type;
4299 if ( !rfocusMorph.test( bubbleType + type ) ) {
4300 cur = cur.parentNode;
4301 }
4302 for ( ; cur; cur = cur.parentNode ) {
4303 eventPath.push( cur );
4304 tmp = cur;
4305 }
4306
4307 // Only add window if we got to document (e.g., not plain obj or detached DOM)
4308 if ( tmp === (elem.ownerDocument || document) ) {
4309 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4310 }
4311 }
4312
4313 // Fire handlers on the event path
4314 i = 0;
4315 while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4316
4317 event.type = i > 1 ?
4318 bubbleType :
4319 special.bindType || type;
4320
4321 // jQuery handler
4322 handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
4323 if ( handle ) {
4324 handle.apply( cur, data );
4325 }
4326
4327 // Native handler
4328 handle = ontype && cur[ ontype ];
4329 if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
4330 event.result = handle.apply( cur, data );
4331 if ( event.result === false ) {
4332 event.preventDefault();
4333 }
4334 }
4335 }
4336 event.type = type;
4337
4338 // If nobody prevented the default action, do it now
4339 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4340
4341 if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4342 jQuery.acceptData( elem ) ) {
4343
4344 // Call a native DOM method on the target with the same name name as the event.
4345 // Don't do default actions on window, that's where global variables be (#6170)
4346 if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
4347
4348 // Don't re-trigger an onFOO event when we call its FOO() method
4349 tmp = elem[ ontype ];
4350
4351 if ( tmp ) {
4352 elem[ ontype ] = null;
4353 }
4354
4355 // Prevent re-triggering of the same event, since we already bubbled it above
4356 jQuery.event.triggered = type;
4357 elem[ type ]();
4358 jQuery.event.triggered = undefined;
4359
4360 if ( tmp ) {
4361 elem[ ontype ] = tmp;
4362 }
4363 }
4364 }
4365 }
4366
4367 return event.result;
4368 },
4369
4370 dispatch: function( event ) {
4371
4372 // Make a writable jQuery.Event from the native event object
4373 event = jQuery.event.fix( event );
4374
4375 var i, j, ret, matched, handleObj,
4376 handlerQueue = [],
4377 args = slice.call( arguments ),
4378 handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
4379 special = jQuery.event.special[ event.type ] || {};
4380
4381 // Use the fix-ed jQuery.Event rather than the (read-only) native event
4382 args[0] = event;
4383 event.delegateTarget = this;
4384
4385 // Call the preDispatch hook for the mapped type, and let it bail if desired
4386 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4387 return;
4388 }
4389
4390 // Determine handlers
4391 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4392
4393 // Run delegates first; they may want to stop propagation beneath us
4394 i = 0;
4395 while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4396 event.currentTarget = matched.elem;
4397
4398 j = 0;
4399 while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4400
4401 // Triggered event must either 1) have no namespace, or
4402 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
4403 if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4404
4405 event.handleObj = handleObj;
4406 event.data = handleObj.data;
4407
4408 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4409 .apply( matched.elem, args );
4410
4411 if ( ret !== undefined ) {
4412 if ( (event.result = ret) === false ) {
4413 event.preventDefault();
4414 event.stopPropagation();
4415 }
4416 }
4417 }
4418 }
4419 }
4420
4421 // Call the postDispatch hook for the mapped type
4422 if ( special.postDispatch ) {
4423 special.postDispatch.call( this, event );
4424 }
4425
4426 return event.result;
4427 },
4428
4429 handlers: function( event, handlers ) {
4430 var i, matches, sel, handleObj,
4431 handlerQueue = [],
4432 delegateCount = handlers.delegateCount,
4433 cur = event.target;
4434
4435 // Find delegate handlers
4436 // Black-hole SVG <use> instance trees (#13180)
4437 // Avoid non-left-click bubbling in Firefox (#3861)
4438 if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4439
4440 for ( ; cur !== this; cur = cur.parentNode || this ) {
4441
4442 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4443 if ( cur.disabled !== true || event.type !== "click" ) {
4444 matches = [];
4445 for ( i = 0; i < delegateCount; i++ ) {
4446 handleObj = handlers[ i ];
4447
4448 // Don't conflict with Object.prototype properties (#13203)
4449 sel = handleObj.selector + " ";
4450
4451 if ( matches[ sel ] === undefined ) {
4452 matches[ sel ] = handleObj.needsContext ?
4453 jQuery( sel, this ).index( cur ) >= 0 :
4454 jQuery.find( sel, this, null, [ cur ] ).length;
4455 }
4456 if ( matches[ sel ] ) {
4457 matches.push( handleObj );
4458 }
4459 }
4460 if ( matches.length ) {
4461 handlerQueue.push({ elem: cur, handlers: matches });
4462 }
4463 }
4464 }
4465 }
4466
4467 // Add the remaining (directly-bound) handlers
4468 if ( delegateCount < handlers.length ) {
4469 handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4470 }
4471
4472 return handlerQueue;
4473 },
4474
4475 // Includes some event props shared by KeyEvent and MouseEvent
4476 props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4477
4478 fixHooks: {},
4479
4480 keyHooks: {
4481 props: "char charCode key keyCode".split(" "),
4482 filter: function( event, original ) {
4483
4484 // Add which for key events
4485 if ( event.which == null ) {
4486 event.which = original.charCode != null ? original.charCode : original.keyCode;
4487 }
4488
4489 return event;
4490 }
4491 },
4492
4493 mouseHooks: {
4494 props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4495 filter: function( event, original ) {
4496 var eventDoc, doc, body,
4497 button = original.button;
4498
4499 // Calculate pageX/Y if missing and clientX/Y available
4500 if ( event.pageX == null && original.clientX != null ) {
4501 eventDoc = event.target.ownerDocument || document;
4502 doc = eventDoc.documentElement;
4503 body = eventDoc.body;
4504
4505 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4506 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
4507 }
4508
4509 // Add which for click: 1 === left; 2 === middle; 3 === right
4510 // Note: button is not normalized, so don't use it
4511 if ( !event.which && button !== undefined ) {
4512 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4513 }
4514
4515 return event;
4516 }
4517 },
4518
4519 fix: function( event ) {
4520 if ( event[ jQuery.expando ] ) {
4521 return event;
4522 }
4523
4524 // Create a writable copy of the event object and normalize some properties
4525 var i, prop, copy,
4526 type = event.type,
4527 originalEvent = event,
4528 fixHook = this.fixHooks[ type ];
4529
4530 if ( !fixHook ) {
4531 this.fixHooks[ type ] = fixHook =
4532 rmouseEvent.test( type ) ? this.mouseHooks :
4533 rkeyEvent.test( type ) ? this.keyHooks :
4534 {};
4535 }
4536 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4537
4538 event = new jQuery.Event( originalEvent );
4539
4540 i = copy.length;
4541 while ( i-- ) {
4542 prop = copy[ i ];
4543 event[ prop ] = originalEvent[ prop ];
4544 }
4545
4546 // Support: Cordova 2.5 (WebKit) (#13255)
4547 // All events should have a target; Cordova deviceready doesn't
4548 if ( !event.target ) {
4549 event.target = document;
4550 }
4551
4552 // Support: Safari 6.0+, Chrome < 28
4553 // Target should not be a text node (#504, #13143)
4554 if ( event.target.nodeType === 3 ) {
4555 event.target = event.target.parentNode;
4556 }
4557
4558 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4559 },
4560
4561 special: {
4562 load: {
4563 // Prevent triggered image.load events from bubbling to window.load
4564 noBubble: true
4565 },
4566 focus: {
4567 // Fire native event if possible so blur/focus sequence is correct
4568 trigger: function() {
4569 if ( this !== safeActiveElement() && this.focus ) {
4570 this.focus();
4571 return false;
4572 }
4573 },
4574 delegateType: "focusin"
4575 },
4576 blur: {
4577 trigger: function() {
4578 if ( this === safeActiveElement() && this.blur ) {
4579 this.blur();
4580 return false;
4581 }
4582 },
4583 delegateType: "focusout"
4584 },
4585 click: {
4586 // For checkbox, fire native event so checked state will be right
4587 trigger: function() {
4588 if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4589 this.click();
4590 return false;
4591 }
4592 },
4593
4594 // For cross-browser consistency, don't fire native .click() on links
4595 _default: function( event ) {
4596 return jQuery.nodeName( event.target, "a" );
4597 }
4598 },
4599
4600 beforeunload: {
4601 postDispatch: function( event ) {
4602
4603 // Support: Firefox 20+
4604 // Firefox doesn't alert if the returnValue field is not set.
4605 if ( event.result !== undefined && event.originalEvent ) {
4606 event.originalEvent.returnValue = event.result;
4607 }
4608 }
4609 }
4610 },
4611
4612 simulate: function( type, elem, event, bubble ) {
4613 // Piggyback on a donor event to simulate a different one.
4614 // Fake originalEvent to avoid donor's stopPropagation, but if the
4615 // simulated event prevents default then we do the same on the donor.
4616 var e = jQuery.extend(
4617 new jQuery.Event(),
4618 event,
4619 {
4620 type: type,
4621 isSimulated: true,
4622 originalEvent: {}
4623 }
4624 );
4625 if ( bubble ) {
4626 jQuery.event.trigger( e, null, elem );
4627 } else {
4628 jQuery.event.dispatch.call( elem, e );
4629 }
4630 if ( e.isDefaultPrevented() ) {
4631 event.preventDefault();
4632 }
4633 }
4634};
4635
4636jQuery.removeEvent = function( elem, type, handle ) {
4637 if ( elem.removeEventListener ) {
4638 elem.removeEventListener( type, handle, false );
4639 }
4640};
4641
4642jQuery.Event = function( src, props ) {
4643 // Allow instantiation without the 'new' keyword
4644 if ( !(this instanceof jQuery.Event) ) {
4645 return new jQuery.Event( src, props );
4646 }
4647
4648 // Event object
4649 if ( src && src.type ) {
4650 this.originalEvent = src;
4651 this.type = src.type;
4652
4653 // Events bubbling up the document may have been marked as prevented
4654 // by a handler lower down the tree; reflect the correct value.
4655 this.isDefaultPrevented = src.defaultPrevented ||
4656 src.defaultPrevented === undefined &&
4657 // Support: Android < 4.0
4658 src.returnValue === false ?
4659 returnTrue :
4660 returnFalse;
4661
4662 // Event type
4663 } else {
4664 this.type = src;
4665 }
4666
4667 // Put explicitly provided properties onto the event object
4668 if ( props ) {
4669 jQuery.extend( this, props );
4670 }
4671
4672 // Create a timestamp if incoming event doesn't have one
4673 this.timeStamp = src && src.timeStamp || jQuery.now();
4674
4675 // Mark it as fixed
4676 this[ jQuery.expando ] = true;
4677};
4678
4679// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4680// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4681jQuery.Event.prototype = {
4682 isDefaultPrevented: returnFalse,
4683 isPropagationStopped: returnFalse,
4684 isImmediatePropagationStopped: returnFalse,
4685
4686 preventDefault: function() {
4687 var e = this.originalEvent;
4688
4689 this.isDefaultPrevented = returnTrue;
4690
4691 if ( e && e.preventDefault ) {
4692 e.preventDefault();
4693 }
4694 },
4695 stopPropagation: function() {
4696 var e = this.originalEvent;
4697
4698 this.isPropagationStopped = returnTrue;
4699
4700 if ( e && e.stopPropagation ) {
4701 e.stopPropagation();
4702 }
4703 },
4704 stopImmediatePropagation: function() {
4705 var e = this.originalEvent;
4706
4707 this.isImmediatePropagationStopped = returnTrue;
4708
4709 if ( e && e.stopImmediatePropagation ) {
4710 e.stopImmediatePropagation();
4711 }
4712
4713 this.stopPropagation();
4714 }
4715};
4716
4717// Create mouseenter/leave events using mouseover/out and event-time checks
4718// Support: Chrome 15+
4719jQuery.each({
4720 mouseenter: "mouseover",
4721 mouseleave: "mouseout",
4722 pointerenter: "pointerover",
4723 pointerleave: "pointerout"
4724}, function( orig, fix ) {
4725 jQuery.event.special[ orig ] = {
4726 delegateType: fix,
4727 bindType: fix,
4728
4729 handle: function( event ) {
4730 var ret,
4731 target = this,
4732 related = event.relatedTarget,
4733 handleObj = event.handleObj;
4734
4735 // For mousenter/leave call the handler if related is outside the target.
4736 // NB: No relatedTarget if the mouse left/entered the browser window
4737 if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
4738 event.type = handleObj.origType;
4739 ret = handleObj.handler.apply( this, arguments );
4740 event.type = fix;
4741 }
4742 return ret;
4743 }
4744 };
4745});
4746
4747// Create "bubbling" focus and blur events
4748// Support: Firefox, Chrome, Safari
4749if ( !support.focusinBubbles ) {
4750 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
4751
4752 // Attach a single capturing handler on the document while someone wants focusin/focusout
4753 var handler = function( event ) {
4754 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
4755 };
4756
4757 jQuery.event.special[ fix ] = {
4758 setup: function() {
4759 var doc = this.ownerDocument || this,
4760 attaches = data_priv.access( doc, fix );
4761
4762 if ( !attaches ) {
4763 doc.addEventListener( orig, handler, true );
4764 }
4765 data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
4766 },
4767 teardown: function() {
4768 var doc = this.ownerDocument || this,
4769 attaches = data_priv.access( doc, fix ) - 1;
4770
4771 if ( !attaches ) {
4772 doc.removeEventListener( orig, handler, true );
4773 data_priv.remove( doc, fix );
4774
4775 } else {
4776 data_priv.access( doc, fix, attaches );
4777 }
4778 }
4779 };
4780 });
4781}
4782
4783jQuery.fn.extend({
4784
4785 on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
4786 var origFn, type;
4787
4788 // Types can be a map of types/handlers
4789 if ( typeof types === "object" ) {
4790 // ( types-Object, selector, data )
4791 if ( typeof selector !== "string" ) {
4792 // ( types-Object, data )
4793 data = data || selector;
4794 selector = undefined;
4795 }
4796 for ( type in types ) {
4797 this.on( type, selector, data, types[ type ], one );
4798 }
4799 return this;
4800 }
4801
4802 if ( data == null && fn == null ) {
4803 // ( types, fn )
4804 fn = selector;
4805 data = selector = undefined;
4806 } else if ( fn == null ) {
4807 if ( typeof selector === "string" ) {
4808 // ( types, selector, fn )
4809 fn = data;
4810 data = undefined;
4811 } else {
4812 // ( types, data, fn )
4813 fn = data;
4814 data = selector;
4815 selector = undefined;
4816 }
4817 }
4818 if ( fn === false ) {
4819 fn = returnFalse;
4820 } else if ( !fn ) {
4821 return this;
4822 }
4823
4824 if ( one === 1 ) {
4825 origFn = fn;
4826 fn = function( event ) {
4827 // Can use an empty set, since event contains the info
4828 jQuery().off( event );
4829 return origFn.apply( this, arguments );
4830 };
4831 // Use same guid so caller can remove using origFn
4832 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4833 }
4834 return this.each( function() {
4835 jQuery.event.add( this, types, fn, data, selector );
4836 });
4837 },
4838 one: function( types, selector, data, fn ) {
4839 return this.on( types, selector, data, fn, 1 );
4840 },
4841 off: function( types, selector, fn ) {
4842 var handleObj, type;
4843 if ( types && types.preventDefault && types.handleObj ) {
4844 // ( event ) dispatched jQuery.Event
4845 handleObj = types.handleObj;
4846 jQuery( types.delegateTarget ).off(
4847 handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
4848 handleObj.selector,
4849 handleObj.handler
4850 );
4851 return this;
4852 }
4853 if ( typeof types === "object" ) {
4854 // ( types-object [, selector] )
4855 for ( type in types ) {
4856 this.off( type, selector, types[ type ] );
4857 }
4858 return this;
4859 }
4860 if ( selector === false || typeof selector === "function" ) {
4861 // ( types [, fn] )
4862 fn = selector;
4863 selector = undefined;
4864 }
4865 if ( fn === false ) {
4866 fn = returnFalse;
4867 }
4868 return this.each(function() {
4869 jQuery.event.remove( this, types, fn, selector );
4870 });
4871 },
4872
4873 trigger: function( type, data ) {
4874 return this.each(function() {
4875 jQuery.event.trigger( type, data, this );
4876 });
4877 },
4878 triggerHandler: function( type, data ) {
4879 var elem = this[0];
4880 if ( elem ) {
4881 return jQuery.event.trigger( type, data, elem, true );
4882 }
4883 }
4884});
4885
4886
4887var
4888 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
4889 rtagName = /<([\w:]+)/,
4890 rhtml = /<|&#?\w+;/,
4891 rnoInnerhtml = /<(?:script|style|link)/i,
4892 // checked="checked" or checked
4893 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4894 rscriptType = /^$|\/(?:java|ecma)script/i,
4895 rscriptTypeMasked = /^true\/(.*)/,
4896 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
4897
4898 // We have to close these tags to support XHTML (#13200)
4899 wrapMap = {
4900
4901 // Support: IE 9
4902 option: [ 1, "<select multiple='multiple'>", "</select>" ],
4903
4904 thead: [ 1, "<table>", "</table>" ],
4905 col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4906 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4907 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4908
4909 _default: [ 0, "", "" ]
4910 };
4911
4912// Support: IE 9
4913wrapMap.optgroup = wrapMap.option;
4914
4915wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4916wrapMap.th = wrapMap.td;
4917
4918// Support: 1.x compatibility
4919// Manipulating tables requires a tbody
4920function manipulationTarget( elem, content ) {
4921 return jQuery.nodeName( elem, "table" ) &&
4922 jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
4923
4924 elem.getElementsByTagName("tbody")[0] ||
4925 elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
4926 elem;
4927}
4928
4929// Replace/restore the type attribute of script elements for safe DOM manipulation
4930function disableScript( elem ) {
4931 elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
4932 return elem;
4933}
4934function restoreScript( elem ) {
4935 var match = rscriptTypeMasked.exec( elem.type );
4936
4937 if ( match ) {
4938 elem.type = match[ 1 ];
4939 } else {
4940 elem.removeAttribute("type");
4941 }
4942
4943 return elem;
4944}
4945
4946// Mark scripts as having already been evaluated
4947function setGlobalEval( elems, refElements ) {
4948 var i = 0,
4949 l = elems.length;
4950
4951 for ( ; i < l; i++ ) {
4952 data_priv.set(
4953 elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
4954 );
4955 }
4956}
4957
4958function cloneCopyEvent( src, dest ) {
4959 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
4960
4961 if ( dest.nodeType !== 1 ) {
4962 return;
4963 }
4964
4965 // 1. Copy private data: events, handlers, etc.
4966 if ( data_priv.hasData( src ) ) {
4967 pdataOld = data_priv.access( src );
4968 pdataCur = data_priv.set( dest, pdataOld );
4969 events = pdataOld.events;
4970
4971 if ( events ) {
4972 delete pdataCur.handle;
4973 pdataCur.events = {};
4974
4975 for ( type in events ) {
4976 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
4977 jQuery.event.add( dest, type, events[ type ][ i ] );
4978 }
4979 }
4980 }
4981 }
4982
4983 // 2. Copy user data
4984 if ( data_user.hasData( src ) ) {
4985 udataOld = data_user.access( src );
4986 udataCur = jQuery.extend( {}, udataOld );
4987
4988 data_user.set( dest, udataCur );
4989 }
4990}
4991
4992function getAll( context, tag ) {
4993 var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
4994 context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
4995 [];
4996
4997 return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4998 jQuery.merge( [ context ], ret ) :
4999 ret;
5000}
5001
5002// Support: IE >= 9
5003function fixInput( src, dest ) {
5004 var nodeName = dest.nodeName.toLowerCase();
5005
5006 // Fails to persist the checked state of a cloned checkbox or radio button.
5007 if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5008 dest.checked = src.checked;
5009
5010 // Fails to return the selected option to the default selected state when cloning options
5011 } else if ( nodeName === "input" || nodeName === "textarea" ) {
5012 dest.defaultValue = src.defaultValue;
5013 }
5014}
5015
5016jQuery.extend({
5017 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5018 var i, l, srcElements, destElements,
5019 clone = elem.cloneNode( true ),
5020 inPage = jQuery.contains( elem.ownerDocument, elem );
5021
5022 // Support: IE >= 9
5023 // Fix Cloning issues
5024 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5025 !jQuery.isXMLDoc( elem ) ) {
5026
5027 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5028 destElements = getAll( clone );
5029 srcElements = getAll( elem );
5030
5031 for ( i = 0, l = srcElements.length; i < l; i++ ) {
5032 fixInput( srcElements[ i ], destElements[ i ] );
5033 }
5034 }
5035
5036 // Copy the events from the original to the clone
5037 if ( dataAndEvents ) {
5038 if ( deepDataAndEvents ) {
5039 srcElements = srcElements || getAll( elem );
5040 destElements = destElements || getAll( clone );
5041
5042 for ( i = 0, l = srcElements.length; i < l; i++ ) {
5043 cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5044 }
5045 } else {
5046 cloneCopyEvent( elem, clone );
5047 }
5048 }
5049
5050 // Preserve script evaluation history
5051 destElements = getAll( clone, "script" );
5052 if ( destElements.length > 0 ) {
5053 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5054 }
5055
5056 // Return the cloned set
5057 return clone;
5058 },
5059
5060 buildFragment: function( elems, context, scripts, selection ) {
5061 var elem, tmp, tag, wrap, contains, j,
5062 fragment = context.createDocumentFragment(),
5063 nodes = [],
5064 i = 0,
5065 l = elems.length;
5066
5067 for ( ; i < l; i++ ) {
5068 elem = elems[ i ];
5069
5070 if ( elem || elem === 0 ) {
5071
5072 // Add nodes directly
5073 if ( jQuery.type( elem ) === "object" ) {
5074 // Support: QtWebKit
5075 // jQuery.merge because push.apply(_, arraylike) throws
5076 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5077
5078 // Convert non-html into a text node
5079 } else if ( !rhtml.test( elem ) ) {
5080 nodes.push( context.createTextNode( elem ) );
5081
5082 // Convert html into DOM nodes
5083 } else {
5084 tmp = tmp || fragment.appendChild( context.createElement("div") );
5085
5086 // Deserialize a standard representation
5087 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5088 wrap = wrapMap[ tag ] || wrapMap._default;
5089 tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
5090
5091 // Descend through wrappers to the right content
5092 j = wrap[ 0 ];
5093 while ( j-- ) {
5094 tmp = tmp.lastChild;
5095 }
5096
5097 // Support: QtWebKit
5098 // jQuery.merge because push.apply(_, arraylike) throws
5099 jQuery.merge( nodes, tmp.childNodes );
5100
5101 // Remember the top-level container
5102 tmp = fragment.firstChild;
5103
5104 // Fixes #12346
5105 // Support: Webkit, IE
5106 tmp.textContent = "";
5107 }
5108 }
5109 }
5110
5111 // Remove wrapper from fragment
5112 fragment.textContent = "";
5113
5114 i = 0;
5115 while ( (elem = nodes[ i++ ]) ) {
5116
5117 // #4087 - If origin and destination elements are the same, and this is
5118 // that element, do not do anything
5119 if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5120 continue;
5121 }
5122
5123 contains = jQuery.contains( elem.ownerDocument, elem );
5124
5125 // Append to fragment
5126 tmp = getAll( fragment.appendChild( elem ), "script" );
5127
5128 // Preserve script evaluation history
5129 if ( contains ) {
5130 setGlobalEval( tmp );
5131 }
5132
5133 // Capture executables
5134 if ( scripts ) {
5135 j = 0;
5136 while ( (elem = tmp[ j++ ]) ) {
5137 if ( rscriptType.test( elem.type || "" ) ) {
5138 scripts.push( elem );
5139 }
5140 }
5141 }
5142 }
5143
5144 return fragment;
5145 },
5146
5147 cleanData: function( elems ) {
5148 var data, elem, type, key,
5149 special = jQuery.event.special,
5150 i = 0;
5151
5152 for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
5153 if ( jQuery.acceptData( elem ) ) {
5154 key = elem[ data_priv.expando ];
5155
5156 if ( key && (data = data_priv.cache[ key ]) ) {
5157 if ( data.events ) {
5158 for ( type in data.events ) {
5159 if ( special[ type ] ) {
5160 jQuery.event.remove( elem, type );
5161
5162 // This is a shortcut to avoid jQuery.event.remove's overhead
5163 } else {
5164 jQuery.removeEvent( elem, type, data.handle );
5165 }
5166 }
5167 }
5168 if ( data_priv.cache[ key ] ) {
5169 // Discard any remaining `private` data
5170 delete data_priv.cache[ key ];
5171 }
5172 }
5173 }
5174 // Discard any remaining `user` data
5175 delete data_user.cache[ elem[ data_user.expando ] ];
5176 }
5177 }
5178});
5179
5180jQuery.fn.extend({
5181 text: function( value ) {
5182 return access( this, function( value ) {
5183 return value === undefined ?
5184 jQuery.text( this ) :
5185 this.empty().each(function() {
5186 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5187 this.textContent = value;
5188 }
5189 });
5190 }, null, value, arguments.length );
5191 },
5192
5193 append: function() {
5194 return this.domManip( arguments, function( elem ) {
5195 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5196 var target = manipulationTarget( this, elem );
5197 target.appendChild( elem );
5198 }
5199 });
5200 },
5201
5202 prepend: function() {
5203 return this.domManip( arguments, function( elem ) {
5204 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5205 var target = manipulationTarget( this, elem );
5206 target.insertBefore( elem, target.firstChild );
5207 }
5208 });
5209 },
5210
5211 before: function() {
5212 return this.domManip( arguments, function( elem ) {
5213 if ( this.parentNode ) {
5214 this.parentNode.insertBefore( elem, this );
5215 }
5216 });
5217 },
5218
5219 after: function() {
5220 return this.domManip( arguments, function( elem ) {
5221 if ( this.parentNode ) {
5222 this.parentNode.insertBefore( elem, this.nextSibling );
5223 }
5224 });
5225 },
5226
5227 remove: function( selector, keepData /* Internal Use Only */ ) {
5228 var elem,
5229 elems = selector ? jQuery.filter( selector, this ) : this,
5230 i = 0;
5231
5232 for ( ; (elem = elems[i]) != null; i++ ) {
5233 if ( !keepData && elem.nodeType === 1 ) {
5234 jQuery.cleanData( getAll( elem ) );
5235 }
5236
5237 if ( elem.parentNode ) {
5238 if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5239 setGlobalEval( getAll( elem, "script" ) );
5240 }
5241 elem.parentNode.removeChild( elem );
5242 }
5243 }
5244
5245 return this;
5246 },
5247
5248 empty: function() {
5249 var elem,
5250 i = 0;
5251
5252 for ( ; (elem = this[i]) != null; i++ ) {
5253 if ( elem.nodeType === 1 ) {
5254
5255 // Prevent memory leaks
5256 jQuery.cleanData( getAll( elem, false ) );
5257
5258 // Remove any remaining nodes
5259 elem.textContent = "";
5260 }
5261 }
5262
5263 return this;
5264 },
5265
5266 clone: function( dataAndEvents, deepDataAndEvents ) {
5267 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5268 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5269
5270 return this.map(function() {
5271 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5272 });
5273 },
5274
5275 html: function( value ) {
5276 return access( this, function( value ) {
5277 var elem = this[ 0 ] || {},
5278 i = 0,
5279 l = this.length;
5280
5281 if ( value === undefined && elem.nodeType === 1 ) {
5282 return elem.innerHTML;
5283 }
5284
5285 // See if we can take a shortcut and just use innerHTML
5286 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5287 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5288
5289 value = value.replace( rxhtmlTag, "<$1></$2>" );
5290
5291 try {
5292 for ( ; i < l; i++ ) {
5293 elem = this[ i ] || {};
5294
5295 // Remove element nodes and prevent memory leaks
5296 if ( elem.nodeType === 1 ) {
5297 jQuery.cleanData( getAll( elem, false ) );
5298 elem.innerHTML = value;
5299 }
5300 }
5301
5302 elem = 0;
5303
5304 // If using innerHTML throws an exception, use the fallback method
5305 } catch( e ) {}
5306 }
5307
5308 if ( elem ) {
5309 this.empty().append( value );
5310 }
5311 }, null, value, arguments.length );
5312 },
5313
5314 replaceWith: function() {
5315 var arg = arguments[ 0 ];
5316
5317 // Make the changes, replacing each context element with the new content
5318 this.domManip( arguments, function( elem ) {
5319 arg = this.parentNode;
5320
5321 jQuery.cleanData( getAll( this ) );
5322
5323 if ( arg ) {
5324 arg.replaceChild( elem, this );
5325 }
5326 });
5327
5328 // Force removal if there was no new content (e.g., from empty arguments)
5329 return arg && (arg.length || arg.nodeType) ? this : this.remove();
5330 },
5331
5332 detach: function( selector ) {
5333 return this.remove( selector, true );
5334 },
5335
5336 domManip: function( args, callback ) {
5337
5338 // Flatten any nested arrays
5339 args = concat.apply( [], args );
5340
5341 var fragment, first, scripts, hasScripts, node, doc,
5342 i = 0,
5343 l = this.length,
5344 set = this,
5345 iNoClone = l - 1,
5346 value = args[ 0 ],
5347 isFunction = jQuery.isFunction( value );
5348
5349 // We can't cloneNode fragments that contain checked, in WebKit
5350 if ( isFunction ||
5351 ( l > 1 && typeof value === "string" &&
5352 !support.checkClone && rchecked.test( value ) ) ) {
5353 return this.each(function( index ) {
5354 var self = set.eq( index );
5355 if ( isFunction ) {
5356 args[ 0 ] = value.call( this, index, self.html() );
5357 }
5358 self.domManip( args, callback );
5359 });
5360 }
5361
5362 if ( l ) {
5363 fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
5364 first = fragment.firstChild;
5365
5366 if ( fragment.childNodes.length === 1 ) {
5367 fragment = first;
5368 }
5369
5370 if ( first ) {
5371 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5372 hasScripts = scripts.length;
5373
5374 // Use the original fragment for the last item instead of the first because it can end up
5375 // being emptied incorrectly in certain situations (#8070).
5376 for ( ; i < l; i++ ) {
5377 node = fragment;
5378
5379 if ( i !== iNoClone ) {
5380 node = jQuery.clone( node, true, true );
5381
5382 // Keep references to cloned scripts for later restoration
5383 if ( hasScripts ) {
5384 // Support: QtWebKit
5385 // jQuery.merge because push.apply(_, arraylike) throws
5386 jQuery.merge( scripts, getAll( node, "script" ) );
5387 }
5388 }
5389
5390 callback.call( this[ i ], node, i );
5391 }
5392
5393 if ( hasScripts ) {
5394 doc = scripts[ scripts.length - 1 ].ownerDocument;
5395
5396 // Reenable scripts
5397 jQuery.map( scripts, restoreScript );
5398
5399 // Evaluate executable scripts on first document insertion
5400 for ( i = 0; i < hasScripts; i++ ) {
5401 node = scripts[ i ];
5402 if ( rscriptType.test( node.type || "" ) &&
5403 !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5404
5405 if ( node.src ) {
5406 // Optional AJAX dependency, but won't run scripts if not present
5407 if ( jQuery._evalUrl ) {
5408 jQuery._evalUrl( node.src );
5409 }
5410 } else {
5411 jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5412 }
5413 }
5414 }
5415 }
5416 }
5417 }
5418
5419 return this;
5420 }
5421});
5422
5423jQuery.each({
5424 appendTo: "append",
5425 prependTo: "prepend",
5426 insertBefore: "before",
5427 insertAfter: "after",
5428 replaceAll: "replaceWith"
5429}, function( name, original ) {
5430 jQuery.fn[ name ] = function( selector ) {
5431 var elems,
5432 ret = [],
5433 insert = jQuery( selector ),
5434 last = insert.length - 1,
5435 i = 0;
5436
5437 for ( ; i <= last; i++ ) {
5438 elems = i === last ? this : this.clone( true );
5439 jQuery( insert[ i ] )[ original ]( elems );
5440
5441 // Support: QtWebKit
5442 // .get() because push.apply(_, arraylike) throws
5443 push.apply( ret, elems.get() );
5444 }
5445
5446 return this.pushStack( ret );
5447 };
5448});
5449
5450
5451var iframe,
5452 elemdisplay = {};
5453
5454/**
5455 * Retrieve the actual display of a element
5456 * @param {String} name nodeName of the element
5457 * @param {Object} doc Document object
5458 */
5459// Called only from within defaultDisplay
5460function actualDisplay( name, doc ) {
5461 var style,
5462 elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5463
5464 // getDefaultComputedStyle might be reliably used only on attached element
5465 display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
5466
5467 // Use of this method is a temporary fix (more like optmization) until something better comes along,
5468 // since it was removed from specification and supported only in FF
5469 style.display : jQuery.css( elem[ 0 ], "display" );
5470
5471 // We don't have any data stored on the element,
5472 // so use "detach" method as fast way to get rid of the element
5473 elem.detach();
5474
5475 return display;
5476}
5477
5478/**
5479 * Try to determine the default display value of an element
5480 * @param {String} nodeName
5481 */
5482function defaultDisplay( nodeName ) {
5483 var doc = document,
5484 display = elemdisplay[ nodeName ];
5485
5486 if ( !display ) {
5487 display = actualDisplay( nodeName, doc );
5488
5489 // If the simple way fails, read from inside an iframe
5490 if ( display === "none" || !display ) {
5491
5492 // Use the already-created iframe if possible
5493 iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
5494
5495 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5496 doc = iframe[ 0 ].contentDocument;
5497
5498 // Support: IE
5499 doc.write();
5500 doc.close();
5501
5502 display = actualDisplay( nodeName, doc );
5503 iframe.detach();
5504 }
5505
5506 // Store the correct default display
5507 elemdisplay[ nodeName ] = display;
5508 }
5509
5510 return display;
5511}
5512var rmargin = (/^margin/);
5513
5514var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5515
5516var getStyles = function( elem ) {
5517 return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
5518 };
5519
5520
5521
5522function curCSS( elem, name, computed ) {
5523 var width, minWidth, maxWidth, ret,
5524 style = elem.style;
5525
5526 computed = computed || getStyles( elem );
5527
5528 // Support: IE9
5529 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
5530 if ( computed ) {
5531 ret = computed.getPropertyValue( name ) || computed[ name ];
5532 }
5533
5534 if ( computed ) {
5535
5536 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
5537 ret = jQuery.style( elem, name );
5538 }
5539
5540 // Support: iOS < 6
5541 // A tribute to the "awesome hack by Dean Edwards"
5542 // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
5543 // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
5544 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
5545
5546 // Remember the original values
5547 width = style.width;
5548 minWidth = style.minWidth;
5549 maxWidth = style.maxWidth;
5550
5551 // Put in the new values to get a computed value out
5552 style.minWidth = style.maxWidth = style.width = ret;
5553 ret = computed.width;
5554
5555 // Revert the changed values
5556 style.width = width;
5557 style.minWidth = minWidth;
5558 style.maxWidth = maxWidth;
5559 }
5560 }
5561
5562 return ret !== undefined ?
5563 // Support: IE
5564 // IE returns zIndex value as an integer.
5565 ret + "" :
5566 ret;
5567}
5568
5569
5570function addGetHookIf( conditionFn, hookFn ) {
5571 // Define the hook, we'll check on the first run if it's really needed.
5572 return {
5573 get: function() {
5574 if ( conditionFn() ) {
5575 // Hook not needed (or it's not possible to use it due to missing dependency),
5576 // remove it.
5577 // Since there are no other hooks for marginRight, remove the whole object.
5578 delete this.get;
5579 return;
5580 }
5581
5582 // Hook needed; redefine it so that the support test is not executed again.
5583
5584 return (this.get = hookFn).apply( this, arguments );
5585 }
5586 };
5587}
5588
5589
5590(function() {
5591 var pixelPositionVal, boxSizingReliableVal,
5592 docElem = document.documentElement,
5593 container = document.createElement( "div" ),
5594 div = document.createElement( "div" );
5595
5596 if ( !div.style ) {
5597 return;
5598 }
5599
5600 div.style.backgroundClip = "content-box";
5601 div.cloneNode( true ).style.backgroundClip = "";
5602 support.clearCloneStyle = div.style.backgroundClip === "content-box";
5603
5604 container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
5605 "position:absolute";
5606 container.appendChild( div );
5607
5608 // Executing both pixelPosition & boxSizingReliable tests require only one layout
5609 // so they're executed at the same time to save the second computation.
5610 function computePixelPositionAndBoxSizingReliable() {
5611 div.style.cssText =
5612 // Support: Firefox<29, Android 2.3
5613 // Vendor-prefix box-sizing
5614 "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
5615 "box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
5616 "border:1px;padding:1px;width:4px;position:absolute";
5617 div.innerHTML = "";
5618 docElem.appendChild( container );
5619
5620 var divStyle = window.getComputedStyle( div, null );
5621 pixelPositionVal = divStyle.top !== "1%";
5622 boxSizingReliableVal = divStyle.width === "4px";
5623
5624 docElem.removeChild( container );
5625 }
5626
5627 // Support: node.js jsdom
5628 // Don't assume that getComputedStyle is a property of the global object
5629 if ( window.getComputedStyle ) {
5630 jQuery.extend( support, {
5631 pixelPosition: function() {
5632 // This test is executed only once but we still do memoizing
5633 // since we can use the boxSizingReliable pre-computing.
5634 // No need to check if the test was already performed, though.
5635 computePixelPositionAndBoxSizingReliable();
5636 return pixelPositionVal;
5637 },
5638 boxSizingReliable: function() {
5639 if ( boxSizingReliableVal == null ) {
5640 computePixelPositionAndBoxSizingReliable();
5641 }
5642 return boxSizingReliableVal;
5643 },
5644 reliableMarginRight: function() {
5645 // Support: Android 2.3
5646 // Check if div with explicit width and no margin-right incorrectly
5647 // gets computed margin-right based on width of container. (#3333)
5648 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
5649 // This support function is only executed once so no memoizing is needed.
5650 var ret,
5651 marginDiv = div.appendChild( document.createElement( "div" ) );
5652
5653 // Reset CSS: box-sizing; display; margin; border; padding
5654 marginDiv.style.cssText = div.style.cssText =
5655 // Support: Firefox<29, Android 2.3
5656 // Vendor-prefix box-sizing
5657 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
5658 "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
5659 marginDiv.style.marginRight = marginDiv.style.width = "0";
5660 div.style.width = "1px";
5661 docElem.appendChild( container );
5662
5663 ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
5664
5665 docElem.removeChild( container );
5666
5667 return ret;
5668 }
5669 });
5670 }
5671})();
5672
5673
5674// A method for quickly swapping in/out CSS properties to get correct calculations.
5675jQuery.swap = function( elem, options, callback, args ) {
5676 var ret, name,
5677 old = {};
5678
5679 // Remember the old values, and insert the new ones
5680 for ( name in options ) {
5681 old[ name ] = elem.style[ name ];
5682 elem.style[ name ] = options[ name ];
5683 }
5684
5685 ret = callback.apply( elem, args || [] );
5686
5687 // Revert the old values
5688 for ( name in options ) {
5689 elem.style[ name ] = old[ name ];
5690 }
5691
5692 return ret;
5693};
5694
5695
5696var
5697 // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
5698 // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5699 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5700 rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
5701 rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
5702
5703 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5704 cssNormalTransform = {
5705 letterSpacing: "0",
5706 fontWeight: "400"
5707 },
5708
5709 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
5710
5711// return a css property mapped to a potentially vendor prefixed property
5712function vendorPropName( style, name ) {
5713
5714 // shortcut for names that are not vendor prefixed
5715 if ( name in style ) {
5716 return name;
5717 }
5718
5719 // check for vendor prefixed names
5720 var capName = name[0].toUpperCase() + name.slice(1),
5721 origName = name,
5722 i = cssPrefixes.length;
5723
5724 while ( i-- ) {
5725 name = cssPrefixes[ i ] + capName;
5726 if ( name in style ) {
5727 return name;
5728 }
5729 }
5730
5731 return origName;
5732}
5733
5734function setPositiveNumber( elem, value, subtract ) {
5735 var matches = rnumsplit.exec( value );
5736 return matches ?
5737 // Guard against undefined "subtract", e.g., when used as in cssHooks
5738 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
5739 value;
5740}
5741
5742function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
5743 var i = extra === ( isBorderBox ? "border" : "content" ) ?
5744 // If we already have the right measurement, avoid augmentation
5745 4 :
5746 // Otherwise initialize for horizontal or vertical properties
5747 name === "width" ? 1 : 0,
5748
5749 val = 0;
5750
5751 for ( ; i < 4; i += 2 ) {
5752 // both box models exclude margin, so add it if we want it
5753 if ( extra === "margin" ) {
5754 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
5755 }
5756
5757 if ( isBorderBox ) {
5758 // border-box includes padding, so remove it if we want content
5759 if ( extra === "content" ) {
5760 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5761 }
5762
5763 // at this point, extra isn't border nor margin, so remove border
5764 if ( extra !== "margin" ) {
5765 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5766 }
5767 } else {
5768 // at this point, extra isn't content, so add padding
5769 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5770
5771 // at this point, extra isn't content nor padding, so add border
5772 if ( extra !== "padding" ) {
5773 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5774 }
5775 }
5776 }
5777
5778 return val;
5779}
5780
5781function getWidthOrHeight( elem, name, extra ) {
5782
5783 // Start with offset property, which is equivalent to the border-box value
5784 var valueIsBorderBox = true,
5785 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
5786 styles = getStyles( elem ),
5787 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
5788
5789 // some non-html elements return undefined for offsetWidth, so check for null/undefined
5790 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
5791 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
5792 if ( val <= 0 || val == null ) {
5793 // Fall back to computed then uncomputed css if necessary
5794 val = curCSS( elem, name, styles );
5795 if ( val < 0 || val == null ) {
5796 val = elem.style[ name ];
5797 }
5798
5799 // Computed unit is not pixels. Stop here and return.
5800 if ( rnumnonpx.test(val) ) {
5801 return val;
5802 }
5803
5804 // we need the check for style in case a browser which returns unreliable values
5805 // for getComputedStyle silently falls back to the reliable elem.style
5806 valueIsBorderBox = isBorderBox &&
5807 ( support.boxSizingReliable() || val === elem.style[ name ] );
5808
5809 // Normalize "", auto, and prepare for extra
5810 val = parseFloat( val ) || 0;
5811 }
5812
5813 // use the active box-sizing model to add/subtract irrelevant styles
5814 return ( val +
5815 augmentWidthOrHeight(
5816 elem,
5817 name,
5818 extra || ( isBorderBox ? "border" : "content" ),
5819 valueIsBorderBox,
5820 styles
5821 )
5822 ) + "px";
5823}
5824
5825function showHide( elements, show ) {
5826 var display, elem, hidden,
5827 values = [],
5828 index = 0,
5829 length = elements.length;
5830
5831 for ( ; index < length; index++ ) {
5832 elem = elements[ index ];
5833 if ( !elem.style ) {
5834 continue;
5835 }
5836
5837 values[ index ] = data_priv.get( elem, "olddisplay" );
5838 display = elem.style.display;
5839 if ( show ) {
5840 // Reset the inline display of this element to learn if it is
5841 // being hidden by cascaded rules or not
5842 if ( !values[ index ] && display === "none" ) {
5843 elem.style.display = "";
5844 }
5845
5846 // Set elements which have been overridden with display: none
5847 // in a stylesheet to whatever the default browser style is
5848 // for such an element
5849 if ( elem.style.display === "" && isHidden( elem ) ) {
5850 values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
5851 }
5852 } else {
5853 hidden = isHidden( elem );
5854
5855 if ( display !== "none" || !hidden ) {
5856 data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
5857 }
5858 }
5859 }
5860
5861 // Set the display of most of the elements in a second loop
5862 // to avoid the constant reflow
5863 for ( index = 0; index < length; index++ ) {
5864 elem = elements[ index ];
5865 if ( !elem.style ) {
5866 continue;
5867 }
5868 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
5869 elem.style.display = show ? values[ index ] || "" : "none";
5870 }
5871 }
5872
5873 return elements;
5874}
5875
5876jQuery.extend({
5877 // Add in style property hooks for overriding the default
5878 // behavior of getting and setting a style property
5879 cssHooks: {
5880 opacity: {
5881 get: function( elem, computed ) {
5882 if ( computed ) {
5883 // We should always get a number back from opacity
5884 var ret = curCSS( elem, "opacity" );
5885 return ret === "" ? "1" : ret;
5886 }
5887 }
5888 }
5889 },
5890
5891 // Don't automatically add "px" to these possibly-unitless properties
5892 cssNumber: {
5893 "columnCount": true,
5894 "fillOpacity": true,
5895 "flexGrow": true,
5896 "flexShrink": true,
5897 "fontWeight": true,
5898 "lineHeight": true,
5899 "opacity": true,
5900 "order": true,
5901 "orphans": true,
5902 "widows": true,
5903 "zIndex": true,
5904 "zoom": true
5905 },
5906
5907 // Add in properties whose names you wish to fix before
5908 // setting or getting the value
5909 cssProps: {
5910 // normalize float css property
5911 "float": "cssFloat"
5912 },
5913
5914 // Get and set the style property on a DOM Node
5915 style: function( elem, name, value, extra ) {
5916 // Don't set styles on text and comment nodes
5917 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5918 return;
5919 }
5920
5921 // Make sure that we're working with the right name
5922 var ret, type, hooks,
5923 origName = jQuery.camelCase( name ),
5924 style = elem.style;
5925
5926 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
5927
5928 // gets hook for the prefixed version
5929 // followed by the unprefixed version
5930 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
5931
5932 // Check if we're setting a value
5933 if ( value !== undefined ) {
5934 type = typeof value;
5935
5936 // convert relative number strings (+= or -=) to relative numbers. #7345
5937 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
5938 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
5939 // Fixes bug #9237
5940 type = "number";
5941 }
5942
5943 // Make sure that null and NaN values aren't set. See: #7116
5944 if ( value == null || value !== value ) {
5945 return;
5946 }
5947
5948 // If a number was passed in, add 'px' to the (except for certain CSS properties)
5949 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
5950 value += "px";
5951 }
5952
5953 // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
5954 // but it would mean to define eight (for every problematic property) identical functions
5955 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
5956 style[ name ] = "inherit";
5957 }
5958
5959 // If a hook was provided, use that value, otherwise just set the specified value
5960 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
5961 style[ name ] = value;
5962 }
5963
5964 } else {
5965 // If a hook was provided get the non-computed value from there
5966 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
5967 return ret;
5968 }
5969
5970 // Otherwise just get the value from the style object
5971 return style[ name ];
5972 }
5973 },
5974
5975 css: function( elem, name, extra, styles ) {
5976 var val, num, hooks,
5977 origName = jQuery.camelCase( name );
5978
5979 // Make sure that we're working with the right name
5980 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
5981
5982 // gets hook for the prefixed version
5983 // followed by the unprefixed version
5984 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
5985
5986 // If a hook was provided get the computed value from there
5987 if ( hooks && "get" in hooks ) {
5988 val = hooks.get( elem, true, extra );
5989 }
5990
5991 // Otherwise, if a way to get the computed value exists, use that
5992 if ( val === undefined ) {
5993 val = curCSS( elem, name, styles );
5994 }
5995
5996 //convert "normal" to computed value
5997 if ( val === "normal" && name in cssNormalTransform ) {
5998 val = cssNormalTransform[ name ];
5999 }
6000
6001 // Return, converting to number if forced or a qualifier was provided and val looks numeric
6002 if ( extra === "" || extra ) {
6003 num = parseFloat( val );
6004 return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6005 }
6006 return val;
6007 }
6008});
6009
6010jQuery.each([ "height", "width" ], function( i, name ) {
6011 jQuery.cssHooks[ name ] = {
6012 get: function( elem, computed, extra ) {
6013 if ( computed ) {
6014 // certain elements can have dimension info if we invisibly show them
6015 // however, it must have a current display style that would benefit from this
6016 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
6017 jQuery.swap( elem, cssShow, function() {
6018 return getWidthOrHeight( elem, name, extra );
6019 }) :
6020 getWidthOrHeight( elem, name, extra );
6021 }
6022 },
6023
6024 set: function( elem, value, extra ) {
6025 var styles = extra && getStyles( elem );
6026 return setPositiveNumber( elem, value, extra ?
6027 augmentWidthOrHeight(
6028 elem,
6029 name,
6030 extra,
6031 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6032 styles
6033 ) : 0
6034 );
6035 }
6036 };
6037});
6038
6039// Support: Android 2.3
6040jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6041 function( elem, computed ) {
6042 if ( computed ) {
6043 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6044 // Work around by temporarily setting element display to inline-block
6045 return jQuery.swap( elem, { "display": "inline-block" },
6046 curCSS, [ elem, "marginRight" ] );
6047 }
6048 }
6049);
6050
6051// These hooks are used by animate to expand properties
6052jQuery.each({
6053 margin: "",
6054 padding: "",
6055 border: "Width"
6056}, function( prefix, suffix ) {
6057 jQuery.cssHooks[ prefix + suffix ] = {
6058 expand: function( value ) {
6059 var i = 0,
6060 expanded = {},
6061
6062 // assumes a single number if not a string
6063 parts = typeof value === "string" ? value.split(" ") : [ value ];
6064
6065 for ( ; i < 4; i++ ) {
6066 expanded[ prefix + cssExpand[ i ] + suffix ] =
6067 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6068 }
6069
6070 return expanded;
6071 }
6072 };
6073
6074 if ( !rmargin.test( prefix ) ) {
6075 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6076 }
6077});
6078
6079jQuery.fn.extend({
6080 css: function( name, value ) {
6081 return access( this, function( elem, name, value ) {
6082 var styles, len,
6083 map = {},
6084 i = 0;
6085
6086 if ( jQuery.isArray( name ) ) {
6087 styles = getStyles( elem );
6088 len = name.length;
6089
6090 for ( ; i < len; i++ ) {
6091 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6092 }
6093
6094 return map;
6095 }
6096
6097 return value !== undefined ?
6098 jQuery.style( elem, name, value ) :
6099 jQuery.css( elem, name );
6100 }, name, value, arguments.length > 1 );
6101 },
6102 show: function() {
6103 return showHide( this, true );
6104 },
6105 hide: function() {
6106 return showHide( this );
6107 },
6108 toggle: function( state ) {
6109 if ( typeof state === "boolean" ) {
6110 return state ? this.show() : this.hide();
6111 }
6112
6113 return this.each(function() {
6114 if ( isHidden( this ) ) {
6115 jQuery( this ).show();
6116 } else {
6117 jQuery( this ).hide();
6118 }
6119 });
6120 }
6121});
6122
6123
6124function Tween( elem, options, prop, end, easing ) {
6125 return new Tween.prototype.init( elem, options, prop, end, easing );
6126}
6127jQuery.Tween = Tween;
6128
6129Tween.prototype = {
6130 constructor: Tween,
6131 init: function( elem, options, prop, end, easing, unit ) {
6132 this.elem = elem;
6133 this.prop = prop;
6134 this.easing = easing || "swing";
6135 this.options = options;
6136 this.start = this.now = this.cur();
6137 this.end = end;
6138 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6139 },
6140 cur: function() {
6141 var hooks = Tween.propHooks[ this.prop ];
6142
6143 return hooks && hooks.get ?
6144 hooks.get( this ) :
6145 Tween.propHooks._default.get( this );
6146 },
6147 run: function( percent ) {
6148 var eased,
6149 hooks = Tween.propHooks[ this.prop ];
6150
6151 if ( this.options.duration ) {
6152 this.pos = eased = jQuery.easing[ this.easing ](
6153 percent, this.options.duration * percent, 0, 1, this.options.duration
6154 );
6155 } else {
6156 this.pos = eased = percent;
6157 }
6158 this.now = ( this.end - this.start ) * eased + this.start;
6159
6160 if ( this.options.step ) {
6161 this.options.step.call( this.elem, this.now, this );
6162 }
6163
6164 if ( hooks && hooks.set ) {
6165 hooks.set( this );
6166 } else {
6167 Tween.propHooks._default.set( this );
6168 }
6169 return this;
6170 }
6171};
6172
6173Tween.prototype.init.prototype = Tween.prototype;
6174
6175Tween.propHooks = {
6176 _default: {
6177 get: function( tween ) {
6178 var result;
6179
6180 if ( tween.elem[ tween.prop ] != null &&
6181 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
6182 return tween.elem[ tween.prop ];
6183 }
6184
6185 // passing an empty string as a 3rd parameter to .css will automatically
6186 // attempt a parseFloat and fallback to a string if the parse fails
6187 // so, simple values such as "10px" are parsed to Float.
6188 // complex values such as "rotate(1rad)" are returned as is.
6189 result = jQuery.css( tween.elem, tween.prop, "" );
6190 // Empty strings, null, undefined and "auto" are converted to 0.
6191 return !result || result === "auto" ? 0 : result;
6192 },
6193 set: function( tween ) {
6194 // use step hook for back compat - use cssHook if its there - use .style if its
6195 // available and use plain properties where available
6196 if ( jQuery.fx.step[ tween.prop ] ) {
6197 jQuery.fx.step[ tween.prop ]( tween );
6198 } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
6199 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6200 } else {
6201 tween.elem[ tween.prop ] = tween.now;
6202 }
6203 }
6204 }
6205};
6206
6207// Support: IE9
6208// Panic based approach to setting things on disconnected nodes
6209
6210Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6211 set: function( tween ) {
6212 if ( tween.elem.nodeType && tween.elem.parentNode ) {
6213 tween.elem[ tween.prop ] = tween.now;
6214 }
6215 }
6216};
6217
6218jQuery.easing = {
6219 linear: function( p ) {
6220 return p;
6221 },
6222 swing: function( p ) {
6223 return 0.5 - Math.cos( p * Math.PI ) / 2;
6224 }
6225};
6226
6227jQuery.fx = Tween.prototype.init;
6228
6229// Back Compat <1.8 extension point
6230jQuery.fx.step = {};
6231
6232
6233
6234
6235var
6236 fxNow, timerId,
6237 rfxtypes = /^(?:toggle|show|hide)$/,
6238 rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
6239 rrun = /queueHooks$/,
6240 animationPrefilters = [ defaultPrefilter ],
6241 tweeners = {
6242 "*": [ function( prop, value ) {
6243 var tween = this.createTween( prop, value ),
6244 target = tween.cur(),
6245 parts = rfxnum.exec( value ),
6246 unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
6247
6248 // Starting value computation is required for potential unit mismatches
6249 start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
6250 rfxnum.exec( jQuery.css( tween.elem, prop ) ),
6251 scale = 1,
6252 maxIterations = 20;
6253
6254 if ( start && start[ 3 ] !== unit ) {
6255 // Trust units reported by jQuery.css
6256 unit = unit || start[ 3 ];
6257
6258 // Make sure we update the tween properties later on
6259 parts = parts || [];
6260
6261 // Iteratively approximate from a nonzero starting point
6262 start = +target || 1;
6263
6264 do {
6265 // If previous iteration zeroed out, double until we get *something*
6266 // Use a string for doubling factor so we don't accidentally see scale as unchanged below
6267 scale = scale || ".5";
6268
6269 // Adjust and apply
6270 start = start / scale;
6271 jQuery.style( tween.elem, prop, start + unit );
6272
6273 // Update scale, tolerating zero or NaN from tween.cur()
6274 // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
6275 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
6276 }
6277
6278 // Update tween properties
6279 if ( parts ) {
6280 start = tween.start = +start || +target || 0;
6281 tween.unit = unit;
6282 // If a +=/-= token was provided, we're doing a relative animation
6283 tween.end = parts[ 1 ] ?
6284 start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
6285 +parts[ 2 ];
6286 }
6287
6288 return tween;
6289 } ]
6290 };
6291
6292// Animations created synchronously will run synchronously
6293function createFxNow() {
6294 setTimeout(function() {
6295 fxNow = undefined;
6296 });
6297 return ( fxNow = jQuery.now() );
6298}
6299
6300// Generate parameters to create a standard animation
6301function genFx( type, includeWidth ) {
6302 var which,
6303 i = 0,
6304 attrs = { height: type };
6305
6306 // if we include width, step value is 1 to do all cssExpand values,
6307 // if we don't include width, step value is 2 to skip over Left and Right
6308 includeWidth = includeWidth ? 1 : 0;
6309 for ( ; i < 4 ; i += 2 - includeWidth ) {
6310 which = cssExpand[ i ];
6311 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6312 }
6313
6314 if ( includeWidth ) {
6315 attrs.opacity = attrs.width = type;
6316 }
6317
6318 return attrs;
6319}
6320
6321function createTween( value, prop, animation ) {
6322 var tween,
6323 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
6324 index = 0,
6325 length = collection.length;
6326 for ( ; index < length; index++ ) {
6327 if ( (tween = collection[ index ].call( animation, prop, value )) ) {
6328
6329 // we're done with this property
6330 return tween;
6331 }
6332 }
6333}
6334
6335function defaultPrefilter( elem, props, opts ) {
6336 /* jshint validthis: true */
6337 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6338 anim = this,
6339 orig = {},
6340 style = elem.style,
6341 hidden = elem.nodeType && isHidden( elem ),
6342 dataShow = data_priv.get( elem, "fxshow" );
6343
6344 // handle queue: false promises
6345 if ( !opts.queue ) {
6346 hooks = jQuery._queueHooks( elem, "fx" );
6347 if ( hooks.unqueued == null ) {
6348 hooks.unqueued = 0;
6349 oldfire = hooks.empty.fire;
6350 hooks.empty.fire = function() {
6351 if ( !hooks.unqueued ) {
6352 oldfire();
6353 }
6354 };
6355 }
6356 hooks.unqueued++;
6357
6358 anim.always(function() {
6359 // doing this makes sure that the complete handler will be called
6360 // before this completes
6361 anim.always(function() {
6362 hooks.unqueued--;
6363 if ( !jQuery.queue( elem, "fx" ).length ) {
6364 hooks.empty.fire();
6365 }
6366 });
6367 });
6368 }
6369
6370 // height/width overflow pass
6371 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6372 // Make sure that nothing sneaks out
6373 // Record all 3 overflow attributes because IE9-10 do not
6374 // change the overflow attribute when overflowX and
6375 // overflowY are set to the same value
6376 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6377
6378 // Set display property to inline-block for height/width
6379 // animations on inline elements that are having width/height animated
6380 display = jQuery.css( elem, "display" );
6381
6382 // Test default display if display is currently "none"
6383 checkDisplay = display === "none" ?
6384 data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6385
6386 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6387 style.display = "inline-block";
6388 }
6389 }
6390
6391 if ( opts.overflow ) {
6392 style.overflow = "hidden";
6393 anim.always(function() {
6394 style.overflow = opts.overflow[ 0 ];
6395 style.overflowX = opts.overflow[ 1 ];
6396 style.overflowY = opts.overflow[ 2 ];
6397 });
6398 }
6399
6400 // show/hide pass
6401 for ( prop in props ) {
6402 value = props[ prop ];
6403 if ( rfxtypes.exec( value ) ) {
6404 delete props[ prop ];
6405 toggle = toggle || value === "toggle";
6406 if ( value === ( hidden ? "hide" : "show" ) ) {
6407
6408 // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
6409 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6410 hidden = true;
6411 } else {
6412 continue;
6413 }
6414 }
6415 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6416
6417 // Any non-fx value stops us from restoring the original display value
6418 } else {
6419 display = undefined;
6420 }
6421 }
6422
6423 if ( !jQuery.isEmptyObject( orig ) ) {
6424 if ( dataShow ) {
6425 if ( "hidden" in dataShow ) {
6426 hidden = dataShow.hidden;
6427 }
6428 } else {
6429 dataShow = data_priv.access( elem, "fxshow", {} );
6430 }
6431
6432 // store state if its toggle - enables .stop().toggle() to "reverse"
6433 if ( toggle ) {
6434 dataShow.hidden = !hidden;
6435 }
6436 if ( hidden ) {
6437 jQuery( elem ).show();
6438 } else {
6439 anim.done(function() {
6440 jQuery( elem ).hide();
6441 });
6442 }
6443 anim.done(function() {
6444 var prop;
6445
6446 data_priv.remove( elem, "fxshow" );
6447 for ( prop in orig ) {
6448 jQuery.style( elem, prop, orig[ prop ] );
6449 }
6450 });
6451 for ( prop in orig ) {
6452 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6453
6454 if ( !( prop in dataShow ) ) {
6455 dataShow[ prop ] = tween.start;
6456 if ( hidden ) {
6457 tween.end = tween.start;
6458 tween.start = prop === "width" || prop === "height" ? 1 : 0;
6459 }
6460 }
6461 }
6462
6463 // If this is a noop like .hide().hide(), restore an overwritten display value
6464 } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
6465 style.display = display;
6466 }
6467}
6468
6469function propFilter( props, specialEasing ) {
6470 var index, name, easing, value, hooks;
6471
6472 // camelCase, specialEasing and expand cssHook pass
6473 for ( index in props ) {
6474 name = jQuery.camelCase( index );
6475 easing = specialEasing[ name ];
6476 value = props[ index ];
6477 if ( jQuery.isArray( value ) ) {
6478 easing = value[ 1 ];
6479 value = props[ index ] = value[ 0 ];
6480 }
6481
6482 if ( index !== name ) {
6483 props[ name ] = value;
6484 delete props[ index ];
6485 }
6486
6487 hooks = jQuery.cssHooks[ name ];
6488 if ( hooks && "expand" in hooks ) {
6489 value = hooks.expand( value );
6490 delete props[ name ];
6491
6492 // not quite $.extend, this wont overwrite keys already present.
6493 // also - reusing 'index' from above because we have the correct "name"
6494 for ( index in value ) {
6495 if ( !( index in props ) ) {
6496 props[ index ] = value[ index ];
6497 specialEasing[ index ] = easing;
6498 }
6499 }
6500 } else {
6501 specialEasing[ name ] = easing;
6502 }
6503 }
6504}
6505
6506function Animation( elem, properties, options ) {
6507 var result,
6508 stopped,
6509 index = 0,
6510 length = animationPrefilters.length,
6511 deferred = jQuery.Deferred().always( function() {
6512 // don't match elem in the :animated selector
6513 delete tick.elem;
6514 }),
6515 tick = function() {
6516 if ( stopped ) {
6517 return false;
6518 }
6519 var currentTime = fxNow || createFxNow(),
6520 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
6521 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
6522 temp = remaining / animation.duration || 0,
6523 percent = 1 - temp,
6524 index = 0,
6525 length = animation.tweens.length;
6526
6527 for ( ; index < length ; index++ ) {
6528 animation.tweens[ index ].run( percent );
6529 }
6530
6531 deferred.notifyWith( elem, [ animation, percent, remaining ]);
6532
6533 if ( percent < 1 && length ) {
6534 return remaining;
6535 } else {
6536 deferred.resolveWith( elem, [ animation ] );
6537 return false;
6538 }
6539 },
6540 animation = deferred.promise({
6541 elem: elem,
6542 props: jQuery.extend( {}, properties ),
6543 opts: jQuery.extend( true, { specialEasing: {} }, options ),
6544 originalProperties: properties,
6545 originalOptions: options,
6546 startTime: fxNow || createFxNow(),
6547 duration: options.duration,
6548 tweens: [],
6549 createTween: function( prop, end ) {
6550 var tween = jQuery.Tween( elem, animation.opts, prop, end,
6551 animation.opts.specialEasing[ prop ] || animation.opts.easing );
6552 animation.tweens.push( tween );
6553 return tween;
6554 },
6555 stop: function( gotoEnd ) {
6556 var index = 0,
6557 // if we are going to the end, we want to run all the tweens
6558 // otherwise we skip this part
6559 length = gotoEnd ? animation.tweens.length : 0;
6560 if ( stopped ) {
6561 return this;
6562 }
6563 stopped = true;
6564 for ( ; index < length ; index++ ) {
6565 animation.tweens[ index ].run( 1 );
6566 }
6567
6568 // resolve when we played the last frame
6569 // otherwise, reject
6570 if ( gotoEnd ) {
6571 deferred.resolveWith( elem, [ animation, gotoEnd ] );
6572 } else {
6573 deferred.rejectWith( elem, [ animation, gotoEnd ] );
6574 }
6575 return this;
6576 }
6577 }),
6578 props = animation.props;
6579
6580 propFilter( props, animation.opts.specialEasing );
6581
6582 for ( ; index < length ; index++ ) {
6583 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
6584 if ( result ) {
6585 return result;
6586 }
6587 }
6588
6589 jQuery.map( props, createTween, animation );
6590
6591 if ( jQuery.isFunction( animation.opts.start ) ) {
6592 animation.opts.start.call( elem, animation );
6593 }
6594
6595 jQuery.fx.timer(
6596 jQuery.extend( tick, {
6597 elem: elem,
6598 anim: animation,
6599 queue: animation.opts.queue
6600 })
6601 );
6602
6603 // attach callbacks from options
6604 return animation.progress( animation.opts.progress )
6605 .done( animation.opts.done, animation.opts.complete )
6606 .fail( animation.opts.fail )
6607 .always( animation.opts.always );
6608}
6609
6610jQuery.Animation = jQuery.extend( Animation, {
6611
6612 tweener: function( props, callback ) {
6613 if ( jQuery.isFunction( props ) ) {
6614 callback = props;
6615 props = [ "*" ];
6616 } else {
6617 props = props.split(" ");
6618 }
6619
6620 var prop,
6621 index = 0,
6622 length = props.length;
6623
6624 for ( ; index < length ; index++ ) {
6625 prop = props[ index ];
6626 tweeners[ prop ] = tweeners[ prop ] || [];
6627 tweeners[ prop ].unshift( callback );
6628 }
6629 },
6630
6631 prefilter: function( callback, prepend ) {
6632 if ( prepend ) {
6633 animationPrefilters.unshift( callback );
6634 } else {
6635 animationPrefilters.push( callback );
6636 }
6637 }
6638});
6639
6640jQuery.speed = function( speed, easing, fn ) {
6641 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
6642 complete: fn || !fn && easing ||
6643 jQuery.isFunction( speed ) && speed,
6644 duration: speed,
6645 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
6646 };
6647
6648 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6649 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
6650
6651 // normalize opt.queue - true/undefined/null -> "fx"
6652 if ( opt.queue == null || opt.queue === true ) {
6653 opt.queue = "fx";
6654 }
6655
6656 // Queueing
6657 opt.old = opt.complete;
6658
6659 opt.complete = function() {
6660 if ( jQuery.isFunction( opt.old ) ) {
6661 opt.old.call( this );
6662 }
6663
6664 if ( opt.queue ) {
6665 jQuery.dequeue( this, opt.queue );
6666 }
6667 };
6668
6669 return opt;
6670};
6671
6672jQuery.fn.extend({
6673 fadeTo: function( speed, to, easing, callback ) {
6674
6675 // show any hidden elements after setting opacity to 0
6676 return this.filter( isHidden ).css( "opacity", 0 ).show()
6677
6678 // animate to the value specified
6679 .end().animate({ opacity: to }, speed, easing, callback );
6680 },
6681 animate: function( prop, speed, easing, callback ) {
6682 var empty = jQuery.isEmptyObject( prop ),
6683 optall = jQuery.speed( speed, easing, callback ),
6684 doAnimation = function() {
6685 // Operate on a copy of prop so per-property easing won't be lost
6686 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
6687
6688 // Empty animations, or finishing resolves immediately
6689 if ( empty || data_priv.get( this, "finish" ) ) {
6690 anim.stop( true );
6691 }
6692 };
6693 doAnimation.finish = doAnimation;
6694
6695 return empty || optall.queue === false ?
6696 this.each( doAnimation ) :
6697 this.queue( optall.queue, doAnimation );
6698 },
6699 stop: function( type, clearQueue, gotoEnd ) {
6700 var stopQueue = function( hooks ) {
6701 var stop = hooks.stop;
6702 delete hooks.stop;
6703 stop( gotoEnd );
6704 };
6705
6706 if ( typeof type !== "string" ) {
6707 gotoEnd = clearQueue;
6708 clearQueue = type;
6709 type = undefined;
6710 }
6711 if ( clearQueue && type !== false ) {
6712 this.queue( type || "fx", [] );
6713 }
6714
6715 return this.each(function() {
6716 var dequeue = true,
6717 index = type != null && type + "queueHooks",
6718 timers = jQuery.timers,
6719 data = data_priv.get( this );
6720
6721 if ( index ) {
6722 if ( data[ index ] && data[ index ].stop ) {
6723 stopQueue( data[ index ] );
6724 }
6725 } else {
6726 for ( index in data ) {
6727 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
6728 stopQueue( data[ index ] );
6729 }
6730 }
6731 }
6732
6733 for ( index = timers.length; index--; ) {
6734 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
6735 timers[ index ].anim.stop( gotoEnd );
6736 dequeue = false;
6737 timers.splice( index, 1 );
6738 }
6739 }
6740
6741 // start the next in the queue if the last step wasn't forced
6742 // timers currently will call their complete callbacks, which will dequeue
6743 // but only if they were gotoEnd
6744 if ( dequeue || !gotoEnd ) {
6745 jQuery.dequeue( this, type );
6746 }
6747 });
6748 },
6749 finish: function( type ) {
6750 if ( type !== false ) {
6751 type = type || "fx";
6752 }
6753 return this.each(function() {
6754 var index,
6755 data = data_priv.get( this ),
6756 queue = data[ type + "queue" ],
6757 hooks = data[ type + "queueHooks" ],
6758 timers = jQuery.timers,
6759 length = queue ? queue.length : 0;
6760
6761 // enable finishing flag on private data
6762 data.finish = true;
6763
6764 // empty the queue first
6765 jQuery.queue( this, type, [] );
6766
6767 if ( hooks && hooks.stop ) {
6768 hooks.stop.call( this, true );
6769 }
6770
6771 // look for any active animations, and finish them
6772 for ( index = timers.length; index--; ) {
6773 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
6774 timers[ index ].anim.stop( true );
6775 timers.splice( index, 1 );
6776 }
6777 }
6778
6779 // look for any animations in the old queue and finish them
6780 for ( index = 0; index < length; index++ ) {
6781 if ( queue[ index ] && queue[ index ].finish ) {
6782 queue[ index ].finish.call( this );
6783 }
6784 }
6785
6786 // turn off finishing flag
6787 delete data.finish;
6788 });
6789 }
6790});
6791
6792jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
6793 var cssFn = jQuery.fn[ name ];
6794 jQuery.fn[ name ] = function( speed, easing, callback ) {
6795 return speed == null || typeof speed === "boolean" ?
6796 cssFn.apply( this, arguments ) :
6797 this.animate( genFx( name, true ), speed, easing, callback );
6798 };
6799});
6800
6801// Generate shortcuts for custom animations
6802jQuery.each({
6803 slideDown: genFx("show"),
6804 slideUp: genFx("hide"),
6805 slideToggle: genFx("toggle"),
6806 fadeIn: { opacity: "show" },
6807 fadeOut: { opacity: "hide" },
6808 fadeToggle: { opacity: "toggle" }
6809}, function( name, props ) {
6810 jQuery.fn[ name ] = function( speed, easing, callback ) {
6811 return this.animate( props, speed, easing, callback );
6812 };
6813});
6814
6815jQuery.timers = [];
6816jQuery.fx.tick = function() {
6817 var timer,
6818 i = 0,
6819 timers = jQuery.timers;
6820
6821 fxNow = jQuery.now();
6822
6823 for ( ; i < timers.length; i++ ) {
6824 timer = timers[ i ];
6825 // Checks the timer has not already been removed
6826 if ( !timer() && timers[ i ] === timer ) {
6827 timers.splice( i--, 1 );
6828 }
6829 }
6830
6831 if ( !timers.length ) {
6832 jQuery.fx.stop();
6833 }
6834 fxNow = undefined;
6835};
6836
6837jQuery.fx.timer = function( timer ) {
6838 jQuery.timers.push( timer );
6839 if ( timer() ) {
6840 jQuery.fx.start();
6841 } else {
6842 jQuery.timers.pop();
6843 }
6844};
6845
6846jQuery.fx.interval = 13;
6847
6848jQuery.fx.start = function() {
6849 if ( !timerId ) {
6850 timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
6851 }
6852};
6853
6854jQuery.fx.stop = function() {
6855 clearInterval( timerId );
6856 timerId = null;
6857};
6858
6859jQuery.fx.speeds = {
6860 slow: 600,
6861 fast: 200,
6862 // Default speed
6863 _default: 400
6864};
6865
6866
6867// Based off of the plugin by Clint Helfers, with permission.
6868// http://blindsignals.com/index.php/2009/07/jquery-delay/
6869jQuery.fn.delay = function( time, type ) {
6870 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
6871 type = type || "fx";
6872
6873 return this.queue( type, function( next, hooks ) {
6874 var timeout = setTimeout( next, time );
6875 hooks.stop = function() {
6876 clearTimeout( timeout );
6877 };
6878 });
6879};
6880
6881
6882(function() {
6883 var input = document.createElement( "input" ),
6884 select = document.createElement( "select" ),
6885 opt = select.appendChild( document.createElement( "option" ) );
6886
6887 input.type = "checkbox";
6888
6889 // Support: iOS 5.1, Android 4.x, Android 2.3
6890 // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
6891 support.checkOn = input.value !== "";
6892
6893 // Must access the parent to make an option select properly
6894 // Support: IE9, IE10
6895 support.optSelected = opt.selected;
6896
6897 // Make sure that the options inside disabled selects aren't marked as disabled
6898 // (WebKit marks them as disabled)
6899 select.disabled = true;
6900 support.optDisabled = !opt.disabled;
6901
6902 // Check if an input maintains its value after becoming a radio
6903 // Support: IE9, IE10
6904 input = document.createElement( "input" );
6905 input.value = "t";
6906 input.type = "radio";
6907 support.radioValue = input.value === "t";
6908})();
6909
6910
6911var nodeHook, boolHook,
6912 attrHandle = jQuery.expr.attrHandle;
6913
6914jQuery.fn.extend({
6915 attr: function( name, value ) {
6916 return access( this, jQuery.attr, name, value, arguments.length > 1 );
6917 },
6918
6919 removeAttr: function( name ) {
6920 return this.each(function() {
6921 jQuery.removeAttr( this, name );
6922 });
6923 }
6924});
6925
6926jQuery.extend({
6927 attr: function( elem, name, value ) {
6928 var hooks, ret,
6929 nType = elem.nodeType;
6930
6931 // don't get/set attributes on text, comment and attribute nodes
6932 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
6933 return;
6934 }
6935
6936 // Fallback to prop when attributes are not supported
6937 if ( typeof elem.getAttribute === strundefined ) {
6938 return jQuery.prop( elem, name, value );
6939 }
6940
6941 // All attributes are lowercase
6942 // Grab necessary hook if one is defined
6943 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
6944 name = name.toLowerCase();
6945 hooks = jQuery.attrHooks[ name ] ||
6946 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
6947 }
6948
6949 if ( value !== undefined ) {
6950
6951 if ( value === null ) {
6952 jQuery.removeAttr( elem, name );
6953
6954 } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
6955 return ret;
6956
6957 } else {
6958 elem.setAttribute( name, value + "" );
6959 return value;
6960 }
6961
6962 } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
6963 return ret;
6964
6965 } else {
6966 ret = jQuery.find.attr( elem, name );
6967
6968 // Non-existent attributes return null, we normalize to undefined
6969 return ret == null ?
6970 undefined :
6971 ret;
6972 }
6973 },
6974
6975 removeAttr: function( elem, value ) {
6976 var name, propName,
6977 i = 0,
6978 attrNames = value && value.match( rnotwhite );
6979
6980 if ( attrNames && elem.nodeType === 1 ) {
6981 while ( (name = attrNames[i++]) ) {
6982 propName = jQuery.propFix[ name ] || name;
6983
6984 // Boolean attributes get special treatment (#10870)
6985 if ( jQuery.expr.match.bool.test( name ) ) {
6986 // Set corresponding property to false
6987 elem[ propName ] = false;
6988 }
6989
6990 elem.removeAttribute( name );
6991 }
6992 }
6993 },
6994
6995 attrHooks: {
6996 type: {
6997 set: function( elem, value ) {
6998 if ( !support.radioValue && value === "radio" &&
6999 jQuery.nodeName( elem, "input" ) ) {
7000 // Setting the type on a radio button after the value resets the value in IE6-9
7001 // Reset value to default in case type is set after value during creation
7002 var val = elem.value;
7003 elem.setAttribute( "type", value );
7004 if ( val ) {
7005 elem.value = val;
7006 }
7007 return value;
7008 }
7009 }
7010 }
7011 }
7012});
7013
7014// Hooks for boolean attributes
7015boolHook = {
7016 set: function( elem, value, name ) {
7017 if ( value === false ) {
7018 // Remove boolean attributes when set to false
7019 jQuery.removeAttr( elem, name );
7020 } else {
7021 elem.setAttribute( name, name );
7022 }
7023 return name;
7024 }
7025};
7026jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7027 var getter = attrHandle[ name ] || jQuery.find.attr;
7028
7029 attrHandle[ name ] = function( elem, name, isXML ) {
7030 var ret, handle;
7031 if ( !isXML ) {
7032 // Avoid an infinite loop by temporarily removing this function from the getter
7033 handle = attrHandle[ name ];
7034 attrHandle[ name ] = ret;
7035 ret = getter( elem, name, isXML ) != null ?
7036 name.toLowerCase() :
7037 null;
7038 attrHandle[ name ] = handle;
7039 }
7040 return ret;
7041 };
7042});
7043
7044
7045
7046
7047var rfocusable = /^(?:input|select|textarea|button)$/i;
7048
7049jQuery.fn.extend({
7050 prop: function( name, value ) {
7051 return access( this, jQuery.prop, name, value, arguments.length > 1 );
7052 },
7053
7054 removeProp: function( name ) {
7055 return this.each(function() {
7056 delete this[ jQuery.propFix[ name ] || name ];
7057 });
7058 }
7059});
7060
7061jQuery.extend({
7062 propFix: {
7063 "for": "htmlFor",
7064 "class": "className"
7065 },
7066
7067 prop: function( elem, name, value ) {
7068 var ret, hooks, notxml,
7069 nType = elem.nodeType;
7070
7071 // don't get/set properties on text, comment and attribute nodes
7072 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
7073 return;
7074 }
7075
7076 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
7077
7078 if ( notxml ) {
7079 // Fix name and attach hooks
7080 name = jQuery.propFix[ name ] || name;
7081 hooks = jQuery.propHooks[ name ];
7082 }
7083
7084 if ( value !== undefined ) {
7085 return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
7086 ret :
7087 ( elem[ name ] = value );
7088
7089 } else {
7090 return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
7091 ret :
7092 elem[ name ];
7093 }
7094 },
7095
7096 propHooks: {
7097 tabIndex: {
7098 get: function( elem ) {
7099 return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
7100 elem.tabIndex :
7101 -1;
7102 }
7103 }
7104 }
7105});
7106
7107// Support: IE9+
7108// Selectedness for an option in an optgroup can be inaccurate
7109if ( !support.optSelected ) {
7110 jQuery.propHooks.selected = {
7111 get: function( elem ) {
7112 var parent = elem.parentNode;
7113 if ( parent && parent.parentNode ) {
7114 parent.parentNode.selectedIndex;
7115 }
7116 return null;
7117 }
7118 };
7119}
7120
7121jQuery.each([
7122 "tabIndex",
7123 "readOnly",
7124 "maxLength",
7125 "cellSpacing",
7126 "cellPadding",
7127 "rowSpan",
7128 "colSpan",
7129 "useMap",
7130 "frameBorder",
7131 "contentEditable"
7132], function() {
7133 jQuery.propFix[ this.toLowerCase() ] = this;
7134});
7135
7136
7137
7138
7139var rclass = /[\t\r\n\f]/g;
7140
7141jQuery.fn.extend({
7142 addClass: function( value ) {
7143 var classes, elem, cur, clazz, j, finalValue,
7144 proceed = typeof value === "string" && value,
7145 i = 0,
7146 len = this.length;
7147
7148 if ( jQuery.isFunction( value ) ) {
7149 return this.each(function( j ) {
7150 jQuery( this ).addClass( value.call( this, j, this.className ) );
7151 });
7152 }
7153
7154 if ( proceed ) {
7155 // The disjunction here is for better compressibility (see removeClass)
7156 classes = ( value || "" ).match( rnotwhite ) || [];
7157
7158 for ( ; i < len; i++ ) {
7159 elem = this[ i ];
7160 cur = elem.nodeType === 1 && ( elem.className ?
7161 ( " " + elem.className + " " ).replace( rclass, " " ) :
7162 " "
7163 );
7164
7165 if ( cur ) {
7166 j = 0;
7167 while ( (clazz = classes[j++]) ) {
7168 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7169 cur += clazz + " ";
7170 }
7171 }
7172
7173 // only assign if different to avoid unneeded rendering.
7174 finalValue = jQuery.trim( cur );
7175 if ( elem.className !== finalValue ) {
7176 elem.className = finalValue;
7177 }
7178 }
7179 }
7180 }
7181
7182 return this;
7183 },
7184
7185 removeClass: function( value ) {
7186 var classes, elem, cur, clazz, j, finalValue,
7187 proceed = arguments.length === 0 || typeof value === "string" && value,
7188 i = 0,
7189 len = this.length;
7190
7191 if ( jQuery.isFunction( value ) ) {
7192 return this.each(function( j ) {
7193 jQuery( this ).removeClass( value.call( this, j, this.className ) );
7194 });
7195 }
7196 if ( proceed ) {
7197 classes = ( value || "" ).match( rnotwhite ) || [];
7198
7199 for ( ; i < len; i++ ) {
7200 elem = this[ i ];
7201 // This expression is here for better compressibility (see addClass)
7202 cur = elem.nodeType === 1 && ( elem.className ?
7203 ( " " + elem.className + " " ).replace( rclass, " " ) :
7204 ""
7205 );
7206
7207 if ( cur ) {
7208 j = 0;
7209 while ( (clazz = classes[j++]) ) {
7210 // Remove *all* instances
7211 while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
7212 cur = cur.replace( " " + clazz + " ", " " );
7213 }
7214 }
7215
7216 // only assign if different to avoid unneeded rendering.
7217 finalValue = value ? jQuery.trim( cur ) : "";
7218 if ( elem.className !== finalValue ) {
7219 elem.className = finalValue;
7220 }
7221 }
7222 }
7223 }
7224
7225 return this;
7226 },
7227
7228 toggleClass: function( value, stateVal ) {
7229 var type = typeof value;
7230
7231 if ( typeof stateVal === "boolean" && type === "string" ) {
7232 return stateVal ? this.addClass( value ) : this.removeClass( value );
7233 }
7234
7235 if ( jQuery.isFunction( value ) ) {
7236 return this.each(function( i ) {
7237 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
7238 });
7239 }
7240
7241 return this.each(function() {
7242 if ( type === "string" ) {
7243 // toggle individual class names
7244 var className,
7245 i = 0,
7246 self = jQuery( this ),
7247 classNames = value.match( rnotwhite ) || [];
7248
7249 while ( (className = classNames[ i++ ]) ) {
7250 // check each className given, space separated list
7251 if ( self.hasClass( className ) ) {
7252 self.removeClass( className );
7253 } else {
7254 self.addClass( className );
7255 }
7256 }
7257
7258 // Toggle whole class name
7259 } else if ( type === strundefined || type === "boolean" ) {
7260 if ( this.className ) {
7261 // store className if set
7262 data_priv.set( this, "__className__", this.className );
7263 }
7264
7265 // If the element has a class name or if we're passed "false",
7266 // then remove the whole classname (if there was one, the above saved it).
7267 // Otherwise bring back whatever was previously saved (if anything),
7268 // falling back to the empty string if nothing was stored.
7269 this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
7270 }
7271 });
7272 },
7273
7274 hasClass: function( selector ) {
7275 var className = " " + selector + " ",
7276 i = 0,
7277 l = this.length;
7278 for ( ; i < l; i++ ) {
7279 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
7280 return true;
7281 }
7282 }
7283
7284 return false;
7285 }
7286});
7287
7288
7289
7290
7291var rreturn = /\r/g;
7292
7293jQuery.fn.extend({
7294 val: function( value ) {
7295 var hooks, ret, isFunction,
7296 elem = this[0];
7297
7298 if ( !arguments.length ) {
7299 if ( elem ) {
7300 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7301
7302 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
7303 return ret;
7304 }
7305
7306 ret = elem.value;
7307
7308 return typeof ret === "string" ?
7309 // handle most common string cases
7310 ret.replace(rreturn, "") :
7311 // handle cases where value is null/undef or number
7312 ret == null ? "" : ret;
7313 }
7314
7315 return;
7316 }
7317
7318 isFunction = jQuery.isFunction( value );
7319
7320 return this.each(function( i ) {
7321 var val;
7322
7323 if ( this.nodeType !== 1 ) {
7324 return;
7325 }
7326
7327 if ( isFunction ) {
7328 val = value.call( this, i, jQuery( this ).val() );
7329 } else {
7330 val = value;
7331 }
7332
7333 // Treat null/undefined as ""; convert numbers to string
7334 if ( val == null ) {
7335 val = "";
7336
7337 } else if ( typeof val === "number" ) {
7338 val += "";
7339
7340 } else if ( jQuery.isArray( val ) ) {
7341 val = jQuery.map( val, function( value ) {
7342 return value == null ? "" : value + "";
7343 });
7344 }
7345
7346 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7347
7348 // If set returns undefined, fall back to normal setting
7349 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
7350 this.value = val;
7351 }
7352 });
7353 }
7354});
7355
7356jQuery.extend({
7357 valHooks: {
7358 option: {
7359 get: function( elem ) {
7360 var val = jQuery.find.attr( elem, "value" );
7361 return val != null ?
7362 val :
7363 // Support: IE10-11+
7364 // option.text throws exceptions (#14686, #14858)
7365 jQuery.trim( jQuery.text( elem ) );
7366 }
7367 },
7368 select: {
7369 get: function( elem ) {
7370 var value, option,
7371 options = elem.options,
7372 index = elem.selectedIndex,
7373 one = elem.type === "select-one" || index < 0,
7374 values = one ? null : [],
7375 max = one ? index + 1 : options.length,
7376 i = index < 0 ?
7377 max :
7378 one ? index : 0;
7379
7380 // Loop through all the selected options
7381 for ( ; i < max; i++ ) {
7382 option = options[ i ];
7383
7384 // IE6-9 doesn't update selected after form reset (#2551)
7385 if ( ( option.selected || i === index ) &&
7386 // Don't return options that are disabled or in a disabled optgroup
7387 ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) &&
7388 ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7389
7390 // Get the specific value for the option
7391 value = jQuery( option ).val();
7392
7393 // We don't need an array for one selects
7394 if ( one ) {
7395 return value;
7396 }
7397
7398 // Multi-Selects return an array
7399 values.push( value );
7400 }
7401 }
7402
7403 return values;
7404 },
7405
7406 set: function( elem, value ) {
7407 var optionSet, option,
7408 options = elem.options,
7409 values = jQuery.makeArray( value ),
7410 i = options.length;
7411
7412 while ( i-- ) {
7413 option = options[ i ];
7414 if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {
7415 optionSet = true;
7416 }
7417 }
7418
7419 // force browsers to behave consistently when non-matching value is set
7420 if ( !optionSet ) {
7421 elem.selectedIndex = -1;
7422 }
7423 return values;
7424 }
7425 }
7426 }
7427});
7428
7429// Radios and checkboxes getter/setter
7430jQuery.each([ "radio", "checkbox" ], function() {
7431 jQuery.valHooks[ this ] = {
7432 set: function( elem, value ) {
7433 if ( jQuery.isArray( value ) ) {
7434 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
7435 }
7436 }
7437 };
7438 if ( !support.checkOn ) {
7439 jQuery.valHooks[ this ].get = function( elem ) {
7440 // Support: Webkit
7441 // "" is returned instead of "on" if a value isn't specified
7442 return elem.getAttribute("value") === null ? "on" : elem.value;
7443 };
7444 }
7445});
7446
7447
7448
7449
7450// Return jQuery for attributes-only inclusion
7451
7452
7453jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
7454 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
7455 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
7456
7457 // Handle event binding
7458 jQuery.fn[ name ] = function( data, fn ) {
7459 return arguments.length > 0 ?
7460 this.on( name, null, data, fn ) :
7461 this.trigger( name );
7462 };
7463});
7464
7465jQuery.fn.extend({
7466 hover: function( fnOver, fnOut ) {
7467 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
7468 },
7469
7470 bind: function( types, data, fn ) {
7471 return this.on( types, null, data, fn );
7472 },
7473 unbind: function( types, fn ) {
7474 return this.off( types, null, fn );
7475 },
7476
7477 delegate: function( selector, types, data, fn ) {
7478 return this.on( types, selector, data, fn );
7479 },
7480 undelegate: function( selector, types, fn ) {
7481 // ( namespace ) or ( selector, types [, fn] )
7482 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
7483 }
7484});
7485
7486
7487var nonce = jQuery.now();
7488
7489var rquery = (/\?/);
7490
7491
7492
7493// Support: Android 2.3
7494// Workaround failure to string-cast null input
7495jQuery.parseJSON = function( data ) {
7496 return JSON.parse( data + "" );
7497};
7498
7499
7500// Cross-browser xml parsing
7501jQuery.parseXML = function( data ) {
7502 var xml, tmp;
7503 if ( !data || typeof data !== "string" ) {
7504 return null;
7505 }
7506
7507 // Support: IE9
7508 try {
7509 tmp = new DOMParser();
7510 xml = tmp.parseFromString( data, "text/xml" );
7511 } catch ( e ) {
7512 xml = undefined;
7513 }
7514
7515 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
7516 jQuery.error( "Invalid XML: " + data );
7517 }
7518 return xml;
7519};
7520
7521
7522var
7523 // Document location
7524 ajaxLocParts,
7525 ajaxLocation,
7526
7527 rhash = /#.*$/,
7528 rts = /([?&])_=[^&]*/,
7529 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
7530 // #7653, #8125, #8152: local protocol detection
7531 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
7532 rnoContent = /^(?:GET|HEAD)$/,
7533 rprotocol = /^\/\//,
7534 rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
7535
7536 /* Prefilters
7537 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7538 * 2) These are called:
7539 * - BEFORE asking for a transport
7540 * - AFTER param serialization (s.data is a string if s.processData is true)
7541 * 3) key is the dataType
7542 * 4) the catchall symbol "*" can be used
7543 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7544 */
7545 prefilters = {},
7546
7547 /* Transports bindings
7548 * 1) key is the dataType
7549 * 2) the catchall symbol "*" can be used
7550 * 3) selection will start with transport dataType and THEN go to "*" if needed
7551 */
7552 transports = {},
7553
7554 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7555 allTypes = "*/".concat("*");
7556
7557// #8138, IE may throw an exception when accessing
7558// a field from window.location if document.domain has been set
7559try {
7560 ajaxLocation = location.href;
7561} catch( e ) {
7562 // Use the href attribute of an A element
7563 // since IE will modify it given document.location
7564 ajaxLocation = document.createElement( "a" );
7565 ajaxLocation.href = "";
7566 ajaxLocation = ajaxLocation.href;
7567}
7568
7569// Segment location into parts
7570ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7571
7572// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7573function addToPrefiltersOrTransports( structure ) {
7574
7575 // dataTypeExpression is optional and defaults to "*"
7576 return function( dataTypeExpression, func ) {
7577
7578 if ( typeof dataTypeExpression !== "string" ) {
7579 func = dataTypeExpression;
7580 dataTypeExpression = "*";
7581 }
7582
7583 var dataType,
7584 i = 0,
7585 dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
7586
7587 if ( jQuery.isFunction( func ) ) {
7588 // For each dataType in the dataTypeExpression
7589 while ( (dataType = dataTypes[i++]) ) {
7590 // Prepend if requested
7591 if ( dataType[0] === "+" ) {
7592 dataType = dataType.slice( 1 ) || "*";
7593 (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
7594
7595 // Otherwise append
7596 } else {
7597 (structure[ dataType ] = structure[ dataType ] || []).push( func );
7598 }
7599 }
7600 }
7601 };
7602}
7603
7604// Base inspection function for prefilters and transports
7605function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
7606
7607 var inspected = {},
7608 seekingTransport = ( structure === transports );
7609
7610 function inspect( dataType ) {
7611 var selected;
7612 inspected[ dataType ] = true;
7613 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
7614 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
7615 if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
7616 options.dataTypes.unshift( dataTypeOrTransport );
7617 inspect( dataTypeOrTransport );
7618 return false;
7619 } else if ( seekingTransport ) {
7620 return !( selected = dataTypeOrTransport );
7621 }
7622 });
7623 return selected;
7624 }
7625
7626 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
7627}
7628
7629// A special extend for ajax options
7630// that takes "flat" options (not to be deep extended)
7631// Fixes #9887
7632function ajaxExtend( target, src ) {
7633 var key, deep,
7634 flatOptions = jQuery.ajaxSettings.flatOptions || {};
7635
7636 for ( key in src ) {
7637 if ( src[ key ] !== undefined ) {
7638 ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
7639 }
7640 }
7641 if ( deep ) {
7642 jQuery.extend( true, target, deep );
7643 }
7644
7645 return target;
7646}
7647
7648/* Handles responses to an ajax request:
7649 * - finds the right dataType (mediates between content-type and expected dataType)
7650 * - returns the corresponding response
7651 */
7652function ajaxHandleResponses( s, jqXHR, responses ) {
7653
7654 var ct, type, finalDataType, firstDataType,
7655 contents = s.contents,
7656 dataTypes = s.dataTypes;
7657
7658 // Remove auto dataType and get content-type in the process
7659 while ( dataTypes[ 0 ] === "*" ) {
7660 dataTypes.shift();
7661 if ( ct === undefined ) {
7662 ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
7663 }
7664 }
7665
7666 // Check if we're dealing with a known content-type
7667 if ( ct ) {
7668 for ( type in contents ) {
7669 if ( contents[ type ] && contents[ type ].test( ct ) ) {
7670 dataTypes.unshift( type );
7671 break;
7672 }
7673 }
7674 }
7675
7676 // Check to see if we have a response for the expected dataType
7677 if ( dataTypes[ 0 ] in responses ) {
7678 finalDataType = dataTypes[ 0 ];
7679 } else {
7680 // Try convertible dataTypes
7681 for ( type in responses ) {
7682 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7683 finalDataType = type;
7684 break;
7685 }
7686 if ( !firstDataType ) {
7687 firstDataType = type;
7688 }
7689 }
7690 // Or just use first one
7691 finalDataType = finalDataType || firstDataType;
7692 }
7693
7694 // If we found a dataType
7695 // We add the dataType to the list if needed
7696 // and return the corresponding response
7697 if ( finalDataType ) {
7698 if ( finalDataType !== dataTypes[ 0 ] ) {
7699 dataTypes.unshift( finalDataType );
7700 }
7701 return responses[ finalDataType ];
7702 }
7703}
7704
7705/* Chain conversions given the request and the original response
7706 * Also sets the responseXXX fields on the jqXHR instance
7707 */
7708function ajaxConvert( s, response, jqXHR, isSuccess ) {
7709 var conv2, current, conv, tmp, prev,
7710 converters = {},
7711 // Work with a copy of dataTypes in case we need to modify it for conversion
7712 dataTypes = s.dataTypes.slice();
7713
7714 // Create converters map with lowercased keys
7715 if ( dataTypes[ 1 ] ) {
7716 for ( conv in s.converters ) {
7717 converters[ conv.toLowerCase() ] = s.converters[ conv ];
7718 }
7719 }
7720
7721 current = dataTypes.shift();
7722
7723 // Convert to each sequential dataType
7724 while ( current ) {
7725
7726 if ( s.responseFields[ current ] ) {
7727 jqXHR[ s.responseFields[ current ] ] = response;
7728 }
7729
7730 // Apply the dataFilter if provided
7731 if ( !prev && isSuccess && s.dataFilter ) {
7732 response = s.dataFilter( response, s.dataType );
7733 }
7734
7735 prev = current;
7736 current = dataTypes.shift();
7737
7738 if ( current ) {
7739
7740 // There's only work to do if current dataType is non-auto
7741 if ( current === "*" ) {
7742
7743 current = prev;
7744
7745 // Convert response if prev dataType is non-auto and differs from current
7746 } else if ( prev !== "*" && prev !== current ) {
7747
7748 // Seek a direct converter
7749 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
7750
7751 // If none found, seek a pair
7752 if ( !conv ) {
7753 for ( conv2 in converters ) {
7754
7755 // If conv2 outputs current
7756 tmp = conv2.split( " " );
7757 if ( tmp[ 1 ] === current ) {
7758
7759 // If prev can be converted to accepted input
7760 conv = converters[ prev + " " + tmp[ 0 ] ] ||
7761 converters[ "* " + tmp[ 0 ] ];
7762 if ( conv ) {
7763 // Condense equivalence converters
7764 if ( conv === true ) {
7765 conv = converters[ conv2 ];
7766
7767 // Otherwise, insert the intermediate dataType
7768 } else if ( converters[ conv2 ] !== true ) {
7769 current = tmp[ 0 ];
7770 dataTypes.unshift( tmp[ 1 ] );
7771 }
7772 break;
7773 }
7774 }
7775 }
7776 }
7777
7778 // Apply converter (if not an equivalence)
7779 if ( conv !== true ) {
7780
7781 // Unless errors are allowed to bubble, catch and return them
7782 if ( conv && s[ "throws" ] ) {
7783 response = conv( response );
7784 } else {
7785 try {
7786 response = conv( response );
7787 } catch ( e ) {
7788 return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
7789 }
7790 }
7791 }
7792 }
7793 }
7794 }
7795
7796 return { state: "success", data: response };
7797}
7798
7799jQuery.extend({
7800
7801 // Counter for holding the number of active queries
7802 active: 0,
7803
7804 // Last-Modified header cache for next request
7805 lastModified: {},
7806 etag: {},
7807
7808 ajaxSettings: {
7809 url: ajaxLocation,
7810 type: "GET",
7811 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7812 global: true,
7813 processData: true,
7814 async: true,
7815 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7816 /*
7817 timeout: 0,
7818 data: null,
7819 dataType: null,
7820 username: null,
7821 password: null,
7822 cache: null,
7823 throws: false,
7824 traditional: false,
7825 headers: {},
7826 */
7827
7828 accepts: {
7829 "*": allTypes,
7830 text: "text/plain",
7831 html: "text/html",
7832 xml: "application/xml, text/xml",
7833 json: "application/json, text/javascript"
7834 },
7835
7836 contents: {
7837 xml: /xml/,
7838 html: /html/,
7839 json: /json/
7840 },
7841
7842 responseFields: {
7843 xml: "responseXML",
7844 text: "responseText",
7845 json: "responseJSON"
7846 },
7847
7848 // Data converters
7849 // Keys separate source (or catchall "*") and destination types with a single space
7850 converters: {
7851
7852 // Convert anything to text
7853 "* text": String,
7854
7855 // Text to html (true = no transformation)
7856 "text html": true,
7857
7858 // Evaluate text as a json expression
7859 "text json": jQuery.parseJSON,
7860
7861 // Parse text as xml
7862 "text xml": jQuery.parseXML
7863 },
7864
7865 // For options that shouldn't be deep extended:
7866 // you can add your own custom options here if
7867 // and when you create one that shouldn't be
7868 // deep extended (see ajaxExtend)
7869 flatOptions: {
7870 url: true,
7871 context: true
7872 }
7873 },
7874
7875 // Creates a full fledged settings object into target
7876 // with both ajaxSettings and settings fields.
7877 // If target is omitted, writes into ajaxSettings.
7878 ajaxSetup: function( target, settings ) {
7879 return settings ?
7880
7881 // Building a settings object
7882 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
7883
7884 // Extending ajaxSettings
7885 ajaxExtend( jQuery.ajaxSettings, target );
7886 },
7887
7888 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7889 ajaxTransport: addToPrefiltersOrTransports( transports ),
7890
7891 // Main method
7892 ajax: function( url, options ) {
7893
7894 // If url is an object, simulate pre-1.5 signature
7895 if ( typeof url === "object" ) {
7896 options = url;
7897 url = undefined;
7898 }
7899
7900 // Force options to be an object
7901 options = options || {};
7902
7903 var transport,
7904 // URL without anti-cache param
7905 cacheURL,
7906 // Response headers
7907 responseHeadersString,
7908 responseHeaders,
7909 // timeout handle
7910 timeoutTimer,
7911 // Cross-domain detection vars
7912 parts,
7913 // To know if global events are to be dispatched
7914 fireGlobals,
7915 // Loop variable
7916 i,
7917 // Create the final options object
7918 s = jQuery.ajaxSetup( {}, options ),
7919 // Callbacks context
7920 callbackContext = s.context || s,
7921 // Context for global events is callbackContext if it is a DOM node or jQuery collection
7922 globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
7923 jQuery( callbackContext ) :
7924 jQuery.event,
7925 // Deferreds
7926 deferred = jQuery.Deferred(),
7927 completeDeferred = jQuery.Callbacks("once memory"),
7928 // Status-dependent callbacks
7929 statusCode = s.statusCode || {},
7930 // Headers (they are sent all at once)
7931 requestHeaders = {},
7932 requestHeadersNames = {},
7933 // The jqXHR state
7934 state = 0,
7935 // Default abort message
7936 strAbort = "canceled",
7937 // Fake xhr
7938 jqXHR = {
7939 readyState: 0,
7940
7941 // Builds headers hashtable if needed
7942 getResponseHeader: function( key ) {
7943 var match;
7944 if ( state === 2 ) {
7945 if ( !responseHeaders ) {
7946 responseHeaders = {};
7947 while ( (match = rheaders.exec( responseHeadersString )) ) {
7948 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7949 }
7950 }
7951 match = responseHeaders[ key.toLowerCase() ];
7952 }
7953 return match == null ? null : match;
7954 },
7955
7956 // Raw string
7957 getAllResponseHeaders: function() {
7958 return state === 2 ? responseHeadersString : null;
7959 },
7960
7961 // Caches the header
7962 setRequestHeader: function( name, value ) {
7963 var lname = name.toLowerCase();
7964 if ( !state ) {
7965 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7966 requestHeaders[ name ] = value;
7967 }
7968 return this;
7969 },
7970
7971 // Overrides response content-type header
7972 overrideMimeType: function( type ) {
7973 if ( !state ) {
7974 s.mimeType = type;
7975 }
7976 return this;
7977 },
7978
7979 // Status-dependent callbacks
7980 statusCode: function( map ) {
7981 var code;
7982 if ( map ) {
7983 if ( state < 2 ) {
7984 for ( code in map ) {
7985 // Lazy-add the new callback in a way that preserves old ones
7986 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
7987 }
7988 } else {
7989 // Execute the appropriate callbacks
7990 jqXHR.always( map[ jqXHR.status ] );
7991 }
7992 }
7993 return this;
7994 },
7995
7996 // Cancel the request
7997 abort: function( statusText ) {
7998 var finalText = statusText || strAbort;
7999 if ( transport ) {
8000 transport.abort( finalText );
8001 }
8002 done( 0, finalText );
8003 return this;
8004 }
8005 };
8006
8007 // Attach deferreds
8008 deferred.promise( jqXHR ).complete = completeDeferred.add;
8009 jqXHR.success = jqXHR.done;
8010 jqXHR.error = jqXHR.fail;
8011
8012 // Remove hash character (#7531: and string promotion)
8013 // Add protocol if not provided (prefilters might expect it)
8014 // Handle falsy url in the settings object (#10093: consistency with old signature)
8015 // We also use the url parameter if available
8016 s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
8017 .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
8018
8019 // Alias method option to type as per ticket #12004
8020 s.type = options.method || options.type || s.method || s.type;
8021
8022 // Extract dataTypes list
8023 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8024
8025 // A cross-domain request is in order when we have a protocol:host:port mismatch
8026 if ( s.crossDomain == null ) {
8027 parts = rurl.exec( s.url.toLowerCase() );
8028 s.crossDomain = !!( parts &&
8029 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
8030 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
8031 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
8032 );
8033 }
8034
8035 // Convert data if not already a string
8036 if ( s.data && s.processData && typeof s.data !== "string" ) {
8037 s.data = jQuery.param( s.data, s.traditional );
8038 }
8039
8040 // Apply prefilters
8041 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8042
8043 // If request was aborted inside a prefilter, stop there
8044 if ( state === 2 ) {
8045 return jqXHR;
8046 }
8047
8048 // We can fire global events as of now if asked to
8049 fireGlobals = s.global;
8050
8051 // Watch for a new set of requests
8052 if ( fireGlobals && jQuery.active++ === 0 ) {
8053 jQuery.event.trigger("ajaxStart");
8054 }
8055
8056 // Uppercase the type
8057 s.type = s.type.toUpperCase();
8058
8059 // Determine if request has content
8060 s.hasContent = !rnoContent.test( s.type );
8061
8062 // Save the URL in case we're toying with the If-Modified-Since
8063 // and/or If-None-Match header later on
8064 cacheURL = s.url;
8065
8066 // More options handling for requests with no content
8067 if ( !s.hasContent ) {
8068
8069 // If data is available, append data to url
8070 if ( s.data ) {
8071 cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8072 // #9682: remove data so that it's not used in an eventual retry
8073 delete s.data;
8074 }
8075
8076 // Add anti-cache in url if needed
8077 if ( s.cache === false ) {
8078 s.url = rts.test( cacheURL ) ?
8079
8080 // If there is already a '_' parameter, set its value
8081 cacheURL.replace( rts, "$1_=" + nonce++ ) :
8082
8083 // Otherwise add one to the end
8084 cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8085 }
8086 }
8087
8088 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8089 if ( s.ifModified ) {
8090 if ( jQuery.lastModified[ cacheURL ] ) {
8091 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8092 }
8093 if ( jQuery.etag[ cacheURL ] ) {
8094 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8095 }
8096 }
8097
8098 // Set the correct header, if data is being sent
8099 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8100 jqXHR.setRequestHeader( "Content-Type", s.contentType );
8101 }
8102
8103 // Set the Accepts header for the server, depending on the dataType
8104 jqXHR.setRequestHeader(
8105 "Accept",
8106 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
8107 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8108 s.accepts[ "*" ]
8109 );
8110
8111 // Check for headers option
8112 for ( i in s.headers ) {
8113 jqXHR.setRequestHeader( i, s.headers[ i ] );
8114 }
8115
8116 // Allow custom headers/mimetypes and early abort
8117 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8118 // Abort if not done already and return
8119 return jqXHR.abort();
8120 }
8121
8122 // aborting is no longer a cancellation
8123 strAbort = "abort";
8124
8125 // Install callbacks on deferreds
8126 for ( i in { success: 1, error: 1, complete: 1 } ) {
8127 jqXHR[ i ]( s[ i ] );
8128 }
8129
8130 // Get transport
8131 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8132
8133 // If no transport, we auto-abort
8134 if ( !transport ) {
8135 done( -1, "No Transport" );
8136 } else {
8137 jqXHR.readyState = 1;
8138
8139 // Send global event
8140 if ( fireGlobals ) {
8141 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8142 }
8143 // Timeout
8144 if ( s.async && s.timeout > 0 ) {
8145 timeoutTimer = setTimeout(function() {
8146 jqXHR.abort("timeout");
8147 }, s.timeout );
8148 }
8149
8150 try {
8151 state = 1;
8152 transport.send( requestHeaders, done );
8153 } catch ( e ) {
8154 // Propagate exception as error if not done
8155 if ( state < 2 ) {
8156 done( -1, e );
8157 // Simply rethrow otherwise
8158 } else {
8159 throw e;
8160 }
8161 }
8162 }
8163
8164 // Callback for when everything is done
8165 function done( status, nativeStatusText, responses, headers ) {
8166 var isSuccess, success, error, response, modified,
8167 statusText = nativeStatusText;
8168
8169 // Called once
8170 if ( state === 2 ) {
8171 return;
8172 }
8173
8174 // State is "done" now
8175 state = 2;
8176
8177 // Clear timeout if it exists
8178 if ( timeoutTimer ) {
8179 clearTimeout( timeoutTimer );
8180 }
8181
8182 // Dereference transport for early garbage collection
8183 // (no matter how long the jqXHR object will be used)
8184 transport = undefined;
8185
8186 // Cache response headers
8187 responseHeadersString = headers || "";
8188
8189 // Set readyState
8190 jqXHR.readyState = status > 0 ? 4 : 0;
8191
8192 // Determine if successful
8193 isSuccess = status >= 200 && status < 300 || status === 304;
8194
8195 // Get response data
8196 if ( responses ) {
8197 response = ajaxHandleResponses( s, jqXHR, responses );
8198 }
8199
8200 // Convert no matter what (that way responseXXX fields are always set)
8201 response = ajaxConvert( s, response, jqXHR, isSuccess );
8202
8203 // If successful, handle type chaining
8204 if ( isSuccess ) {
8205
8206 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8207 if ( s.ifModified ) {
8208 modified = jqXHR.getResponseHeader("Last-Modified");
8209 if ( modified ) {
8210 jQuery.lastModified[ cacheURL ] = modified;
8211 }
8212 modified = jqXHR.getResponseHeader("etag");
8213 if ( modified ) {
8214 jQuery.etag[ cacheURL ] = modified;
8215 }
8216 }
8217
8218 // if no content
8219 if ( status === 204 || s.type === "HEAD" ) {
8220 statusText = "nocontent";
8221
8222 // if not modified
8223 } else if ( status === 304 ) {
8224 statusText = "notmodified";
8225
8226 // If we have data, let's convert it
8227 } else {
8228 statusText = response.state;
8229 success = response.data;
8230 error = response.error;
8231 isSuccess = !error;
8232 }
8233 } else {
8234 // We extract error from statusText
8235 // then normalize statusText and status for non-aborts
8236 error = statusText;
8237 if ( status || !statusText ) {
8238 statusText = "error";
8239 if ( status < 0 ) {
8240 status = 0;
8241 }
8242 }
8243 }
8244
8245 // Set data for the fake xhr object
8246 jqXHR.status = status;
8247 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
8248
8249 // Success/Error
8250 if ( isSuccess ) {
8251 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
8252 } else {
8253 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
8254 }
8255
8256 // Status-dependent callbacks
8257 jqXHR.statusCode( statusCode );
8258 statusCode = undefined;
8259
8260 if ( fireGlobals ) {
8261 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
8262 [ jqXHR, s, isSuccess ? success : error ] );
8263 }
8264
8265 // Complete
8266 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
8267
8268 if ( fireGlobals ) {
8269 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
8270 // Handle the global AJAX counter
8271 if ( !( --jQuery.active ) ) {
8272 jQuery.event.trigger("ajaxStop");
8273 }
8274 }
8275 }
8276
8277 return jqXHR;
8278 },
8279
8280 getJSON: function( url, data, callback ) {
8281 return jQuery.get( url, data, callback, "json" );
8282 },
8283
8284 getScript: function( url, callback ) {
8285 return jQuery.get( url, undefined, callback, "script" );
8286 }
8287});
8288
8289jQuery.each( [ "get", "post" ], function( i, method ) {
8290 jQuery[ method ] = function( url, data, callback, type ) {
8291 // shift arguments if data argument was omitted
8292 if ( jQuery.isFunction( data ) ) {
8293 type = type || callback;
8294 callback = data;
8295 data = undefined;
8296 }
8297
8298 return jQuery.ajax({
8299 url: url,
8300 type: method,
8301 dataType: type,
8302 data: data,
8303 success: callback
8304 });
8305 };
8306});
8307
8308// Attach a bunch of functions for handling common AJAX events
8309jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
8310 jQuery.fn[ type ] = function( fn ) {
8311 return this.on( type, fn );
8312 };
8313});
8314
8315
8316jQuery._evalUrl = function( url ) {
8317 return jQuery.ajax({
8318 url: url,
8319 type: "GET",
8320 dataType: "script",
8321 async: false,
8322 global: false,
8323 "throws": true
8324 });
8325};
8326
8327
8328jQuery.fn.extend({
8329 wrapAll: function( html ) {
8330 var wrap;
8331
8332 if ( jQuery.isFunction( html ) ) {
8333 return this.each(function( i ) {
8334 jQuery( this ).wrapAll( html.call(this, i) );
8335 });
8336 }
8337
8338 if ( this[ 0 ] ) {
8339
8340 // The elements to wrap the target around
8341 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
8342
8343 if ( this[ 0 ].parentNode ) {
8344 wrap.insertBefore( this[ 0 ] );
8345 }
8346
8347 wrap.map(function() {
8348 var elem = this;
8349
8350 while ( elem.firstElementChild ) {
8351 elem = elem.firstElementChild;
8352 }
8353
8354 return elem;
8355 }).append( this );
8356 }
8357
8358 return this;
8359 },
8360
8361 wrapInner: function( html ) {
8362 if ( jQuery.isFunction( html ) ) {
8363 return this.each(function( i ) {
8364 jQuery( this ).wrapInner( html.call(this, i) );
8365 });
8366 }
8367
8368 return this.each(function() {
8369 var self = jQuery( this ),
8370 contents = self.contents();
8371
8372 if ( contents.length ) {
8373 contents.wrapAll( html );
8374
8375 } else {
8376 self.append( html );
8377 }
8378 });
8379 },
8380
8381 wrap: function( html ) {
8382 var isFunction = jQuery.isFunction( html );
8383
8384 return this.each(function( i ) {
8385 jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
8386 });
8387 },
8388
8389 unwrap: function() {
8390 return this.parent().each(function() {
8391 if ( !jQuery.nodeName( this, "body" ) ) {
8392 jQuery( this ).replaceWith( this.childNodes );
8393 }
8394 }).end();
8395 }
8396});
8397
8398
8399jQuery.expr.filters.hidden = function( elem ) {
8400 // Support: Opera <= 12.12
8401 // Opera reports offsetWidths and offsetHeights less than zero on some elements
8402 return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
8403};
8404jQuery.expr.filters.visible = function( elem ) {
8405 return !jQuery.expr.filters.hidden( elem );
8406};
8407
8408
8409
8410
8411var r20 = /%20/g,
8412 rbracket = /\[\]$/,
8413 rCRLF = /\r?\n/g,
8414 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8415 rsubmittable = /^(?:input|select|textarea|keygen)/i;
8416
8417function buildParams( prefix, obj, traditional, add ) {
8418 var name;
8419
8420 if ( jQuery.isArray( obj ) ) {
8421 // Serialize array item.
8422 jQuery.each( obj, function( i, v ) {
8423 if ( traditional || rbracket.test( prefix ) ) {
8424 // Treat each array item as a scalar.
8425 add( prefix, v );
8426
8427 } else {
8428 // Item is non-scalar (array or object), encode its numeric index.
8429 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
8430 }
8431 });
8432
8433 } else if ( !traditional && jQuery.type( obj ) === "object" ) {
8434 // Serialize object item.
8435 for ( name in obj ) {
8436 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8437 }
8438
8439 } else {
8440 // Serialize scalar item.
8441 add( prefix, obj );
8442 }
8443}
8444
8445// Serialize an array of form elements or a set of
8446// key/values into a query string
8447jQuery.param = function( a, traditional ) {
8448 var prefix,
8449 s = [],
8450 add = function( key, value ) {
8451 // If value is a function, invoke it and return its value
8452 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
8453 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
8454 };
8455
8456 // Set traditional to true for jQuery <= 1.3.2 behavior.
8457 if ( traditional === undefined ) {
8458 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
8459 }
8460
8461 // If an array was passed in, assume that it is an array of form elements.
8462 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8463 // Serialize the form elements
8464 jQuery.each( a, function() {
8465 add( this.name, this.value );
8466 });
8467
8468 } else {
8469 // If traditional, encode the "old" way (the way 1.3.2 or older
8470 // did it), otherwise encode params recursively.
8471 for ( prefix in a ) {
8472 buildParams( prefix, a[ prefix ], traditional, add );
8473 }
8474 }
8475
8476 // Return the resulting serialization
8477 return s.join( "&" ).replace( r20, "+" );
8478};
8479
8480jQuery.fn.extend({
8481 serialize: function() {
8482 return jQuery.param( this.serializeArray() );
8483 },
8484 serializeArray: function() {
8485 return this.map(function() {
8486 // Can add propHook for "elements" to filter or add form elements
8487 var elements = jQuery.prop( this, "elements" );
8488 return elements ? jQuery.makeArray( elements ) : this;
8489 })
8490 .filter(function() {
8491 var type = this.type;
8492
8493 // Use .is( ":disabled" ) so that fieldset[disabled] works
8494 return this.name && !jQuery( this ).is( ":disabled" ) &&
8495 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8496 ( this.checked || !rcheckableType.test( type ) );
8497 })
8498 .map(function( i, elem ) {
8499 var val = jQuery( this ).val();
8500
8501 return val == null ?
8502 null :
8503 jQuery.isArray( val ) ?
8504 jQuery.map( val, function( val ) {
8505 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8506 }) :
8507 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8508 }).get();
8509 }
8510});
8511
8512
8513jQuery.ajaxSettings.xhr = function() {
8514 try {
8515 return new XMLHttpRequest();
8516 } catch( e ) {}
8517};
8518
8519var xhrId = 0,
8520 xhrCallbacks = {},
8521 xhrSuccessStatus = {
8522 // file protocol always yields status code 0, assume 200
8523 0: 200,
8524 // Support: IE9
8525 // #1450: sometimes IE returns 1223 when it should be 204
8526 1223: 204
8527 },
8528 xhrSupported = jQuery.ajaxSettings.xhr();
8529
8530// Support: IE9
8531// Open requests must be manually aborted on unload (#5280)
8532if ( window.ActiveXObject ) {
8533 jQuery( window ).on( "unload", function() {
8534 for ( var key in xhrCallbacks ) {
8535 xhrCallbacks[ key ]();
8536 }
8537 });
8538}
8539
8540support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
8541support.ajax = xhrSupported = !!xhrSupported;
8542
8543jQuery.ajaxTransport(function( options ) {
8544 var callback;
8545
8546 // Cross domain only allowed if supported through XMLHttpRequest
8547 if ( support.cors || xhrSupported && !options.crossDomain ) {
8548 return {
8549 send: function( headers, complete ) {
8550 var i,
8551 xhr = options.xhr(),
8552 id = ++xhrId;
8553
8554 xhr.open( options.type, options.url, options.async, options.username, options.password );
8555
8556 // Apply custom fields if provided
8557 if ( options.xhrFields ) {
8558 for ( i in options.xhrFields ) {
8559 xhr[ i ] = options.xhrFields[ i ];
8560 }
8561 }
8562
8563 // Override mime type if needed
8564 if ( options.mimeType && xhr.overrideMimeType ) {
8565 xhr.overrideMimeType( options.mimeType );
8566 }
8567
8568 // X-Requested-With header
8569 // For cross-domain requests, seeing as conditions for a preflight are
8570 // akin to a jigsaw puzzle, we simply never set it to be sure.
8571 // (it can always be set on a per-request basis or even using ajaxSetup)
8572 // For same-domain requests, won't change header if already provided.
8573 if ( !options.crossDomain && !headers["X-Requested-With"] ) {
8574 headers["X-Requested-With"] = "XMLHttpRequest";
8575 }
8576
8577 // Set headers
8578 for ( i in headers ) {
8579 xhr.setRequestHeader( i, headers[ i ] );
8580 }
8581
8582 // Callback
8583 callback = function( type ) {
8584 return function() {
8585 if ( callback ) {
8586 delete xhrCallbacks[ id ];
8587 callback = xhr.onload = xhr.onerror = null;
8588
8589 if ( type === "abort" ) {
8590 xhr.abort();
8591 } else if ( type === "error" ) {
8592 complete(
8593 // file: protocol always yields status 0; see #8605, #14207
8594 xhr.status,
8595 xhr.statusText
8596 );
8597 } else {
8598 complete(
8599 xhrSuccessStatus[ xhr.status ] || xhr.status,
8600 xhr.statusText,
8601 // Support: IE9
8602 // Accessing binary-data responseText throws an exception
8603 // (#11426)
8604 typeof xhr.responseText === "string" ? {
8605 text: xhr.responseText
8606 } : undefined,
8607 xhr.getAllResponseHeaders()
8608 );
8609 }
8610 }
8611 };
8612 };
8613
8614 // Listen to events
8615 xhr.onload = callback();
8616 xhr.onerror = callback("error");
8617
8618 // Create the abort callback
8619 callback = xhrCallbacks[ id ] = callback("abort");
8620
8621 try {
8622 // Do send the request (this may raise an exception)
8623 xhr.send( options.hasContent && options.data || null );
8624 } catch ( e ) {
8625 // #14683: Only rethrow if this hasn't been notified as an error yet
8626 if ( callback ) {
8627 throw e;
8628 }
8629 }
8630 },
8631
8632 abort: function() {
8633 if ( callback ) {
8634 callback();
8635 }
8636 }
8637 };
8638 }
8639});
8640
8641
8642
8643
8644// Install script dataType
8645jQuery.ajaxSetup({
8646 accepts: {
8647 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8648 },
8649 contents: {
8650 script: /(?:java|ecma)script/
8651 },
8652 converters: {
8653 "text script": function( text ) {
8654 jQuery.globalEval( text );
8655 return text;
8656 }
8657 }
8658});
8659
8660// Handle cache's special case and crossDomain
8661jQuery.ajaxPrefilter( "script", function( s ) {
8662 if ( s.cache === undefined ) {
8663 s.cache = false;
8664 }
8665 if ( s.crossDomain ) {
8666 s.type = "GET";
8667 }
8668});
8669
8670// Bind script tag hack transport
8671jQuery.ajaxTransport( "script", function( s ) {
8672 // This transport only deals with cross domain requests
8673 if ( s.crossDomain ) {
8674 var script, callback;
8675 return {
8676 send: function( _, complete ) {
8677 script = jQuery("<script>").prop({
8678 async: true,
8679 charset: s.scriptCharset,
8680 src: s.url
8681 }).on(
8682 "load error",
8683 callback = function( evt ) {
8684 script.remove();
8685 callback = null;
8686 if ( evt ) {
8687 complete( evt.type === "error" ? 404 : 200, evt.type );
8688 }
8689 }
8690 );
8691 document.head.appendChild( script[ 0 ] );
8692 },
8693 abort: function() {
8694 if ( callback ) {
8695 callback();
8696 }
8697 }
8698 };
8699 }
8700});
8701
8702
8703
8704
8705var oldCallbacks = [],
8706 rjsonp = /(=)\?(?=&|$)|\?\?/;
8707
8708// Default jsonp settings
8709jQuery.ajaxSetup({
8710 jsonp: "callback",
8711 jsonpCallback: function() {
8712 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
8713 this[ callback ] = true;
8714 return callback;
8715 }
8716});
8717
8718// Detect, normalize options and install callbacks for jsonp requests
8719jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8720
8721 var callbackName, overwritten, responseContainer,
8722 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
8723 "url" :
8724 typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
8725 );
8726
8727 // Handle iff the expected data type is "jsonp" or we have a parameter to set
8728 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
8729
8730 // Get callback name, remembering preexisting value associated with it
8731 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
8732 s.jsonpCallback() :
8733 s.jsonpCallback;
8734
8735 // Insert callback into url or form data
8736 if ( jsonProp ) {
8737 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
8738 } else if ( s.jsonp !== false ) {
8739 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
8740 }
8741
8742 // Use data converter to retrieve json after script execution
8743 s.converters["script json"] = function() {
8744 if ( !responseContainer ) {
8745 jQuery.error( callbackName + " was not called" );
8746 }
8747 return responseContainer[ 0 ];
8748 };
8749
8750 // force json dataType
8751 s.dataTypes[ 0 ] = "json";
8752
8753 // Install callback
8754 overwritten = window[ callbackName ];
8755 window[ callbackName ] = function() {
8756 responseContainer = arguments;
8757 };
8758
8759 // Clean-up function (fires after converters)
8760 jqXHR.always(function() {
8761 // Restore preexisting value
8762 window[ callbackName ] = overwritten;
8763
8764 // Save back as free
8765 if ( s[ callbackName ] ) {
8766 // make sure that re-using the options doesn't screw things around
8767 s.jsonpCallback = originalSettings.jsonpCallback;
8768
8769 // save the callback name for future use
8770 oldCallbacks.push( callbackName );
8771 }
8772
8773 // Call if it was a function and we have a response
8774 if ( responseContainer && jQuery.isFunction( overwritten ) ) {
8775 overwritten( responseContainer[ 0 ] );
8776 }
8777
8778 responseContainer = overwritten = undefined;
8779 });
8780
8781 // Delegate to script
8782 return "script";
8783 }
8784});
8785
8786
8787
8788
8789// data: string of html
8790// context (optional): If specified, the fragment will be created in this context, defaults to document
8791// keepScripts (optional): If true, will include scripts passed in the html string
8792jQuery.parseHTML = function( data, context, keepScripts ) {
8793 if ( !data || typeof data !== "string" ) {
8794 return null;
8795 }
8796 if ( typeof context === "boolean" ) {
8797 keepScripts = context;
8798 context = false;
8799 }
8800 context = context || document;
8801
8802 var parsed = rsingleTag.exec( data ),
8803 scripts = !keepScripts && [];
8804
8805 // Single tag
8806 if ( parsed ) {
8807 return [ context.createElement( parsed[1] ) ];
8808 }
8809
8810 parsed = jQuery.buildFragment( [ data ], context, scripts );
8811
8812 if ( scripts && scripts.length ) {
8813 jQuery( scripts ).remove();
8814 }
8815
8816 return jQuery.merge( [], parsed.childNodes );
8817};
8818
8819
8820// Keep a copy of the old load method
8821var _load = jQuery.fn.load;
8822
8823/**
8824 * Load a url into a page
8825 */
8826jQuery.fn.load = function( url, params, callback ) {
8827 if ( typeof url !== "string" && _load ) {
8828 return _load.apply( this, arguments );
8829 }
8830
8831 var selector, type, response,
8832 self = this,
8833 off = url.indexOf(" ");
8834
8835 if ( off >= 0 ) {
8836 selector = jQuery.trim( url.slice( off ) );
8837 url = url.slice( 0, off );
8838 }
8839
8840 // If it's a function
8841 if ( jQuery.isFunction( params ) ) {
8842
8843 // We assume that it's the callback
8844 callback = params;
8845 params = undefined;
8846
8847 // Otherwise, build a param string
8848 } else if ( params && typeof params === "object" ) {
8849 type = "POST";
8850 }
8851
8852 // If we have elements to modify, make the request
8853 if ( self.length > 0 ) {
8854 jQuery.ajax({
8855 url: url,
8856
8857 // if "type" variable is undefined, then "GET" method will be used
8858 type: type,
8859 dataType: "html",
8860 data: params
8861 }).done(function( responseText ) {
8862
8863 // Save response for use in complete callback
8864 response = arguments;
8865
8866 self.html( selector ?
8867
8868 // If a selector was specified, locate the right elements in a dummy div
8869 // Exclude scripts to avoid IE 'Permission Denied' errors
8870 jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
8871
8872 // Otherwise use the full result
8873 responseText );
8874
8875 }).complete( callback && function( jqXHR, status ) {
8876 self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
8877 });
8878 }
8879
8880 return this;
8881};
8882
8883
8884
8885
8886jQuery.expr.filters.animated = function( elem ) {
8887 return jQuery.grep(jQuery.timers, function( fn ) {
8888 return elem === fn.elem;
8889 }).length;
8890};
8891
8892
8893
8894
8895var docElem = window.document.documentElement;
8896
8897/**
8898 * Gets a window from an element
8899 */
8900function getWindow( elem ) {
8901 return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
8902}
8903
8904jQuery.offset = {
8905 setOffset: function( elem, options, i ) {
8906 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
8907 position = jQuery.css( elem, "position" ),
8908 curElem = jQuery( elem ),
8909 props = {};
8910
8911 // Set position first, in-case top/left are set even on static elem
8912 if ( position === "static" ) {
8913 elem.style.position = "relative";
8914 }
8915
8916 curOffset = curElem.offset();
8917 curCSSTop = jQuery.css( elem, "top" );
8918 curCSSLeft = jQuery.css( elem, "left" );
8919 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
8920 ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
8921
8922 // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8923 if ( calculatePosition ) {
8924 curPosition = curElem.position();
8925 curTop = curPosition.top;
8926 curLeft = curPosition.left;
8927
8928 } else {
8929 curTop = parseFloat( curCSSTop ) || 0;
8930 curLeft = parseFloat( curCSSLeft ) || 0;
8931 }
8932
8933 if ( jQuery.isFunction( options ) ) {
8934 options = options.call( elem, i, curOffset );
8935 }
8936
8937 if ( options.top != null ) {
8938 props.top = ( options.top - curOffset.top ) + curTop;
8939 }
8940 if ( options.left != null ) {
8941 props.left = ( options.left - curOffset.left ) + curLeft;
8942 }
8943
8944 if ( "using" in options ) {
8945 options.using.call( elem, props );
8946
8947 } else {
8948 curElem.css( props );
8949 }
8950 }
8951};
8952
8953jQuery.fn.extend({
8954 offset: function( options ) {
8955 if ( arguments.length ) {
8956 return options === undefined ?
8957 this :
8958 this.each(function( i ) {
8959 jQuery.offset.setOffset( this, options, i );
8960 });
8961 }
8962
8963 var docElem, win,
8964 elem = this[ 0 ],
8965 box = { top: 0, left: 0 },
8966 doc = elem && elem.ownerDocument;
8967
8968 if ( !doc ) {
8969 return;
8970 }
8971
8972 docElem = doc.documentElement;
8973
8974 // Make sure it's not a disconnected DOM node
8975 if ( !jQuery.contains( docElem, elem ) ) {
8976 return box;
8977 }
8978
8979 // If we don't have gBCR, just use 0,0 rather than error
8980 // BlackBerry 5, iOS 3 (original iPhone)
8981 if ( typeof elem.getBoundingClientRect !== strundefined ) {
8982 box = elem.getBoundingClientRect();
8983 }
8984 win = getWindow( doc );
8985 return {
8986 top: box.top + win.pageYOffset - docElem.clientTop,
8987 left: box.left + win.pageXOffset - docElem.clientLeft
8988 };
8989 },
8990
8991 position: function() {
8992 if ( !this[ 0 ] ) {
8993 return;
8994 }
8995
8996 var offsetParent, offset,
8997 elem = this[ 0 ],
8998 parentOffset = { top: 0, left: 0 };
8999
9000 // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
9001 if ( jQuery.css( elem, "position" ) === "fixed" ) {
9002 // We assume that getBoundingClientRect is available when computed position is fixed
9003 offset = elem.getBoundingClientRect();
9004
9005 } else {
9006 // Get *real* offsetParent
9007 offsetParent = this.offsetParent();
9008
9009 // Get correct offsets
9010 offset = this.offset();
9011 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9012 parentOffset = offsetParent.offset();
9013 }
9014
9015 // Add offsetParent borders
9016 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
9017 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
9018 }
9019
9020 // Subtract parent offsets and element margins
9021 return {
9022 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9023 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9024 };
9025 },
9026
9027 offsetParent: function() {
9028 return this.map(function() {
9029 var offsetParent = this.offsetParent || docElem;
9030
9031 while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
9032 offsetParent = offsetParent.offsetParent;
9033 }
9034
9035 return offsetParent || docElem;
9036 });
9037 }
9038});
9039
9040// Create scrollLeft and scrollTop methods
9041jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9042 var top = "pageYOffset" === prop;
9043
9044 jQuery.fn[ method ] = function( val ) {
9045 return access( this, function( elem, method, val ) {
9046 var win = getWindow( elem );
9047
9048 if ( val === undefined ) {
9049 return win ? win[ prop ] : elem[ method ];
9050 }
9051
9052 if ( win ) {
9053 win.scrollTo(
9054 !top ? val : window.pageXOffset,
9055 top ? val : window.pageYOffset
9056 );
9057
9058 } else {
9059 elem[ method ] = val;
9060 }
9061 }, method, val, arguments.length, null );
9062 };
9063});
9064
9065// Add the top/left cssHooks using jQuery.fn.position
9066// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9067// getComputedStyle returns percent when specified for top/left/bottom/right
9068// rather than make the css module depend on the offset module, we just check for it here
9069jQuery.each( [ "top", "left" ], function( i, prop ) {
9070 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9071 function( elem, computed ) {
9072 if ( computed ) {
9073 computed = curCSS( elem, prop );
9074 // if curCSS returns percentage, fallback to offset
9075 return rnumnonpx.test( computed ) ?
9076 jQuery( elem ).position()[ prop ] + "px" :
9077 computed;
9078 }
9079 }
9080 );
9081});
9082
9083
9084// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9085jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9086 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
9087 // margin is only for outerHeight, outerWidth
9088 jQuery.fn[ funcName ] = function( margin, value ) {
9089 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9090 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9091
9092 return access( this, function( elem, type, value ) {
9093 var doc;
9094
9095 if ( jQuery.isWindow( elem ) ) {
9096 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9097 // isn't a whole lot we can do. See pull request at this URL for discussion:
9098 // https://github.com/jquery/jquery/pull/764
9099 return elem.document.documentElement[ "client" + name ];
9100 }
9101
9102 // Get document width or height
9103 if ( elem.nodeType === 9 ) {
9104 doc = elem.documentElement;
9105
9106 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
9107 // whichever is greatest
9108 return Math.max(
9109 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9110 elem.body[ "offset" + name ], doc[ "offset" + name ],
9111 doc[ "client" + name ]
9112 );
9113 }
9114
9115 return value === undefined ?
9116 // Get width or height on the element, requesting but not forcing parseFloat
9117 jQuery.css( elem, type, extra ) :
9118
9119 // Set width or height on the element
9120 jQuery.style( elem, type, value, extra );
9121 }, type, chainable ? margin : undefined, chainable, null );
9122 };
9123 });
9124});
9125
9126
9127// The number of elements contained in the matched element set
9128jQuery.fn.size = function() {
9129 return this.length;
9130};
9131
9132jQuery.fn.andSelf = jQuery.fn.addBack;
9133
9134
9135
9136
9137// Register as a named AMD module, since jQuery can be concatenated with other
9138// files that may use define, but not via a proper concatenation script that
9139// understands anonymous AMD modules. A named AMD is safest and most robust
9140// way to register. Lowercase jquery is used because AMD module names are
9141// derived from file names, and jQuery is normally delivered in a lowercase
9142// file name. Do this after creating the global so that if an AMD module wants
9143// to call noConflict to hide this version of jQuery, it will work.
9144
9145// Note that for maximum portability, libraries that are not jQuery should
9146// declare themselves as anonymous modules, and avoid setting a global if an
9147// AMD loader is present. jQuery is a special case. For more information, see
9148// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
9149
9150if ( typeof define === "function" && define.amd ) {
9151 define( "jquery", [], function() {
9152 return jQuery;
9153 });
9154}
9155
9156
9157
9158
9159var
9160 // Map over jQuery in case of overwrite
9161 _jQuery = window.jQuery,
9162
9163 // Map over the $ in case of overwrite
9164 _$ = window.$;
9165
9166jQuery.noConflict = function( deep ) {
9167 if ( window.$ === jQuery ) {
9168 window.$ = _$;
9169 }
9170
9171 if ( deep && window.jQuery === jQuery ) {
9172 window.jQuery = _jQuery;
9173 }
9174
9175 return jQuery;
9176};
9177
9178// Expose jQuery and $ identifiers, even in
9179// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
9180// and CommonJS for browser emulators (#13566)
9181if ( typeof noGlobal === strundefined ) {
9182 window.jQuery = window.$ = jQuery;
9183}
9184
9185
9186
9187
9188return jQuery;
9189
9190}));
diff --git a/webapp/vendor/spoticon.svg b/webapp/vendor/spoticon.svg
new file mode 100644
index 0000000..38706f5
--- /dev/null
+++ b/webapp/vendor/spoticon.svg
@@ -0,0 +1,691 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3<svg xmlns="http://www.w3.org/2000/svg"
4><metadata
5></metadata
6><defs
7><font horiz-adv-x="2016"
8><font-face font-family="Spoticon" units-per-em="2016" ascent="2016" descent="-2"
9></font-face
10><missing-glyph horiz-adv-x="2016" d=""
11></missing-glyph
12><glyph unicode="&#xd;" d=""
13></glyph
14><glyph unicode=" " d=""
15></glyph
16><glyph unicode="-" d="M378 882H1638v252H378V882Z"
17></glyph
18><glyph unicode="0" d="M1763 1764V252H251V1764H1763ZM1461 554v908H553V554h908Z"
19></glyph
20><glyph unicode="1" d="M1310 1764V252H1008V1462H706v302h604Z"
21></glyph
22><glyph unicode="2" d="M1764 1764V857H554V554H1764V252H252v907H1462v303H252v302H1764Z"
23></glyph
24><glyph unicode="3" d="M1764 1764V252H252V554H1462V857H857v302h605v303H252v302H1764Z"
25></glyph
26><glyph unicode="4" d="M554 1764V1159h908v605h302V252H1462V857H252v907H554Z"
27></glyph
28><glyph unicode="5" d="M1764 1462H554V1159H1764V252H252V554H1462V857H252v907H1764V1462Z"
29></glyph
30><glyph unicode="6" d="M1764 1764V1462H554V1159H1764V252H252V1764H1764ZM1462 554V857H554V554h908Z"
31></glyph
32><glyph unicode="7" d="M1764 1764V252H1462V1462H252v302H1764Z"
33></glyph
34><glyph unicode="8" d="M1764 1764V252H252V1764H1764ZM1462 1159v303H554V1159h908ZM1462 554V857H554V554h908Z"
35></glyph
36><glyph unicode="9" d="M1764 1764V252H1462V857H252v907H1764ZM1462 1159v303H554V1159h908Z"
37></glyph
38><glyph unicode="a" d="M554 857V252H252V1764H1764V252H1462V857H554ZM1462 1159v303H554V1159h908Z"
39></glyph
40><glyph unicode="b" d="M1764 857V252H252V1764H1764V1159H1462V857h302ZM554 1462V1159h908v303H554ZM554 554h908V857H554V554Z"
41></glyph
42><glyph unicode="c" d="M1764 1764V1462H554V554H1764V252H252V1764H1764Z"
43></glyph
44><glyph unicode="d" d="M1462 1764V1462h302V554H1462v908H554V554h908V252H252V1764H1462Z"
45></glyph
46><glyph unicode="e" d="M1764 1764V1462H554V1159h605V857H554V554H1764V252H252V1764H1764Z"
47></glyph
48><glyph unicode="f" d="M1764 1764V1462H554V1159h605V857H554V252H252V1764H1764Z"
49></glyph
50><glyph unicode="g" d="M1764 1764V1462H554V554h908V857H857v302h907V252H252V1764H1764Z"
51></glyph
52><glyph unicode="h" d="M554 857V252H252V1764H554V1159h908v605h302V252H1462V857H554Z"
53></glyph
54><glyph unicode="i" d="M1159 1764V252H857V1764h302Z"
55></glyph
56><glyph unicode="j" d="M554 857V554h908V1764h302V252H252V857H554Z"
57></glyph
58><glyph unicode="k" d="M554 857V252H252V1764H554V1159h605V857h303V554h302V252H1462V554H1159V857H554ZM1159 1462h303V1159H1159v303ZM1764 1764V1462H1462v302h302Z"
59></glyph
60><glyph unicode="l" d="M554 1764V554H1764V252H252V1764H554Z"
61></glyph
62><glyph unicode="m" d="M554 1462V252H252V1764H1764V252H1462V1462H1159V252H857V1462H554Z"
63></glyph
64><glyph unicode="n" d="M554 1462V252H252V1764H1764V252H1462V1462H554Z"
65></glyph
66><glyph unicode="o" d="M1764 1764V252H252V1764H1764ZM1462 554v908H554V554h908Z"
67></glyph
68><glyph unicode="p" d="M1764 1764V857H554V252H252V1764H1764ZM1462 1159v303H554V1159h908Z"
69></glyph
70><glyph unicode="q" d="M1762 1894V382H1134V123H882V382H250V1894H1762ZM1460 685v907H552V685H882v320h252V685h326Z"
71></glyph
72><glyph unicode="r" d="M554 857V252H252V1764H1764V857H1462V554h302V252H1462V554H1159V857H554ZM1462 1159v303H554V1159h908Z"
73></glyph
74><glyph unicode="s" d="M1764 1764V1462H554V1159H1764V252H252V554H1462V857H252v907H1764Z"
75></glyph
76><glyph unicode="t" d="M1764 1764V1462H1159V252H857V1462H252v302H1764Z"
77></glyph
78><glyph unicode="u" d="M554 1764V554h908V1764h302V252H252V1764H554Z"
79></glyph
80><glyph unicode="v" d="M252 857v907H554V857H857V554h302V252H857V554H554V857H252ZM1462 857V554H1159V857h303ZM1764 1764V857H1462v907h302Z"
81></glyph
82><glyph unicode="w" d="M554 1764V554H857V1764h302V554h303V1764h302V252H252V1764H554Z"
83></glyph
84><glyph unicode="x" d="M252 1462v302H554V1462H857V1159h302V857h303V554h302V252H1462V554H1159V857H857v302H554v303H252ZM554 554V252H252V554H554ZM857 857V554H554V857H857ZM1462 1462V1159H1159v303h303ZM1764 1764V1462H1462v302h302Z"
85></glyph
86><glyph unicode="y" d="M252 1462v302H554V1462H857V1159h302V252H857v907H554v303H252ZM1462 1462V1159H1159v303h303ZM1764 1764V1462H1462v302h302Z"
87></glyph
88><glyph unicode="z" d="M1764 1764V1462H1462V1159H1159v303H252v302H1764ZM554 554V857H857V554h907V252H252V554H554ZM1159 1159V857H857v302h302Z"
89></glyph
90><glyph unicode="&#xa0;" d=""
91></glyph
92><glyph unicode="&#x2000;" d=""
93></glyph
94><glyph unicode="&#x2001;" d=""
95></glyph
96><glyph unicode="&#x2002;" d=""
97></glyph
98><glyph unicode="&#x2003;" d=""
99></glyph
100><glyph unicode="&#x2004;" d=""
101></glyph
102><glyph unicode="&#x2005;" d=""
103></glyph
104><glyph unicode="&#x2006;" d=""
105></glyph
106><glyph unicode="&#x2007;" d=""
107></glyph
108><glyph unicode="&#x2008;" d=""
109></glyph
110><glyph unicode="&#x2009;" d=""
111></glyph
112><glyph unicode="&#x200a;" d=""
113></glyph
114><glyph unicode="&#x202f;" d=""
115></glyph
116><glyph unicode="&#xf100;" d="M126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM732 1008q0 114 81 195t195 81t195 -81t81 -195T1203 813T1008 732T813 813t-81 195Z"
117></glyph
118><glyph unicode="&#xf101;" d="M126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM732 1008q0 114 81 195t195 81t195 -81t81 -195T1203 813T1008 732T813 813t-81 195Z"
119></glyph
120><glyph unicode="&#xf102;" d="M1147 1605l250 -452q58 -19 115 -19q157 0 267.5 110.5T1890 1512t-110.5 267.5T1512 1890q-65 0 -125.5 -21.5T1279 1809t-81.5 -90.5T1147 1605ZM399 681l816 411l-208 377L228 987q-12 -8 -22.5 -17t-19 -20T171 927.5T159.5 903T152 877t-3.5 -27T149 822.5T153 795Q56 685 29 577Q-7 427 87 291q15 -22 35.5 -38t40 -25T210 215t48.5 -5t55 2t53.5 6t56 8q59 9 93 13t82 4.5T684.5 233T756 199V0h252V768L756 641V308q-32 14 -70 21t-69 8.5T543 336t-67 -6.5T408 320q-31 -5 -51.5 -8t-45 -5.5T271 304t-34 2t-30 6.5T184 325t-19 20Q95 446 121 554q19 76 83 155q40 -36 93 -44t102 16Z"
121></glyph
122><glyph unicode="&#xf103;" d="M1146 1607l251 -454q58 -19 115 -19q157 0 267.5 110.5T1890 1512t-110.5 267.5T1512 1890q-131 0 -232.5 -80T1146 1607ZM399 681l816 411l-208 377L228 987Q179 957 158.5 902.5T151 793Q107 742 75 688T29 577Q-8 427 87 291q15 -22 35.5 -37.5t40 -25T210 215t48.5 -5t54.5 2t53.5 6t56.5 8q60 10 93.5 13.5t82 4.5T685 234t71 -34V0h252V831L756 704V308q-40 17 -84 24.5t-95 5t-82.5 -6T408 320q-56 -9 -87.5 -12.5t-66 -3T199 315t-34 30Q95 446 121 554q19 75 82 154q40 -35 93.5 -43T399 681Z"
123></glyph
124><glyph unicode="&#xf104;" d="M155 148Q18 285 7 487Q2 585 45.5 688.5T177 880L1192 1895q77 77 171 105.5t188 3.5q92 -25 162 -95t95 -162q25 -94 -3.5 -188T1699 1388L728 417Q644 333 547.5 322T384 378q-86 86 -43 216q23 67 82 127l682 682q21 21 51 21q30 0 51 -21t21 -51t-21 -51L525 619Q484 578 473.5 535.5T485 479q17 -17 47 -14q45 4 95 54l971 971q103 103 72 220q-15 56 -58 98.5t-98 57.5q-118 31 -221 -72L278 779Q211 712 178.5 636T151 489Q160 347 257 250T495 144q71 -5 147 27.5T785 271L1801 1287q21 21 51 21q29 0 50 -21t21 -51t-21 -51L887 170Q717 0 507 0Q408 0 316.5 39T155 148Z"
125></glyph
126><glyph unicode="&#xf105;" d="M148 148Q11 285 0 487q-5 98 38.5 201.5T170 880L1185 1895q77 77 171.5 105.5T1545 2004q92 -25 162 -95t95 -162q25 -93 -4 -187.5T1692 1388L722 417Q638 333 540.5 322T377 377q-85 85 -43 217q22 67 82 127l682 682q21 21 51 21q30 0 51 -21t21 -51t-21 -51L518 619Q477 578 466.5 535.5T478 479q17 -17 47 -14q45 4 95 54l971 970q103 103 72 221q-15 56 -57.5 98.5T1507 1866q-117 31 -220 -72L725 1232Q458 966 271 779Q204 712 171.5 636T144 489Q153 347 250 250T489 144q71 -5 147 27.5T779 271L1794 1287q21 21 51 21q29 0 50 -21t21 -51t-21 -51L880 170Q710 0 500 0Q401 0 309.5 39T148 148Z"
127></glyph
128><glyph unicode="&#xf106;" d="M1670 1008q0 -134 -52.5 -256.5T1476 540T1264.5 398.5T1008 346T751.5 398.5T540 540T398.5 751.5T346 1008t52.5 256.5T540 1476t211.5 141.5T1008 1670q108 0 208.5 -33.5t182 -95t143 -143t95 -182T1670 1008ZM252 1008q0 -154 60 -294T473 473T714 312t294 -60t294 60t241 161t161 241t60 294t-60 294t-161 241t-241 161t-294 60T714 1704T473 1543T312 1302T252 1008ZM1386 1134H630q-52 0 -89 -37t-37 -89t37 -89t89 -37h756q52 0 89 37t37 89t-37 89t-89 37Z"
129></glyph
130><glyph unicode="&#xf107;" d="M1670 1008q0 -134 -52.5 -256.5T1476 540T1264.5 398.5T1008 346T751.5 398.5T540 540T398.5 751.5T346 1008t52.5 256.5T540 1476t211.5 141.5T1008 1670q108 0 208.5 -33.5t182 -95t143 -143t95 -182T1670 1008ZM252 1008q0 -154 60 -294T473 473T714 312t294 -60t294 60t241 161t161 241t60 294t-60 294t-161 241t-241 161t-294 60T714 1704T473 1543T312 1302T252 1008ZM1386 1134H630q-52 0 -89 -37t-37 -89t37 -89t89 -37h756q52 0 89 37t37 89t-37 89t-89 37Z"
131></glyph
132><glyph unicode="&#xf108;" d="M1847 1932q0 34 -24.5 59t-59.5 25H254q-34 0 -59 -25t-25 -59V1764H1847v168ZM96 1134q-40 0 -60.5 -27.5T26 1040L307 93Q318 55 355 27.5T432 0H1581q41 0 77.5 27.5T1706 94l281 947q11 38 -9.5 65.5T1917 1134H96ZM1008 128q-135 0 -254.5 49.5T554.5 316T458 515q-19 126 47 239T705.5 936.5T1008 1006q169 0 303.5 -69.5T1512 754t47 -239Q1542 405 1462.5 316T1263 177.5T1008 128ZM1008 410q-55 0 -95.5 30.5T871 515q-2 45 38.5 78t98.5 33q59 0 99.5 -33T1146 515q-1 -44 -41.5 -74.5T1008 410ZM511 1260q67 112 199 180t298 68q167 0 299 -68t199 -180h412l84 293q10 35 -9 60t-55 25H86q-36 0 -55 -25T21 1553L99 1260H511Z"
133></glyph
134><glyph unicode="&#xf109;" d="M1846 1932q0 34 -25 59t-59 25H253q-35 0 -59.5 -25T169 1932V1764H1846v168ZM95 1134q-40 0 -60.5 -27.5T25 1041L306 94Q317 55 354 27.5T431 0H1580q41 0 77.5 27.5T1705 94l281 947q11 38 -9.5 65.5T1916 1134H95ZM1008 128q-135 0 -255 49.5T553.5 316T457 515q-14 95 21.5 184.5t109 157T771 965t237 41q126 0 236.5 -41T1428 856.5t108.5 -157T1558 515Q1541 405 1461.5 316T1262 177.5T1008 128ZM1008 410q-56 0 -96.5 30.5T870 515q-2 46 38.5 78.5T1008 626q58 0 98.5 -32.5T1145 515q-1 -44 -41.5 -74.5T1008 410ZM510 1260q67 112 199 180t299 68q166 0 298 -68t199 -180h413l83 294q10 34 -9 59t-55 25H86q-37 0 -56 -25T20 1553L98 1260H510Z"
135></glyph
136><glyph unicode="&#xf10a;" d="M801 331L297 794q-37 33 -39 82.5t31.5 86t83 39T459 970L848 614l558 1079q23 44 70 59t91 -7.5t59 -70t-8 -91.5L988 364Q961 312 903 302q-11 -2 -21 -2q-22 0 -43 8t-38 23Z"
137></glyph
138><glyph unicode="&#xf10b;" d="M801 331L297 794q-37 33 -39 82.5t31.5 86t83 39T459 970L848 614l558 1079q23 44 70 59t91 -7.5t59 -70t-8 -91.5L988 364Q961 312 903 302q-11 -2 -21 -2q-22 0 -43 8t-38 23Z"
139></glyph
140><glyph unicode="&#xf10c;" d="M945 429L189 1185q-29 29 -29 70t29 69t70 28t69 -28L1008 643l693 693q29 28 70 28t69 -28t28 -69t-28 -69L1084 442q-38 -38 -76 -38t-63 25Z"
141></glyph
142><glyph unicode="&#xf10d;" d="M939 435L183 1191q-29 29 -29 67t29 66t66.5 28T315 1324L1008 637l687 687q29 28 66.5 28t65.5 -28q29 -28 29 -66t-29 -67L1071 435q-17 -25 -63 -25q-44 0 -69 25Z"
143></glyph
144><glyph unicode="&#xf10e;" d="M1197 176L441 932q-28 29 -28 70t28 69l756 756q28 28 69 28t69.5 -28t28.5 -69t-28 -70L643 1008L1336 315q11 -11 18 -25t9 -29t0 -30t-9 -29t-18 -26q-17 -8 -26.5 -12T1286 155.5T1260 151q-38 0 -63 25Z"
145></glyph
146><glyph unicode="&#xf10f;" d="M1191 183L435 939q-19 18 -25.5 42t0 47.5T435 1071l756 756q28 28 66 28t66 -28t28 -66t-28 -66L636 1008L1323 321q28 -28 28 -66t-28 -66q-16 -31 -63 -31q-10 0 -19 1t-18 4t-17 8t-15 12Z"
147></glyph
148><glyph unicode="&#xf110;" d="M693 176q-19 19 -25.5 44.5t0 50.5T693 315l680 693L693 1701q-28 28 -28 69t28 69.5t69 28.5t70 -28l756 -756q14 -14 21 -32.5t7 -37t-7 -37T1588 945L832 189Q813 170 794 160.5T756 151q-38 0 -63 25Z"
149></glyph
150><glyph unicode="&#xf111;" d="M687 183q-14 14 -21.5 31T658 248.5t7.5 35T687 315l693 693L687 1695q-8 8 -14 17t-9.5 19t-4.5 20t0 20t4.5 20t9.5 19t14 17q28 28 66 28t66 -28l756 -756q28 -28 28 -66t-28 -66L819 183Q802 158 756 158q-44 0 -69 25Z"
151></glyph
152><glyph unicode="&#xf112;" d="M1701 680l-693 693L315 680q-9 -9 -20.5 -15.5T271 655t-25 -3t-25 3t-23.5 9.5T176 680q-18 19 -24.5 44.5t0 50.5T176 819l756 756q19 19 44.5 25.5t50.5 0t44 -25.5L1827 819q14 -14 21 -32.5t7 -37t-7 -37T1827 680q-25 -25 -63 -25t-63 25Z"
153></glyph
154><glyph unicode="&#xf113;" d="M1695 687l-687 693L321 687Q303 668 279 661.5t-47.5 0T189 687q-28 28 -28 66t28 66l756 756q7 7 15 12.5t16.5 9t17 5t17.5 1.5t18 -1.5t17 -5t16 -9t15 -12.5L1833 819q29 -28 29 -66t-29 -66q-25 -25 -69 -25q-20 0 -38 5.5T1695 687Z"
155></glyph
156><glyph unicode="&#xf114;" d="M1865 1877q-13 13 -51 13L806 1638q-20 -11 -35 -28t-15 -35V592Q653 617 592 604Q479 585 397 495.5T315 302q0 -102 80.5 -155T592 113q123 29 206.5 112T882 403v882l882 214V793q-100 26 -151 13Q1500 787 1418 697.5T1336 504q0 -103 81 -156t196 -33q117 39 197 126.5T1890 630V1827q0 23 -25 50ZM315 2016q-132 0 -223.5 -91.5T0 1701Q0 1568 91.5 1477T315 1386t223.5 91T630 1701q0 132 -91.5 223.5T315 2016ZM315 1915q85 0 149.5 -64.5T529 1701T464.5 1551T315 1486t-149.5 65T101 1701t64.5 149.5T315 1915Z"
157></glyph
158><glyph unicode="&#xf115;" d="M1865 1877q-22 22 -51 13L806 1638q-20 -6 -35 -23.5T756 1575V585q-63 27 -157 7Q481 573 398 487.5T315 302q0 -99 83 -152.5T599 119q114 24 196.5 108T882 409v882l882 214V806q-64 28 -157 6Q1489 789 1406 702T1323 516t83 -152.5T1607 333q118 20 200.5 106.5T1890 630V1827q0 33 -25 50ZM315 2016q-132 0 -223.5 -91.5T0 1701Q0 1568 91.5 1477T315 1386t223.5 91T630 1701q0 132 -91.5 223.5T315 2016ZM315 1915q90 0 152 -62.5T529 1701q0 -90 -62 -152.5T315 1486t-152 62.5T101 1701q0 89 62 151.5T315 1915Z"
159></glyph
160><glyph unicode="&#xf116;" d="M387 252H369q-48 0 -82.5 34.5T252 369V1647q0 48 34.5 82.5T369 1764h18q31 0 58 -16t43 -43t16 -58V369q0 -48 -34.5 -82.5T387 252ZM891 252H873q-48 0 -82.5 34.5T756 369V1647q0 19 6 36.5t17 32t25.5 25.5t32 17t36.5 6h18q31 0 58 -16t43 -43t16 -58V369q0 -24 -9.5 -45.5t-25 -37t-37 -25T891 252ZM1767 302l-38 -12q-42 -12 -81 9t-51 63L1219 1597q-12 43 8.5 82t60.5 50l38 13q30 7 56.5 1t47.5 -26t28 -47L1836 435q7 -21 4 -42.5T1828 353t-25 -31.5T1767 302Z"
161></glyph
162><glyph unicode="&#xf117;" d="M384 252H372q-49 0 -84.5 34.5T252 372V1644q0 35 15.5 62t42.5 42.5t62 15.5h19q23 0 44 -9t36 -24.5t24 -38t9 -48.5V372q0 -49 -34.5 -84.5T384 252ZM888 252H869q-48 0 -83.5 34.5T750 372V1644q0 49 34 84.5t85 35.5h19q49 0 84.5 -34.5T1008 1644V372q0 -49 -34.5 -84.5T888 252ZM1764 302l-38 -12q-42 -14 -80 6t-52 63L1216 1594q-14 42 6 80t63 52l38 13q42 14 80 -6.5t52 -62.5L1833 435q14 -42 -6 -80t-63 -53Z"
163></glyph
164><glyph unicode="&#xf11a;" d="M126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM236 1008q0 157 61.5 300T462 1554t246 164.5t300 61.5t300 -61.5T1554 1554t164.5 -246T1780 1008T1718.5 708T1554 462T1308 297.5T1008 236T708 297.5T462 462T297.5 708T236 1008ZM1134 1443q0 28 -20.5 48.5T1065 1512H951q-28 0 -48.5 -20.5T882 1443V1008H579q-31 0 -37.5 -15.5T557 955L955 557q22 -22 53 -22t53 22l398 398q14 14 16.5 26.5t-8 19.5t-30.5 7H1134v435Z"
165></glyph
166><glyph unicode="&#xf11b;" d="M126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM220 1008q0 160 62.5 306t168 251.5t251.5 168t306 62.5t306 -62.5t251.5 -168t168 -251.5T1796 1008T1733.5 702t-168 -251.5T1314 282.5T1008 220T702 282.5t-251.5 168T282.5 702T220 1008ZM1134 1008v435q0 28 -20.5 48.5T1065 1512H951q-28 0 -48.5 -20.5T882 1443V1008H579q-31 0 -37.5 -15.5T557 955L955 557q22 -22 53 -22t53 22l398 398q14 14 16.5 26.5t-8 19.5t-30.5 7H1134Z"
167></glyph
168><glyph unicode="&#xf11c;" d="M1008 2016q418 0 714 -92q136 -43 215 -101.5T2016 1701V1512L1260 756V126q0 -52 -74 -89T1008 0T830 37t-74 89V756L0 1512v189q0 63 79 121.5T295 1924q131 41 321 67q184 25 392 25ZM130 1701q16 -19 56 -42q75 -43 191 -74q267 -73 631 -73t631 73q116 31 191 74q40 23 56 42q-16 19 -56 42q-75 43 -191 74q-267 73 -631 73T377 1817Q261 1786 186 1743q-40 -23 -56 -42Z"
169></glyph
170><glyph unicode="&#xf11d;" d="M1008 2016q418 0 714 -92q136 -43 215 -101.5T2016 1701V1512L1260 756V126q0 -52 -74 -89T1008 0T830 37t-74 89V756L0 1512v189q0 63 79 121.5T295 1924q131 41 321 67q184 25 392 25ZM130 1701q16 -19 56 -42q73 -42 191 -73q273 -74 631 -74t631 74q118 31 191 73q40 23 56 42q-16 19 -56 42q-73 42 -191 73q-273 74 -631 74T377 1816Q259 1785 186 1743q-40 -23 -56 -42Z"
171></glyph
172><glyph unicode="&#xf11e;" d="M126 1827V0H252V1827q0 28 -17.5 45.5T189 1890t-45.5 -17.5T126 1827ZM1789 756H479q-38 0 -69.5 31.5T378 857v806q0 15 5.5 30t15.5 27.5t22.5 22.5t27.5 15.5t30 5.5H1789q39 0 52 -23.5T1827 1688L1537 1336q-28 -29 -28 -76t28 -76L1827 832q27 -29 14 -52.5T1789 756Z"
173></glyph
174><glyph unicode="&#xf11f;" d="M126 1827V0H252V1827q0 28 -17.5 45.5T189 1890t-45.5 -17.5T126 1827ZM1789 756H479q-38 0 -69.5 31.5T378 857v806q0 15 5.5 30t15.5 27.5t22.5 22.5t27.5 15.5t30 5.5H1789q39 0 52 -23.5T1827 1688L1537 1336q-28 -29 -28 -76t28 -76L1827 832q27 -29 14 -52.5T1789 756Z"
175></glyph
176><glyph unicode="&#xf120;" d="M1619 454Q1547 372 1455 328T1260 284q-68 0 -133.5 21.5t-121.5 59T901 454Q828 434 760.5 409T661 368L630 353Q596 334 567 299T521 221.5T504 139q0 -28 11 -53.5T545.5 41T592 11T649 0H1865q61 0 103 41.5T2010 145q4 56 -31.5 117.5T1890 353q-12 6 -34.5 16.5t-93 37.5T1619 454ZM781 630H145q-19 0 -19 19q0 25 20 58.5T189 750q15 7 42.5 20t113 41.5T517 857Q473 882 397 958Q351 945 306 930T230 902.5t-55.5 -23T138 863l-12 -6Q100 843 77 819T37 766.5t-27 -61T0 643Q0 605 19 573.5T71.5 523T145 504H649q13 6 28 11.5t31 11T742 538t37 11.5T819 561q-6 9 -13 21.5T794.5 604T781 630ZM680 1046v31q-37 19 -72 53.5t-64 81T493 1312t-34 115.5T447 1550q0 159 83 249.5T756 1890q123 0 203 -70.5T1058 1625q76 26 126 26q-21 116 -84 200T949 1975.5T756 2016q-72 0 -137 -19T499.5 1939.5t-94 -93t-62 -129T321 1556q0 -80 18 -161.5T390.5 1240t78 -133.5T569.5 1004T687 945q-7 31 -7 101ZM1260 435q-70 0 -137 35.5T1003 567T909.5 706.5T847 874.5T825 1052q0 108 34.5 196T953 1393.5t138 88t169 30.5t169 -30.5t138 -88T1660.5 1248T1695 1052q0 -110 -35 -221T1567.5 632.5T1428.5 490T1260 435Z"
177></glyph
178><glyph unicode="&#xf121;" d="M147 504Q86 504 43 546T0 647q0 38 17.5 80.5t47 78T129 860q4 2 12 6t35 16.5t56 24T306.5 933T397 960q9 -9 17.5 -18t18 -17.5T451 908Q272 866 159 804Q121 784 92 736T63 647q0 -33 24.5 -56.5T147 567H630V504H147ZM680 1014q-33 13 -65.5 36.5t-61 55t-54.5 70t-46 83T418 1351t-23 99.5T387 1553q0 182 100.5 291T756 1953q145 0 241 -82.5T1117 1645q11 2 21 4t20.5 3.5t21.5 3.5q-29 170 -145.5 265T756 2016q-51 0 -99 -10t-91 -30t-80 -48.5t-67 -67t-51 -85t-32.5 -103T324 1553q0 -99 28 -200t75.5 -183.5T543 1026.5T686 946q-4 34 -6 68ZM1260 432q87 0 168 54.5t138 142T1657.5 827t34.5 222q0 109 -34 197.5t-93 146T1428 1481t-168 31t-168 -31T955 1392.5t-93 -146T828 1049q0 -74 15.5 -149.5T887 756.5T955 629t87 -103.5T1145.5 457T1260 432ZM1619 456Q1460 283 1260 283q-102 0 -193 45.5T901 456Q856 444 811.5 429T736 401.5t-55 -23T645 362l-12 -6Q612 344 592.5 326.5T557 287T529 241T510.5 191.5T504 143Q504 84 547 42T651 0H1869q30 0 57 11.5T1973 42t31.5 45.5T2016 143q0 38 -17.5 80.5t-47 78T1887 356q-12 6 -34 16.5T1761 410t-142 46Z"
179></glyph
180><glyph unicode="&#xf122;" d="M1663 1166q-24 102 -80 193l81 108q23 31 20.5 73t-30.5 69l-45 45q-27 28 -69 30.5T1467 1664l-108 -81q-91 56 -193 80l-19 133q-5 39 -37 66.5t-70 27.5H976q-38 0 -70 -27.5T869 1796L850 1663q-52 -12 -100 -32.5T657 1583l-108 81q-20 15 -46.5 19.5t-52 -3.5T407 1654l-45 -45q-28 -27 -30.5 -69T352 1467l81 -108q-56 -91 -80 -193L220 1147q-39 -5 -66.5 -37T126 1040V976q0 -19 7.5 -37.5t20 -33t30 -24.5T220 869L353 850q8 -35 20 -68t27 -64t33 -61L352 549Q329 518 331.5 476T362 407l45 -45q27 -28 69 -30.5T549 352l108 81q91 -56 193 -80L869 220q3 -26 19 -47.5t39.5 -34T976 126h64q25 0 48.5 12.5t39.5 34t19 47.5l19 133q52 12 100 32.5t93 47.5l108 -81q12 -9 27 -14.5t30.5 -6t31 2.5t29.5 10t24 18l45 45q28 27 30.5 69T1664 549l-81 108q9 15 17.5 30t16 30.5t14 32t12.5 33t11 33t9 34.5l133 19q39 5 66.5 37t27.5 70v64q0 25 -12.5 48.5t-34 39.5t-47.5 19l-133 19ZM613 1008q0 107 53 198t144 144t198 53t198 -53t144 -144t53 -198T1350 810T1206 666T1008 613T810 666T666 810t-53 198Z"
181></glyph
182><glyph unicode="&#xf123;" d="M1664 1166q-24 103 -80 194l80 107q23 31 20.5 73t-30.5 69l-45 45q-27 28 -69 30.5T1467 1664l-107 -80q-91 56 -194 80l-19 132q-5 39 -37 66.5t-70 27.5H976q-38 0 -70 -27.5T869 1796L850 1664Q747 1640 656 1584l-107 80q-31 23 -73 20.5T407 1654l-45 -45q-28 -27 -30.5 -69T352 1467l80 -107q-56 -91 -80 -194L220 1147q-39 -5 -66.5 -37T126 1040V976q0 -19 7.5 -37.5t20 -33t30 -24.5T220 869L352 850q12 -52 32.5 -100.5T432 656L352 549Q337 529 332.5 502.5t3.5 -52T362 407l45 -45q18 -18 43.5 -26t52 -3.5T549 352l107 80q18 -11 36 -20.5T729.5 393t39 -16.5t40 -13.5T850 352L869 220q5 -39 37 -66.5T976 126h64q38 0 70 27.5t37 66.5l19 132q35 8 68.5 20t64.5 27t61 33l107 -80q31 -23 73 -20.5t69 30.5l45 45q28 27 30.5 69T1664 549l-80 107q56 91 80 194l132 19q39 5 66.5 37t27.5 70v64q0 25 -12.5 48.5t-34 39.5t-47.5 19l-132 19ZM567 1008q0 120 59 221.5T786.5 1390t221.5 59t221.5 -59T1390 1229.5T1449 1008T1390 786.5T1229.5 626T1008 567T786.5 626T626 786.5T567 1008Z"
183></glyph
184><glyph unicode="&#xf124;" d="M1449 1764H567q-46 0 -85.5 -28.5T422 1663Q126 838 126 825V302q0 -12 7.5 -23.5t19 -19T176 252H1840q18 0 34 15.5t16 34.5V825q0 3 -10 34t-27.5 80T1813 1051t-46.5 131.5t-49 137t-47 130.5T1631 1559.5t-27 75.5t-10 28q-14 43 -56 72t-89 29ZM567 1638h882q6 0 25 -19L1732 882H1449q-12 0 -23.5 -4.5t-20.5 -12t-16 -18T1380 825L1317 504H712L649 825q-6 16 -18 29t-27 20.5T573 882H277l265 737q0 5 10 12t15 7Z"
185></glyph
186><glyph unicode="&#xf125;" d="M1449 1764H567q-46 0 -85.5 -28.5T422 1663Q126 838 126 825V302q0 -12 7.5 -23.5t19 -19T176 252H1840q18 0 34 15.5t16 34.5V825q0 3 -10 34t-27.5 80T1813 1051t-46.5 131.5t-49 137t-47 130.5T1631 1559.5t-27 75.5t-10 28q-14 43 -56 72t-89 29ZM567 1638h882q6 0 25 -19L1732 882H1449q-12 0 -23.5 -4.5t-20.5 -12t-16 -18T1380 825L1317 504H712L649 825q-6 16 -18 29t-27 20.5T573 882H277l265 737q0 5 10 12t15 7Z"
187></glyph
188><glyph unicode="&#xf126;" d="M1265 328q7 -6 8 -13t-5 -17.5T1256 280t-20 -23q-27 -30 -85.5 -77.5T1030 97Q956 56 849 28T631 0Q568 0 522.5 40T477 123q0 25 28 81q30 61 96 185q65 123 126 251L839 901q22 63 16 163l-3 48q0 31 -54 31q-22 0 -74.5 -48T624 993Q584 947 553 907q-19 -18 -36 -3l-29 28q-20 18 -9 27l21 29q36 52 121 146q82 93 207 170q132 82 273 82q45 0 79.5 -27t49.5 -65q14 -36 14 -69q0 -30 -9 -66q-16 -55 -27 -85q-8 -24 -18 -52q-8 -21 -24 -63q-3 -9 -26 -70L985 422q-2 -6 -11.5 -30T959 355Q943 315 941 308Q929 279 929 259q0 -43 42 -43q38 0 115.5 61.5T1196 382q12 15 26 3l43 -57ZM1358 1845q0 -82 -50 -142t-131 -60q-95 0 -147 49.5T978 1830q0 77 50 131.5t127 54.5q203 0 203 -171Z"
189></glyph
190><glyph unicode="&#xf127;" d="M1359 1841q0 -78 -55.5 -141T1171 1637q-97 0 -175.5 56T917 1828q0 72 58.5 130t133.5 58q106 0 178 -51t72 -124ZM1006 420q-7 -17 -15 -44q-6 -16 -13 -37q-3 -10 -10 -30.5T959 283q-8 -23 -9 -36q-1 -5 -1 -14q0 -43 36 -43q35 0 114.5 72.5T1208 380q4 6 12 7t12 -4l36 -37q3 -3 4.5 -6t2 -6t0.5 -5.5t-1.5 -6.5t-2.5 -6.5t-4 -6.5t-4 -6t-4.5 -6t-4.5 -6q-44 -61 -99 -111Q1070 103 967 57Q836 -2 684 -2q-59 0 -88.5 25.5T566 90q0 31 26 117q27 88 102 305q4 10 9 25.5t7 21.5q24 69 34 99l75 306q45 132 45 171q0 18 -10.5 29T825 1175q-28 0 -96 -68.5T612 970q-18 -18 -34 -3l-27 28q-18 18 -9 27l1 1q1 1 2 2.5t2 3.5q164 215 355 305q110 52 219 52q73 0 120 -27t47 -71q0 -47 -28 -124q-3 -9 -14.5 -41T1226 1067q-32 -88 -41 -115L1006 420Z"
191></glyph
192><glyph unicode="&#xf128;" d="M1512 1279q0 98 -38.5 188t-103 155T1217 1725.5T1030 1764H986q-56 0 -110 -12.5T774.5 1715T685 1658t-75 -75t-57 -89.5T516.5 1392T504 1282V1134q-53 -7 -89.5 -47.5T378 992V400q0 -39 19.5 -72.5t53 -53T523 255h970q39 0 72.5 19.5t53 53T1638 400V989q0 36 -17 67t-46 50.5t-63 24.5v148ZM1030 1638q72 0 138 -28.5t113.5 -76t76 -113.5T1386 1282V1134H630v148q0 72 28.5 138t76 113.5t113.5 76T986 1638h44Z"
193></glyph
194><glyph unicode="&#xf129;" d="M1512 1279q0 98 -38.5 188t-103 155T1217 1725.5T1030 1764H986q-56 0 -110 -12.5T774.5 1715T685 1658t-75 -75t-57 -89.5T516.5 1392T504 1282V1134q-53 -7 -89.5 -47.5T378 992V400q0 -39 19.5 -72.5t53 -53T523 255h970q39 0 72.5 19.5t53 53T1638 400V989q0 36 -17 67t-46 50.5t-63 24.5v148ZM1030 1638q72 0 138 -28.5t113.5 -76t76 -113.5T1386 1282V1134H630v148q0 72 28.5 138t76 113.5t113.5 76T986 1638h44Z"
195></glyph
196><glyph unicode="&#xf12a;" d="M0 1008Q0 721 202 479L63 151Q35 95 60 69.5T151 63L542 227Q764 126 1008 126q204 0 390.5 69.5t322 187t215.5 281t80 344.5t-80 344.5t-215.5 281t-322 187T1008 1890T617.5 1820.5t-322 -187T80 1352.5T0 1008ZM1210 554q-24 -31 -57 -58.5T1082.5 449t-78 -31.5t-81 -15t-78 4t-70.5 25T718 479q-12 12 -20 32t-9.5 44t4.5 50q11 47 48 89.5T828.5 764t106 42.5t109 12.5T1134 794v781q0 28 17.5 45.5T1197 1638t45.5 -17.5T1260 1575V756q0 -65 -11 -110t-39 -92Z"
197></glyph
198><glyph unicode="&#xf12b;" d="M0 1008Q0 721 202 479L63 151Q35 95 60 69.5T151 63L542 227Q764 126 1008 126q204 0 390.5 69.5t322 187t215.5 281t80 344.5t-80 344.5t-215.5 281t-322 187T1008 1890T617.5 1820.5t-322 -187T80 1352.5T0 1008ZM1210 554q-24 -31 -57 -58.5T1082.5 449t-78 -31.5t-81 -15t-78 4t-70.5 25T718 479q-12 12 -20 32t-9.5 44t4.5 50q11 47 48 89.5T828.5 764t106 42.5t109 12.5T1134 794v781q0 28 17.5 45.5T1197 1638t45.5 -17.5T1260 1575V756q0 -65 -11 -110t-39 -92Z"
199></glyph
200><glyph unicode="&#xf12c;" d="M479 1134q-47 0 -74 -27t-27 -74V970q0 -15 4.5 -28.5t13 -24.5T416 898.5t28 -12T479 882h63q38 0 63 27t25 74v50q0 31 -12 54t-35 35t-54 12H479ZM983 1134q-47 0 -74 -27t-27 -74V970q0 -38 27 -63t74 -25h63q38 0 63 27t25 74v50q0 47 -27 74t-74 27H983ZM1474 1134q-15 0 -28.5 -4.5t-24.5 -13T1402.5 1096t-12 -28t-4.5 -35V970q0 -38 27 -63t74 -25h63q38 0 63 27t25 74v50q0 47 -27 74t-74 27h-63ZM479 1134q-47 0 -74 -27t-27 -74V970q0 -15 4.5 -28.5t13 -24.5T416 898.5t28 -12T479 882h63q38 0 63 27t25 74v50q0 31 -12 54t-35 35t-54 12H479ZM983 1134q-47 0 -74 -27t-27 -74V970q0 -38 27 -63t74 -25h63q38 0 63 27t25 74v50q0 47 -27 74t-74 27H983ZM1474 1134q-15 0 -28.5 -4.5t-24.5 -13T1402.5 1096t-12 -28t-4.5 -35V970q0 -38 27 -63t74 -25h63q38 0 63 27t25 74v50q0 47 -27 74t-74 27h-63Z"
201></glyph
202><glyph unicode="&#xf12d;" d="M479 1134q-47 0 -74 -27t-27 -74V970q0 -15 4.5 -28.5t13 -24.5T416 898.5t28 -12T479 882h63q38 0 63 27t25 74v50q0 31 -12 54t-35 35t-54 12H479ZM983 1134q-47 0 -74 -27t-27 -74V970q0 -38 27 -63t74 -25h63q38 0 63 27t25 74v50q0 47 -27 74t-74 27H983ZM1474 1134q-15 0 -28.5 -4.5t-24.5 -13T1402.5 1096t-12 -28t-4.5 -35V970q0 -38 27 -63t74 -25h63q38 0 63 27t25 74v50q0 47 -27 74t-74 27h-63Z"
203></glyph
204><glyph unicode="&#xf12e;" d="M1008 0q71 0 130 36.5t92 97.5q-54 -4 -109.5 -6T1008 126q-113 0 -222 8Q819 73 878 36.5T1008 0ZM1644 1222q-6 67 -28 131.5T1558.5 1474t-82 104T1374 1663.5T1256 1724q2 13 3 22t1 18q0 104 -74 178t-178 74T830 1942T756 1764q0 -14 4 -40Q602 1663 494.5 1526.5T372 1222L322 662Q276 646 240 627.5t-61.5 -38T139.5 548T126 504q0 -68 118 -126.5t321 -92T1008 252t443 33.5t321 92T1890 504q0 30 -23.5 58t-67 53T1694 662l-50 560ZM1008 1922q65 0 111.5 -46.5T1166 1764q0 -2 -1 -4t-1.5 -4t-0.5 -3q-56 11 -112 11H965q-56 0 -112 -12q0 2 -1.5 6t-1.5 6q0 32 12.5 61t34 50.5t50.5 34t61 12.5Z"
205></glyph
206><glyph unicode="&#xf12f;" d="M1008 0q71 0 130 36.5t92 97.5q-54 -4 -109.5 -6T1008 126q-113 0 -222 8Q819 73 878 36.5T1008 0ZM1644 1222q-6 67 -28 131.5T1558.5 1474t-82 104T1374 1663.5T1256 1724q2 13 3 22t1 18q0 104 -74 178t-178 74T830 1942T756 1764q0 -14 4 -40Q602 1663 494.5 1526.5T372 1222L322 662Q276 646 240 627.5t-61.5 -38T139.5 548T126 504q0 -68 118 -126.5t321 -92T1008 252t443 33.5t321 92T1890 504q0 30 -23.5 58t-67 53T1694 662l-50 560ZM1008 1922q65 0 111.5 -46.5T1166 1764q0 -2 -1 -4t-1.5 -4t-0.5 -3q-56 11 -112 11H965q-56 0 -112 -12q0 2 -1.5 6t-1.5 6q0 32 12.5 61t34 50.5t50.5 34t61 12.5Z"
207></glyph
208><glyph unicode="&#xf130;" d="M630 252H504q-52 0 -89 37t-37 89V1638q0 52 37 89t89 37H630q52 0 89 -37t37 -89V378q0 -52 -37 -89T630 252ZM1512 252H1386q-52 0 -89 37t-37 89V1638q0 52 37 89t89 37h126q52 0 89 -37t37 -89V378q0 -52 -37 -89t-89 -37Z"
209></glyph
210><glyph unicode="&#xf131;" d="M693 252H567q-52 0 -89 37t-37 89V1638q0 52 37 89t89 37H693q52 0 89 -37t37 -89V378q0 -52 -37 -89T693 252ZM1449 252H1323q-52 0 -89 37t-37 89V1638q0 52 37 89t89 37h126q52 0 89 -37t37 -89V378q0 -52 -37 -89t-89 -37Z"
211></glyph
212><glyph unicode="&#xf132;" d="M504 1661V354q0 -61 40 -79.5T640 290L1674 924q56 34 56 83t-56 83L640 1725q-56 34 -96 15.5T504 1661Z"
213></glyph
214><glyph unicode="&#xf133;" d="M504 1661V354q0 -61 40 -80t96 16L1674 924q56 34 56 83t-56 83L640 1725q-56 34 -96 15.5T504 1661Z"
215></glyph
216><glyph unicode="&#xf134;" d="M1739 1880q-6 6 -16.5 9t-17.5 3t-17 0L680 1640q-39 -19 -48 -51q-2 -6 -2 -12V595q-17 4 -26 6t-24.5 5t-27 4.5t-26.5 2t-30 -1T466 607Q353 588 271 498.5T189 305q0 -68 37.5 -116t101 -67T466 116q123 28 206.5 111.5T756 406v882l882 214V796q-14 4 -21.5 5.5T1595 806t-22.5 4.5t-21 2.5t-22 1t-21 -1T1487 809Q1374 790 1292 700.5T1210 506q0 -67 37.5 -115T1348 324t139 -7q117 40 197 127t80 188V1829q0 17 -6.5 27.5T1739 1880Z"
217></glyph
218><glyph unicode="&#xf135;" d="M1739 1880q-6 6 -16.5 9t-17.5 3t-17 0L680 1640q-39 -19 -48 -51q-2 -6 -2 -12V595q-17 4 -26 6t-24.5 5t-27 4.5t-26.5 2t-30 -1T466 607Q353 588 271 498.5T189 305q0 -68 37.5 -116t101 -67T466 116q123 28 206.5 111.5T756 406v882l882 214V796q-14 4 -21.5 5.5T1595 806t-22.5 4.5t-21 2.5t-22 1t-21 -1T1487 809Q1374 790 1292 700.5T1210 506q0 -67 37.5 -115T1348 324t139 -7q117 40 197 127t80 188V1829q0 17 -6.5 27.5T1739 1880Z"
219></glyph
220><glyph unicode="&#xf136;" d="M1512 1896q0 24 -9.5 44.5t-25 33.5t-37.5 18t-46 0L370 1788q-13 -3 -26 -9t-25 -15H1512v132ZM1742 0H274Q213 0 169.5 43.5T126 148V1490q0 61 43.5 104.5T274 1638H1742q61 0 104.5 -43.5T1890 1490V148q0 -61 -43.5 -104.5T1742 0ZM1489 1377q-24 20 -53 13L801 1259q-22 -5 -36 -22.5T751 1197V560q-15 1 -29.5 0T693 556Q613 539 558.5 489T504 378q0 -63 56 -100T693 257q51 11 94.5 40t69 68.5T882 446q0 3 0.5 17t0.5 25t-1 16l-5 434l509 114V665q-33 2 -63 -4q-51 -10 -94.5 -37t-69 -64T1134 485q0 -57 55.5 -87T1323 383t133.5 66.5T1512 559q0 1 0 2l-1 3q0 0 0.5 1t0.5 2v761q0 10 -2.5 19t-8 16.5T1489 1377Z"
221></glyph
222><glyph unicode="&#xf137;" d="M1512 1896q0 49 -34.5 77.5T1394 1992L370 1788q-14 -3 -27 -9t-25 -15H1512v132ZM1742 0H274Q213 0 169.5 43.5T126 148V1490q0 61 43.5 104.5T274 1638H1742q61 0 104.5 -43.5T1890 1490V148q0 -61 -43.5 -104.5T1742 0ZM1426 1377q-11 9 -25 12.5t-28 0.5L741 1259q-22 -5 -35 -22t-13 -40V560q0 0 -4.5 0t-11 0T663 559.5T646.5 558T633 556Q554 539 498 484T442 367t55 -94T631 257q51 11 94 39t68 66.5T818 442q0 6 0.5 19t0.5 17V938l504 114V665q-33 2 -63 -4q-78 -15 -133.5 -66.5T1071 485.5T1126.5 398T1260 383t133.5 66.5T1449 559q0 1 0 2q-1 2 -1 3q0 0 0.5 1t0.5 2v761q0 30 -23 49Z"
223></glyph
224><glyph unicode="&#xf138;" d="M1134 1134v529q0 25 -14.5 48.5t-38 38T1033 1764H983q-38 0 -69.5 -31.5T882 1663V1134H353q-19 0 -37.5 -8.5T283 1103t-22.5 -32.5T252 1033V983q0 -25 14.5 -48.5t38 -38T353 882H882V353q0 -38 31.5 -69.5T983 252h50q19 0 37.5 8.5T1103 283t22.5 32.5T1134 353V882h529q38 0 69.5 31.5T1764 983v50q0 25 -14.5 48.5t-38 38T1663 1134H1134Z"
225></glyph
226><glyph unicode="&#xf139;" d="M1134 1134v529q0 25 -14.5 48.5t-38 38T1033 1764H983q-38 0 -69.5 -31.5T882 1663V1134H353q-19 0 -37.5 -8.5T283 1103t-22.5 -32.5T252 1033V983q0 -25 14.5 -48.5t38 -38T353 882H882V353q0 -38 31.5 -69.5T983 252h50q19 0 37.5 8.5T1103 283t22.5 32.5T1134 353V882h529q38 0 69.5 31.5T1764 983v50q0 25 -14.5 48.5t-38 38T1663 1134H1134Z"
227></glyph
228><glyph unicode="&#xf13a;" d="M1890 315q0 -26 -18.5 -44.5T1827 252H189q-26 0 -44.5 18.5T126 315t18.5 44.5T189 378H1827q26 0 44.5 -18.5T1890 315ZM1890 819q0 -26 -18.5 -44.5T1827 756H189q-26 0 -44.5 18.5T126 819t18.5 44.5T189 882H1827q26 0 44.5 -18.5T1890 819ZM1890 1619V1405q0 -60 -42.5 -102.5T1745 1260H271q-39 0 -72.5 19.5t-53 53T126 1405v214q0 60 42.5 102.5T271 1764H1745q60 0 102.5 -42.5T1890 1619Z"
229></glyph
230><glyph unicode="&#xf13b;" d="M1890 315q0 -26 -18.5 -44.5T1827 252H189q-26 0 -44.5 18.5T126 315t18.5 44.5T189 378H1827q26 0 44.5 -18.5T1890 315ZM1890 819q0 -26 -18.5 -44.5T1827 756H189q-26 0 -44.5 18.5T126 819t18.5 44.5T189 882H1827q26 0 44.5 -18.5T1890 819ZM1890 1619V1405q0 -60 -42.5 -102.5T1745 1260H271q-39 0 -72.5 19.5t-53 53T126 1405v214q0 60 42.5 102.5T271 1764H1745q60 0 102.5 -42.5T1890 1619Z"
231></glyph
232><glyph unicode="&#xf13c;" d="M1255 1008q0 -50 -19.5 -96T1183 833t-79 -52.5T1008 761t-96 19.5T833 833t-52.5 79T761 1008q0 29 6.5 56.5t18.5 52t29 46t38.5 38.5t46 29t52 18.5t56.5 6.5q102 0 174.5 -72.5T1255 1008ZM1424 606q-8 9 -12.5 20.5t-4 23.5t5.5 23.5t14 19.5q66 62 101 143.5t35 171.5q0 36 -6 71t-17 68t-27.5 64t-38 59t-47.5 53q-19 17 -19.5 42.5t17 44.5t43 19.5T1512 1413q56 -53 95 -117.5T1666 1158t20 -150q0 -114 -45.5 -220T1512 604q-18 -17 -43 -17q-26 0 -45 19ZM1567 307q-4 7 -7 14.5t-4 15.5t0 16t4.5 15t8.5 13.5t12 11.5q146 108 228.5 271t82.5 344t-82.5 344.5T1581 1623q-14 10 -20.5 25t-5 31.5t11.5 30t25.5 20t31.5 4.5t30 -11q112 -83 194 -196.5t125 -246T2016 1008q0 -105 -25 -207T1920 607.5t-114 -172T1654 294q-16 -12 -37 -12q-31 0 -50 25ZM504 603Q421 682 375.5 788T330 1008q0 77 20 150t59 137.5T504 1413q19 17 44.5 16.5T591 1410q18 -18 17.5 -44T589 1323Q523 1261 488 1179.5T453 1008T488 836.5T589 693q19 -17 19.5 -42.5T592 606Q573 587 547 587q-25 0 -43 16ZM362 294Q192 418 96 607.5T0 1008t96 400.5T362 1723q5 3 10.5 5.5t11.5 4t12 2t12 -0.5t11.5 -3t10.5 -5t10 -7.5t9 -9.5q15 -20 11 -45.5T435 1623Q289 1515 206.5 1352T124 1008T206.5 664T435 393q21 -15 25 -40.5T448 307q-4 -6 -10 -11t-12 -8t-13 -4.5T399 282q-7 0 -13 1t-12.5 4T362 294Z"
233></glyph
234><glyph unicode="&#xf13d;" d="M1259 1008q0 -51 -20 -97.5t-53.5 -80t-80 -53.5T1008 757q-104 0 -177.5 73.5T757 1008t73.5 177.5T1008 1259t177.5 -73.5T1259 1008ZM1442 610q-13 15 -12.5 34.5T1444 677q23 22 42.5 46t35.5 50t28 54.5t20.5 58t12.5 60t4 62.5q0 47 -9.5 92.5T1550 1188t-44.5 80t-61.5 71q-14 13 -14.5 32.5t13 34t33 15T1509 1407q41 -39 73.5 -85t54.5 -96.5T1670 1120t11 -112q0 -75 -20 -147T1602 724.5T1509 608q-14 -12 -32 -12q-21 0 -35 14ZM1589 305q-12 16 -9 35t19 31q38 28 72 60t63.5 67t55.5 73.5t46.5 79.5t36.5 84.5t27 88t16.5 91t5.5 93.5q0 124 -38.5 242.5T1772 1470t-173 175q-16 12 -19 31t8.5 34.5t31 18.5t35.5 -8q84 -62 151.5 -142.5t114 -171.5t71 -193T2016 1008q0 -210 -96 -399T1655 295q-13 -9 -28 -9q-11 0 -21 5t-17 14ZM507 609q-54 51 -93 115.5T355 861t-20 147q0 76 19.5 148T413 1291.5T507 1408q14 13 33.5 12.5T574 1406q8 -10 11 -22t-0.5 -24T572 1339Q503 1274 466 1188.5T429 1008T466 827.5T572 677q14 -13 14.5 -32.5T574 610q-5 -4 -10.5 -7.5t-11.5 -5T539 596q-9 0 -17 3t-15 10ZM361 295Q192 420 96 609T0 1008q0 139 43 271.5T167.5 1525T361 1721q11 8 23.5 9t24 -4T427 1711q12 -16 9 -35t-19 -31Q317 1571 244 1470T132.5 1250.5T94 1008Q94 820 179.5 651T417 371q16 -12 19 -31t-9 -35q-4 -6 -10.5 -10.5T403 288t-14 -2q-15 0 -28 9Z"
235></glyph
236><glyph unicode="&#xf13e;" d="M1638 1008V911q0 -76 -41 -141T1485.5 667.5T1332 630H630V806q0 13 -2.5 21.5t-7.5 13t-11.5 5t-15 -4T577 829L305 557Q291 543 286 523.5t0 -39T305 451L577 179q22 -22 37.5 -15.5T630 202V378h702q114 0 217 42.5t178 114t119 170T1890 911v97q0 52 -37 89t-89 37t-89 -37t-37 -89ZM378 1105q0 116 89.5 198.5T684 1386h702V1210q0 -32 15.5 -38.5T1439 1187l272 272q22 22 22 53t-22 53l-272 272q-22 22 -37.5 15.5T1386 1814V1638H684q-91 0 -176 -27T354.5 1534.5T234 1419.5T154 1273T126 1105v-97q0 -52 37 -89t89 -37t89 37t37 89v97Z"
237></glyph
238><glyph unicode="&#xf13f;" d="M1638 976V880q0 -87 -37 -157.5t-107.5 -113T1332 567H630V775q0 20 -7 30.5T603.5 814T577 797L305 526Q291 512 286 492.5t0 -39T305 419L577 148q22 -22 37.5 -15.5T630 170V378h702q107 0 199.5 39.5t157 107.5T1790 685t37 195v96q0 40 -27.5 67.5t-67 27.5t-67 -27.5T1638 976ZM378 1137q0 63 26.5 121t72 99.5t108 66.5T715 1449h671V1241q0 -31 15.5 -37.5T1439 1219l272 271q22 22 22 53.5t-22 53.5l-272 271q-22 22 -37.5 15.5T1386 1846V1638H715q-107 0 -204.5 -40t-168 -107t-112 -159.5T189 1137v-97q0 -40 27.5 -67.5t67 -27.5t67 27.5T378 1040v97Z"
239></glyph
240><glyph unicode="&#xf140;" d="M1512 1134q0 -171 -84.5 -316T1198 588.5T882 504T566 588.5T336.5 818T252 1134t84.5 316T566 1679.5T882 1764t316 -84.5T1427.5 1450T1512 1134ZM126 1134q0 -154 60 -294T347 599T588 438T882 378t294 60t241 161t161 241t60 294t-60 294t-161 241t-241 161t-294 60T588 1830T347 1669T186 1428T126 1134ZM1632 562q-25 -34 -53.5 -65T1519 437.5T1454 384L1675 163q37 -37 89 -37q25 0 48 9.5t41 27.5q24 24 32.5 56.5t0 65T1853 341L1632 562Z"
241></glyph
242><glyph unicode="&#xf141;" d="M1587 607Q1512 504 1409 429L1675 163q36 -37 89 -37t89 37q37 37 37 89t-37 89L1587 607ZM1544 1134q0 -134 -52.5 -256.5t-141 -211T1139 525.5T882 473T625.5 525.5t-211 141t-141 211T221 1134t52.5 257t141 211.5t211 141T882 1796t257 -52.5t211.5 -141t141 -211.5T1544 1134ZM126 1134Q126 929 227.5 755T503 479.5T882 378q154 0 294 60t241 161t161 241t60 294t-60 294t-161 241t-241 161t-294 60T588 1830T347 1669T186 1428T126 1134Z"
243></glyph
244><glyph unicode="&#xf142;" d="M1283 1726q-61 53 -104.5 33T1135 1658v-98V1364q0 0 -93 -14Q731 1289 506 1129Q128 857 127 378q3 7 9 18.5t28.5 47t49.5 70t75 81t102.5 87T525 763t166.5 69.5t202.5 47T1135 898V678V579q0 -80 43.5 -100T1282 513l549 481q60 53 60 129t-61 129l-547 474Z"
245></glyph
246><glyph unicode="&#xf143;" d="M1283 1726q-61 53 -104.5 33T1135 1658v-98V1364q0 0 -93 -14Q731 1289 506 1129Q128 857 127 378q3 7 9 18.5t28.5 47t49.5 70t75 81t102.5 87T525 763t166.5 69.5t202.5 47T1135 898V678V579q0 -80 43.5 -100T1282 513l549 481q60 53 60 129t-61 129l-547 474Z"
247></glyph
248><glyph unicode="&#xf144;" d="M601 1215q10 18 20.5 35t24.5 39.5t28.5 43.5t33 46t37.5 49q-99 99 -219.5 154.5T252 1638q-52 0 -89 -37t-37 -89t37 -89t89 -37q43 0 82.5 -7.5t75 -21T478 1323t63 -48t60 -60ZM1512 1210q0 -32 15.5 -38.5T1565 1187l272 272q22 22 22 53t-22 53l-272 272q-22 22 -37.5 15.5T1512 1814V1630q-66 -8 -127.5 -25T1271 1565.5T1169.5 1513T1080 1451.5t-78.5 -70t-69 -74.5t-60 -77.5T821 1153t-44 -75Q724 985 680.5 919T587 795.5t-99.5 -92T379 649.5T252 630q-52 0 -89 -37T126 504t37 -89t89 -37q111 0 211 35t172 86T778 632.5T894.5 785T996 954q74 130 152 217t167.5 137t196.5 67V1210ZM1512 806V636q-52 6 -96.5 16t-80 24T1269 709.5T1213 752t-49 51q-15 -27 -29.5 -50.5T1102 700t-38 -58.5T1023 584q85 -84 202.5 -135T1512 383V202q0 -32 15.5 -38.5T1565 179l272 272q22 22 22 53t-22 53L1565 829q-22 22 -37.5 15.5T1512 806Z"
249></glyph
250><glyph unicode="&#xf145;" d="M618 1243q51 87 108 161Q524 1606 252 1606q-39 0 -66.5 -27.5T158 1512t27.5 -66.5T252 1418q111 0 199.5 -43.5T618 1243ZM1512 1210q0 -32 15.5 -38.5T1565 1187l272 272q22 22 22 53t-22 53l-272 272q-22 22 -37.5 15.5T1512 1814V1598q-80 -10 -153 -33t-131.5 -53.5T1114 1439t-97 -84t-82.5 -94.5t-70 -98.5T804 1062Q751 968 706 900.5T608.5 773T503 676.5T387 619T252 598q-39 0 -66.5 -27.5T158 504t27.5 -66.5T252 410q77 0 148 17t128.5 45T641 545t97 89.5t86.5 106t75.5 112T969 969q113 201 243.5 306.5T1512 1408V1210ZM1512 806V605q-34 3 -65 8.5T1389 626t-51.5 16T1291 661.5t-41.5 23t-37.5 27t-34 30T1147 774q-24 -42 -50.5 -83T1041 610q40 -40 85 -71.5t102 -57T1356.5 439T1512 415V202q0 -32 15.5 -38.5T1565 179l272 272q10 10 16 24.5t6 28.5t-6 28.5T1837 557L1565 829q-22 22 -37.5 15.5T1512 806Z"
251></glyph
252><glyph unicode="&#xf146;" d="M630 1119v517q0 48 -34 82.5T514 1753H494q-31 0 -58 -15.5T393.5 1695T378 1636V368q0 -48 34 -82t82 -34h20q48 0 82 34t34 82V896L1516 290q17 -12 32.5 -17t29 -5t25 6t19 17t12 27t4.5 36V1661q0 61 -35.5 79.5T1516 1725L630 1119Z"
253></glyph
254><glyph unicode="&#xf147;" d="M630 1119v517q0 48 -34 82.5T514 1753H494q-31 0 -58 -15.5T393.5 1695T378 1636V368q0 -48 34 -82t82 -34h20q48 0 82 34t34 82V896L1516 290q17 -12 32.5 -17t29 -5t25 6t19 17t12 27t4.5 36V1661q0 61 -35.5 79.5T1516 1725L630 1119Z"
255></glyph
256><glyph unicode="&#xf148;" d="M1502 1753q-19 0 -36.5 -6t-32 -17t-25 -25T1392 1673t-6 -37V1119L500 1725q-51 34 -86.5 15.5T378 1661V354q0 -61 35.5 -80T500 290l886 606V368q0 -48 34 -82t82 -34h20q48 0 82 34t34 82V1636q0 32 -15.5 59t-42.5 42.5t-58 15.5h-20Z"
257></glyph
258><glyph unicode="&#xf149;" d="M1502 1753q-19 0 -36.5 -6t-32 -17t-25 -25T1392 1673t-6 -37V1119L500 1725q-51 34 -86.5 15.5T378 1661V354q0 -61 35.5 -80T500 290l886 606V368q0 -48 34 -82t82 -34h20q48 0 82 34t34 82V1636q0 32 -15.5 59t-42.5 42.5t-58 15.5h-20Z"
259></glyph
260><glyph unicode="&#xf14a;" d="M103 1177L621 800L582 680L421 186q-8 -25 -7 -40.5t9.5 -22t24 -2T484 141l15 11l506 367L1526 141q42 -31 60.5 -17.5T1588 186L1389 800l519 377q42 30 34.5 52t-58.5 22H1243l-39 119l-160 490q-10 32 -24.5 43.5t-28.5 0T966 1860L767 1251H127q-52 0 -59 -22t35 -52Z"
261></glyph
262><glyph unicode="&#xf14b;" d="M103 1177L621 800L582 680L421 186q-8 -25 -7 -40.5t9.5 -22t24 -2T484 141l15 11l506 367L1526 141q42 -31 60.5 -17.5T1588 186L1389 800l519 377q42 30 34.5 52t-58.5 22H1243l-39 119l-160 490q-10 32 -24.5 43.5t-28.5 0T966 1860L767 1251H127q-52 0 -59 -22t35 -52Z"
263></glyph
264><glyph unicode="&#xf14c;" d="M1989 888q27 -27 27 -69q0 -43 -27 -70Q1443 203 1269 30Q1239 0 1197 -0.5T1124 29L36 1117Q3 1150 1 1187q-1 8 -1 35v668q0 30 49 78t77 48H458q212 -1 334 -1q70 0 107 -37L1989 888ZM311 1572q48 0 89.5 41.5T442 1703t-41.5 89T311 1833t-89.5 -41T180 1703q0 -49 42 -89q40 -42 89 -42Z"
265></glyph
266><glyph unicode="&#xf14d;" d="M2016 819q0 -43 -27 -70Q1964 724 1268 30Q1238 0 1196.5 -0.5T1124 29L36 1117Q3 1150 1 1187q-1 8 -1 35q0 132 1 361v361q0 30 20.5 51T70 2016H430q231 -1 362 -1q71 0 107 -36l546 -546q352 -353 544 -545q27 -27 27 -69ZM313 1578q48 0 86.5 39t38.5 86q0 48 -38.5 86T313 1827t-86.5 -38T188 1703q0 -47 39 -86q37 -39 86 -39Z"
267></glyph
268><glyph unicode="&#xf14e;" d="M189 1512H315q26 0 44.5 -18.5T378 1449V693q0 -26 -18.5 -44.5T315 630H189q-26 0 -44.5 18.5T126 693v756q0 26 18.5 44.5T189 1512ZM1764 883h-26q32 -3 58 -18.5t41.5 -42T1853 764q0 -52 -51 -82.5T1645 638q-44 -5 -130 -7t-169 -2q-13 -9 -16 -23.5t5 -32.5q11 -8 28.5 -26t46 -96.5T1438 267q0 -146 -24.5 -206.5T1338 0q-31 0 -55 18t-28 44q-15 88 -49 165t-75.5 131t-94 100T937 532.5t-97.5 50T756 614t-62 16h-1q-26 0 -44.5 18.5T630 693v756q0 36 51 72.5t122 61t143.5 40T1065 1638h230q82 0 151 -12t113.5 -30t75.5 -41t44.5 -44.5T1693 1471q0 -18 -5 -33t-12 -24t-14 -15t-12 -9t-4 -4h57q52 0 89 -37t37 -89q0 -50 -35 -86t-85 -39h55q52 0 89 -37t37 -89t-37 -89t-89 -37Z"
269></glyph
270><glyph unicode="&#xf14f;" d="M189 1512H315q26 0 44.5 -18.5T378 1449V693q0 -26 -18.5 -44.5T315 630H189q-26 0 -44.5 18.5T126 693v756q0 26 18.5 44.5T189 1512ZM1764 883h-26q32 -3 58 -18.5t41.5 -42T1853 764q0 -52 -51 -82.5T1645 638q-44 -5 -130 -7t-169 -2q-13 -9 -16 -23.5t5 -32.5q11 -8 28.5 -26t46 -96.5T1438 267q0 -146 -24.5 -206.5T1338 0q-31 0 -55 18t-28 44q-15 88 -49 165t-75.5 131t-94 100T937 532.5t-97.5 50T756 614t-62 16h-1q-26 0 -44.5 18.5T630 693v756q0 36 51 72.5t122 61t143.5 40T1065 1638h230q82 0 151 -12t113.5 -30t75.5 -41t44.5 -44.5T1693 1471q0 -18 -5 -33t-12 -24t-14 -15t-12 -9t-4 -4h57q52 0 89 -37t37 -89q0 -50 -35 -86t-85 -39h55q52 0 89 -37t37 -89t-37 -89t-89 -37Z"
271></glyph
272><glyph unicode="&#xf150;" d="M189 504H315q26 0 44.5 18.5T378 567v756q0 26 -18.5 44.5T315 1386H189q-26 0 -44.5 -18.5T126 1323V567q0 -26 18.5 -44.5T189 504ZM1764 1133h-26q49 4 82 37.5t33 81.5q0 21 -8 38.5t-24.5 31T1779 1346t-58 19t-76 13q-44 5 -130 7t-169 2q-6 4 -10.5 10t-6 13.5t0 15.5t5.5 17q2 1 5.5 4t14.5 15t20.5 27t21.5 40.5t20.5 55.5t14.5 73t6 91q0 99 -12 159t-33 84t-55 24q-31 0 -55 -18t-28 -44q-15 -88 -49 -165t-75.5 -131t-94 -100T937 1483.5t-97.5 -50T756 1402t-62 -16h-1q-26 0 -44.5 -18.5T630 1323V567q0 -36 51 -72.5t122 -61t143.5 -40T1065 378h230q69 0 128.5 8t102 22t75.5 31.5t52.5 36.5t29.5 36.5t10 32.5q0 18 -5 33t-12 24t-14 15t-12 9t-4 4h57q52 0 89 37t37 89q0 25 -9.5 47.5t-25.5 39t-38 27T1709 881h55q34 0 63 17t46 46t17 63q0 52 -37 89t-89 37Z"
273></glyph
274><glyph unicode="&#xf151;" d="M189 504H315q26 0 44.5 18.5T378 567v756q0 26 -18.5 44.5T315 1386H189q-26 0 -44.5 -18.5T126 1323V567q0 -26 18.5 -44.5T189 504ZM1764 1133h-26q49 4 82 37.5t33 81.5q0 21 -8 38.5t-24.5 31T1779 1346t-58 19t-76 13q-44 5 -130 7t-169 2q-6 4 -10.5 10t-6 13.5t0 15.5t5.5 17q2 1 5.5 4t14.5 15t20.5 27t21.5 40.5t20.5 55.5t14.5 73t6 91q0 99 -12 159t-33 84t-55 24q-31 0 -55 -18t-28 -44q-15 -88 -49 -165t-75.5 -131t-94 -100T937 1483.5t-97.5 -50T756 1402t-62 -16h-1q-26 0 -44.5 -18.5T630 1323V567q0 -36 51 -72.5t122 -61t143.5 -40T1065 378h230q69 0 128.5 8t102 22t75.5 31.5t52.5 36.5t29.5 36.5t10 32.5q0 18 -5 33t-12 24t-14 15t-12 9t-4 4h57q52 0 89 37t37 89q0 25 -9.5 47.5t-25.5 39t-38 27T1709 881h55q34 0 63 17t46 46t17 63q0 52 -37 89t-89 37Z"
275></glyph
276><glyph unicode="&#xf152;" d="M1134 1764h63q26 0 44.5 18.5T1260 1827t-18.5 44.5T1197 1890H819q-26 0 -44.5 -18.5T756 1827t18.5 -44.5T819 1764h63V1627Q711 1598 570 1498l-56 56q-27 28 -66.5 28T381 1554l-45 -45q-28 -27 -28 -66.5T336 1376l56 -57Q252 1123 252 882q0 -154 60 -294T473 347T714 186t294 -60t294 60t241 161t161 241t60 294q0 138 -48.5 265.5t-132.5 225T1383 1537t-249 90v137ZM378 882q0 171 84.5 316T692 1427.5t316 84.5t316 -84.5T1553.5 1198T1638 882T1553.5 566T1324 336.5T1008 252T692 336.5T462.5 566T378 882ZM1301 712L1129 858q1 2 2 7t2 9t1 8q0 52 -37 89t-89 37T919 971T882 882t37 -89t89 -37q6 0 13.5 1t12.5 2.5t12 4.5L1220 616q14 -11 35 -24t37 -20l118 -51q17 -7 21.5 -1.5T1427 540l-70 108q-23 36 -56 64Z"
277></glyph
278><glyph unicode="&#xf153;" d="M1134 1764h63q26 0 44.5 18.5T1260 1827t-18.5 44.5T1197 1890H819q-26 0 -44.5 -18.5T756 1827t18.5 -44.5T819 1764h63V1627Q711 1598 570 1498l-56 56q-27 28 -66.5 28T381 1554l-45 -45q-28 -27 -28 -66.5T336 1376l56 -56Q252 1122 252 882q0 -154 60 -294T473 347T714 186t294 -60t294 60t241 161t161 241t60 294q0 138 -48.5 265.5t-132.5 225T1383 1537t-249 90v137ZM346 882q0 134 52.5 256.5T540 1350t211.5 141.5T1008 1544t256.5 -52.5T1476 1350t141.5 -211.5T1670 882T1617.5 625.5T1476 414T1264.5 272.5T1008 220T751.5 272.5T540 414T398.5 625.5T346 882ZM1301 712L1131 856q1 2 1 4t0.5 4.5t1 4.5t0.5 4t0 4.5t0 4.5q0 52 -37 89t-89 37T919 971T882 882t37 -89t89 -37q18 0 39 7L1220 616q9 -7 22 -15.5T1268.5 584T1292 572l118 -51q17 -7 21.5 -1.5T1427 540l-70 108q-10 15 -26 33.5T1301 712Z"
279></glyph
280><glyph unicode="&#xf154;" d="M253 1851L91 1679l-76 77l253 260H378V1008H253v843ZM515 613q88 69 146 115.5T784 830t105 94t79.5 83.5t60.5 81t34 74.5t13 75q0 47 -18 83.5t-49 58T941.5 1412T864 1423q-59 0 -111 -16.5T661 1362t-70 -66l-77 80q19 25 42.5 47t50.5 39.5t57.5 31t63 22.5t67 13.5T864 1534q65 0 124.5 -18.5t108 -53.5t77.5 -93t29 -131q0 -50 -16 -100.5T1137.5 1036T1064 937.5T964 835T848 732.5T713 623h494V511H515V613ZM1374 245q22 -30 52 -54t65.5 -42T1569 121.5t86 -9.5q109 0 172.5 51T1891 301q0 61 -32.5 101.5T1771 461t-131 18q-89 0 -104 -1V592q5 0 16 -0.5t27.5 -0.5t28 0t32.5 0q66 0 117.5 16.5t84 55T1874 757q0 81 -64.5 126.5T1649 929q-81 0 -145 -30T1383 807l-70 79q58 71 146 113t200 42q73 0 135 -18t108 -51.5T1973.5 887T1999 774q0 -42 -13.5 -79t-35 -63T1900 586.5t-58 -31T1783 540q37 -4 75.5 -21t75 -46T1993 396t23 -106q0 -84 -42.5 -149.5T1849 37.5T1658 0Q1536 0 1442.5 46.5T1300 166l74 79Z"
281></glyph
282><glyph unicode="&#xf155;" d="M253 1851L91 1679l-76 77l253 260H378V1008H253v843ZM515 613q88 69 146 115.5T784 830t105 94t79.5 83.5t60.5 81t34 74.5t13 75q0 47 -18 83.5t-49 58T941.5 1412T864 1423q-59 0 -111 -16.5T661 1362t-70 -66l-77 80q19 25 42.5 47t50.5 39.5t57.5 31t63 22.5t67 13.5T864 1534q65 0 124.5 -18.5t108 -53.5t77.5 -93t29 -131q0 -50 -16 -100.5T1137.5 1036T1064 937.5T964 835T848 732.5T713 623h494V511H515V613ZM1374 245q22 -30 52 -54t65.5 -42T1569 121.5t86 -9.5q109 0 172.5 51T1891 301q0 61 -32.5 101.5T1771 461t-131 18q-89 0 -104 -1V592q5 0 16 -0.5t27.5 -0.5t28 0t32.5 0q66 0 117.5 16.5t84 55T1874 757q0 81 -64.5 126.5T1649 929q-81 0 -145 -30T1383 807l-70 79q58 71 146 113t200 42q73 0 135 -18t108 -51.5T1973.5 887T1999 774q0 -42 -13.5 -79t-35 -63T1900 586.5t-58 -31T1783 540q37 -4 75.5 -21t75 -46T1993 396t23 -106q0 -84 -42.5 -149.5T1849 37.5T1658 0Q1536 0 1442.5 46.5T1300 166l74 79Z"
283></glyph
284><glyph unicode="&#xf156;" d="M1008 126q-179 0 -342.5 70T384 384T196 665.5T126 1008t70 342.5T384 1632t281.5 188t342.5 70t342.5 -70T1632 1632t188 -281.5T1890 1008T1820 665.5T1632 384T1350.5 196T1008 126ZM1260 1573q0 26 -18.5 44.5T1197 1636t-44.5 -18.5T1134 1573V794q-37 23 -90 26.5t-107.5 -12T832 765.5T746.5 697T701 611q-6 -26 -4.5 -51.5t8 -46.5T722 479q34 -41 84.5 -61t106 -17t111 21.5T1129 476t86 80q30 38 37.5 79t7.5 121v817Z"
285></glyph
286><glyph unicode="&#xf157;" d="M1008 126q-179 0 -342.5 70T384 384T196 665.5T126 1008t70 342.5T384 1632t281.5 188t342.5 70t342.5 -70T1632 1632t188 -281.5T1890 1008T1820 665.5T1632 384T1350.5 196T1008 126ZM1260 1573q0 26 -18.5 44.5T1197 1636t-44.5 -18.5T1134 1573V794q-37 23 -90 26.5t-107.5 -12T832 765.5T746.5 697T701 611q-6 -26 -4.5 -51.5t8 -46.5T722 479q34 -41 85 -61T913 401t110.5 21.5T1129 476t86 80q30 38 37.5 79t7.5 121v817Z"
287></glyph
288><glyph unicode="&#xf158;" d="M1457 1638q-20 0 -29.5 -6.5t-7.5 -18t16 -25.5l130 -130L1111 1042L782 1152q-26 9 -52 2.5T685 1129L252 691V1764q0 28 -18 47t-45 19t-45 -19t-18 -47V314q0 -81 57.5 -134.5T324 126H1774q10 0 20 3t18.5 8.5T1827 151t9 17.5t3 20.5q0 13 -5 25t-14 20t-21 13t-25 5H324q-29 0 -50.5 18T252 314V422L778 954L1104 845q12 -4 25 -5t25 1.5t23 8.5t21 15l501 459l141 -140q21 -21 35.5 -15t14.5 36v362q0 20 -9.5 36t-25.5 25.5t-36 9.5H1457Z"
289></glyph
290><glyph unicode="&#xf159;" d="M1457 1638q-20 0 -29.5 -6.5t-7.5 -18t16 -25.5l152 -152L1119 1006L772 1122q-12 4 -23.5 3.5T726 1120t-19 -13L252 646V1764q0 26 -18.5 44.5T189 1827t-44.5 -18.5T126 1764V314q0 -80 56.5 -134T320 126H1764q26 0 44.5 18.5T1827 189t-18.5 44.5T1764 252H320q-19 0 -34.5 7.5t-24.5 22T252 314V466L769 990L1114 875q8 -3 16.5 -3.5t16.5 1t15.5 5.5t14.5 10l500 459l163 -163q21 -21 35.5 -15t14.5 35v364q0 29 -20.5 49.5T1820 1638H1457Z"
291></glyph
292><glyph unicode="&#xf15c;" d="M1448 681Q1358 575 1246 515.5T1008 456q-127 0 -239.5 60.5T565 684Q485 658 411 625T304 572L270 552Q211 514 168.5 437.5T126 292.5T176.5 175T297 126H1719q70 0 120.5 49T1890 292.5t-42.5 144T1745 550q-13 8 -37.5 21.5t-102 48.5T1448 681ZM1008 630q-68 0 -134 29.5t-120.5 80T652 859.5t-79.5 149T522 1176t-18 174q0 127 39.5 230.5t108 170.5t160 103t196.5 36t196.5 -36t160 -103t108 -170.5T1512 1350q0 -129 -40 -259T1365 859.5T1203.5 694T1008 630Z"
293></glyph
294><glyph unicode="&#xf15d;" d="M1448 681Q1358 575 1246 515.5T1008 456q-127 0 -239.5 60.5T565 684Q485 658 411 625T304 572L270 552Q211 514 168.5 437.5T126 292.5T176.5 175T297 126H1719q70 0 120.5 49T1890 292.5t-42.5 144T1745 550q-13 8 -37.5 21.5t-102 48.5T1448 681ZM1008 630q-68 0 -134 29.5t-120.5 80T652 859.5t-79.5 149T522 1176t-18 174q0 127 39.5 230.5t108 170.5t160 103t196.5 36t196.5 -36t160 -103t108 -170.5T1512 1350q0 -129 -40 -259T1365 859.5T1203.5 694T1008 630Z"
295></glyph
296><glyph unicode="&#xf15e;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4ZM1532 590q-26 16 -32.5 45.5T1509 690q92 145 92 318q0 175 -94 321q-6 10 -9 21.5t-2.5 22.5t4.5 21.5t11.5 20T1529 1430q12 8 26.5 10.5t28 -0.5t25.5 -11t20 -21q29 -44 51 -92.5t37 -98.5t22.5 -103t7.5 -106q0 -215 -115 -396q-10 -16 -26.5 -25T1571 578q-22 0 -39 12ZM1747 430q-25 17 -31 46.5t11 54.5q143 216 143 477q0 264 -147 482q-17 25 -11 54.5t31 46.5t54.5 11.5T1844 1572q172 -255 172 -564q0 -305 -168 -557q-22 -33 -61 -33q-22 0 -40 12Z"
297></glyph
298><glyph unicode="&#xf15f;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4ZM1532 590q-26 16 -32.5 45.5T1509 690q92 145 92 318q0 175 -94 321q-6 10 -9 21.5t-2.5 22.5t4.5 21.5t11.5 20T1529 1430q12 8 26.5 10.5t28 -0.5t25.5 -11t20 -21q29 -44 51 -92.5t37 -98.5t22.5 -103t7.5 -106q0 -215 -115 -396q-10 -16 -26.5 -25T1571 578q-22 0 -39 12ZM1747 430q-25 17 -31 46.5t11 54.5q143 216 143 477q0 264 -147 482q-17 25 -11 54.5t31 46.5t54.5 11.5T1844 1572q172 -255 172 -564q0 -305 -168 -557q-22 -33 -61 -33q-22 0 -40 12Z"
299></glyph
300><glyph unicode="&#xf160;" d="M1681 1512q14 14 22.5 31t11 35.5t0 36.5t-11 35t-22.5 31q-17 17 -39.5 26t-45 9t-45 -9T1512 1681L1008 1177L504 1681q-17 17 -39.5 26t-45 9t-45 -9T335 1681q-35 -35 -35 -84.5T335 1512L839 1008L335 504Q312 481 303.5 450t0 -61.5T335 335q17 -17 39 -26t45 -9q50 0 85 35l504 504L1512 335q35 -35 85 -35q49 1 84 35q17 17 26 39.5t9 45t-9 45T1681 504l-504 504l504 504Z"
301></glyph
302><glyph unicode="&#xf161;" d="M1681 1512q14 14 22.5 31t11 35.5t0 36.5t-11 35t-22.5 31q-17 17 -39.5 26t-45 9t-45 -9T1512 1681L1008 1177L504 1681q-17 17 -39.5 26t-45 9t-45 -9T335 1681q-35 -35 -35 -84.5T335 1512L839 1008L335 504Q312 481 303.5 450t0 -61.5T335 335q17 -17 39 -26t45 -9q50 0 85 35l504 504L1512 335q35 -35 85 -35q49 1 84 35q17 17 26 39.5t9 45t-9 45T1681 504l-504 504l504 504Z"
303></glyph
304><glyph unicode="&#xf164;" d="M1865 1877q-22 18 -54 13L806 1638q-20 -6 -35 -23.5T756 1575V589q-79 27 -157 9Q481 575 398 487.5T315 299q0 -100 83 -155T599 113q115 23 198 108t85 182v888l882 214l3 -699q-74 27 -157 9Q1491 792 1408.5 705T1326 516q0 -99 83 -154t201 -32q116 24 198 110.5T1890 626V1827q0 30 -25 50ZM378 1764v189q0 28 -17.5 45.5T315 2016t-45.5 -17.5T252 1953V1764H63q-28 0 -45.5 -17.5T0 1701t17.5 -45.5T63 1638H252V1449q0 -28 17.5 -45.5T315 1386t45.5 17.5T378 1449v189H567q28 0 45.5 17.5T630 1701t-17.5 45.5T567 1764H378Z"
305></glyph
306><glyph unicode="&#xf165;" d="M1865 1877q-22 18 -54 13L806 1638q-20 -6 -35 -23.5T756 1575V589q-79 27 -157 9Q481 575 398 487.5T315 299q0 -100 83 -155T599 113q115 23 198 108t85 182v888l882 214l3 -699q-74 27 -157 9Q1491 792 1408.5 705T1326 516q0 -99 83 -154t201 -32q116 24 198 110.5T1890 626V1827q0 30 -25 50ZM378 1764v189q0 28 -17.5 45.5T315 2016t-45.5 -17.5T252 1953V1764H63q-28 0 -45.5 -17.5T0 1701t17.5 -45.5T63 1638H252V1449q0 -28 17.5 -45.5T315 1386t45.5 17.5T378 1449v189H567q28 0 45.5 17.5T630 1701t-17.5 45.5T567 1764H378Z"
307></glyph
308><glyph unicode="&#xf166;" d="M378 1764v189q0 26 -18.5 44.5T315 2016t-44.5 -18.5T252 1953V1764H63q-26 0 -44.5 -18.5T0 1701t18.5 -44.5T63 1638H252V1449q0 -26 18.5 -44.5T315 1386t44.5 18.5T378 1449v189H567q26 0 44.5 18.5T630 1701t-18.5 44.5T567 1764H378ZM1872 1865q-18 15 -41 9L823 1622q-6 -2 -11.5 -5t-10 -7.5T794 1600t-4.5 -11T788 1576V599q-81 46 -190 24Q521 608 456 562.5T353 454T315 325q0 -100 83 -154T598.5 140.5T799 251.5T882 439v1q0 6 0 850l914 222V779q-81 45 -190 24q-77 -16 -142 -61.5T1361 633T1323 504q0 -100 83 -154t200 -30q77 15 142.5 60.5T1852 489t38 129q0 2 0 1210q0 23 -18 37Z"
309></glyph
310><glyph unicode="&#xf167;" d="M126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM732 1008q0 114 81 195t195 81t195 -81t81 -195T1203 813T1008 732T813 813t-81 195Z"
311></glyph
312><glyph unicode="&#xf168;" d="M1146 1607l251 -455q57 -18 115 -18q157 0 267.5 110.5T1890 1512t-110.5 267.5T1512 1890q-86 0 -162.5 -37T1220 1752t-74 -145ZM399 681l816 411l-208 377L228 987Q175 954 155 893.5T157 776Q70 674 45 573Q9 430 100 300q14 -21 33 -35t36.5 -22.5T214 230t46 -4.5t52.5 2.5t52 5.5T420 242q48 7 73 10.5t67.5 6t71 -0.5T694 245.5T756 219V0h252V831L756 704V290q-32 14 -69.5 22t-68 10T545 320.5T478 314T411 304q-46 -7 -68.5 -10T284 289t-56 2t-41.5 15T152 336Q77 442 106 558q19 79 86 161q19 -20 44 -34t52.5 -19T345 664.5T399 681Z"
313></glyph
314><glyph unicode="&#xf169;" d="M1670 1008q0 -134 -52.5 -256.5T1476 540T1264.5 398.5T1008 346T751.5 398.5T540 540T398.5 751.5T346 1008t52.5 256.5T540 1476t211.5 141.5T1008 1670q108 0 208.5 -33.5t182 -95t143 -143t95 -182T1670 1008ZM252 1008q0 -154 60 -294T473 473T714 312t294 -60t294 60t241 161t161 241t60 294t-60 294t-161 241t-241 161t-294 60T714 1704T473 1543T312 1302T252 1008ZM1386 1134H630q-52 0 -89 -37t-37 -89t37 -89t89 -37h756q52 0 89 37t37 89t-37 89t-89 37Z"
315></glyph
316><glyph unicode="&#xf16a;" d="M1847 1932q0 34 -24.5 59t-59.5 25H254q-34 0 -59 -25t-25 -59V1764H1847v168ZM96 1134q-40 0 -60.5 -27.5T26 1040L307 93Q318 55 355 27.5T432 0H1581q40 0 77 27.5T1706 93l281 947q11 39 -9.5 66.5T1917 1134H96ZM1008 128q-135 0 -254.5 49.5T554.5 316T458 515q-19 126 47 239T705.5 936.5T1008 1006t302.5 -69.5T1511.5 754T1559 515Q1542 405 1462.5 316T1263 177.5T1008 128ZM1008 410q-56 0 -96 30.5T871 515q-2 45 38.5 78t98.5 33q59 0 99.5 -33T1146 515q-1 -44 -41.5 -74.5T1008 410ZM511 1260q67 112 199 180t298 68q167 0 298.5 -68T1506 1260h412l83 293q10 35 -8.5 60t-54.5 25H86q-36 0 -55 -25T21 1553L99 1260H511Z"
317></glyph
318><glyph unicode="&#xf16b;" d="M801 331L297 794q-37 33 -39 82.5t31.5 86t83 39T459 970L848 614l558 1079q23 44 70 59t91 -7.5t59 -70t-8 -91.5L988 364Q961 312 903 302q-11 -2 -21 -2q-22 0 -43 8t-38 23Z"
319></glyph
320><glyph unicode="&#xf16c;" d="M942 437L186 1193q-28 29 -28 68t28 65q29 28 67.5 28T318 1326L1008 636l690 690q28 28 67 28t65 -28q28 -28 28 -67.5T1830 1193L1074 437q-28 -28 -66 -28t-66 28Z"
321></glyph
322><glyph unicode="&#xf16d;" d="M1194 186L438 942q-28 28 -28 67t28 65l756 756q14 14 31.5 21.5t35.5 7.5t35 -7.5t30 -21.5q28 -28 28 -67t-28 -65L636 1008L1326 318q28 -28 28 -67t-28 -65q-28 -29 -66 -28q-38 0 -66 28Z"
323></glyph
324><glyph unicode="&#xf16e;" d="M690 186q-19 18 -25.5 42.5t0 48.5T690 318l690 690L690 1698q-19 18 -25.5 42.5t0 48.5t25.5 41q14 14 31.5 21.5T757 1859t35 -7.5T822 1830l756 -756q28 -28 28 -67t-28 -65L822 186Q794 157 756 158q-38 0 -66 28Z"
325></glyph
326><glyph unicode="&#xf16f;" d="M1698 690l-690 690L318 690Q300 671 275.5 664.5t-48.5 0T186 690q-28 28 -28 67t28 65l756 756q28 28 67 28t65 -28L1830 822q28 -28 28 -67t-28 -65q-28 -29 -66 -28q-38 0 -66 28Z"
327></glyph
328><glyph unicode="&#xf170;" d="M315 2016q-130 0 -222.5 -92.5T0 1701T92.5 1478.5T315 1386t222.5 92.5T630 1701t-92.5 222.5T315 2016ZM315 1915q44 0 83.5 -17t68 -45.5t45.5 -68T529 1701t-17 -83.5t-45.5 -68t-68 -45.5T315 1487q-58 0 -107.5 28.5t-78 78T101 1701q0 44 17 83.5t45.5 68t68 45.5t83.5 17ZM1872 1865q-18 15 -41 9L823 1622q-6 -2 -11.5 -5t-10 -7.5T794 1600t-4.5 -11T788 1576V599q-81 46 -190 24Q521 608 456 562.5T353 454T315 325q0 -100 83 -154T598.5 140.5T799 251.5T882 439v1q0 6 0 850l914 222V779q-81 45 -190 24q-77 -16 -142 -61.5T1361 633T1323 504q0 -100 83 -154t200 -30q77 15 142.5 60.5T1852 489t38 129q0 2 0 1210q0 23 -18 37Z"
329></glyph
330><glyph unicode="&#xf171;" d="M391 252H365q-47 0 -80 33t-33 80V1651q0 47 33 80t80 33h13q56 0 91 -32.5T504 1651V365q0 -47 -33 -80T391 252ZM895 252H869q-47 0 -80 33t-33 80V1651q0 47 33 80t80 33h13q56 0 91 -32.5t35 -80.5V365q0 -31 -15 -57T952 267T895 252ZM1764 290l-38 -13q-40 -10 -80 10.5T1588 353L1210 1588q-6 18 -3 39t12 39.5t26 34.5t40 25l38 13q26 6 52.5 0t50 -25.5T1462 1663L1840 428q3 -12 3 -25.5t-3 -27t-9.5 -26t-16 -23.5T1792 305.5T1764 290Z"
331></glyph
332><glyph unicode="&#xf172;" d="M1008 1890q-181 0 -344.5 -69T382 1634T195 1352.5T126 1008T195 663.5T382 382T663.5 195T1008 126t344.5 69T1634 382t187 281.5t69 344.5q0 88 -25 214q-30 113 -87.5 214.5t-138.5 184t-178.5 143T1247 1857t-239 33ZM1386 1235q-64 0 -107.5 46T1235 1386t43.5 105t107.5 46q66 0 108.5 -42.5T1537 1386q0 -59 -43.5 -105T1386 1235ZM227 1008q0 158 62 302.5T456 1560t249.5 167t302.5 62q29 0 65 -4t59 -8.5t65 -12.5L1033 1134h-25q-57 0 -91.5 -34.5T882 1008t34.5 -91.5T1008 882t91.5 34.5T1134 1008v25l643 164q25 -126 25 -189Q1794 749 1635 542Q1488 349 1263 270Q1139 227 1008 227Q751 227 543 382Q353 524 273 745q-46 128 -46 263Z"
333></glyph
334><glyph unicode="&#xf173;" d="M1222 1865q-139 25 -214 25q-179 0 -342 -70T384.5 1631.5T196 1350T126 1008T196 666T384.5 384.5T666 196t342 -70t342 70t281.5 188.5T1820 666t70 342q0 76 -25 214q-57 235 -231 408t-412 235ZM1386 1235q-61 0 -106 45t-45 106t45 106t106 45t106 -45t45 -106t-45 -106t-106 -45ZM220 1008q0 160 62.5 306t168 251.5t251.5 168t306 62.5q113 0 189 -26L1040 1128q-13 6 -32 6q-52 0 -89 -37t-37 -89t37 -89t89 -37t89 37t37 89q0 5 0 7t-0.5 5.5t-1 6t-1.5 6t-3 7.5l642 157q25 -126 26 -189q0 -160 -62.5 -306t-168 -251.5T1314 282.5T1008 220T702 282.5t-251.5 168T282.5 702T220 1008Z"
335></glyph
336><glyph unicode="&#xf174;" d="M1846 1282q-3 8 -10 25q-6 18 -9 25q0 4 -3 7q-32 69 -51 101q0 1 -1.5 2.5t-1.5 3.5l-28 47q-10 16 -35 47l-3 4q-19 25 -34 40q0 2 -2 4l-2 3q-37 41 -78 79q-2 0 -4 1l-3 2q-6 6 -20 17t-21 17l-3 3q-8 7 -23.5 18t-23.5 17l-47 28q-2 0 -3.5 2t-3.5 2q-31 19 -100 50q-3 0 -3.5 0.5t-3.5 2.5q-5 2 -12 5t-13 5t-13 4.5t-12 4.5h-3q-31 10 -63.5 17.5t-66 12.5t-68.5 8t-70 3q-240 0 -443 -118T244 1451T126 1008T244 565T565 244T1008 126t443 118t321 321t118 443q0 139 -44 271v3ZM1386 1241q-61 0 -104.5 43.5t-43.5 105t43.5 104.5t104.5 43t104.5 -43T1534 1389.5t-43.5 -105T1386 1241ZM220 1008q0 160 62.5 306t168 251.5t251.5 168t306 62.5q46 0 92.5 -6t99.5 -17L1040 1131q-11 3 -32 3q-52 0 -89 -37t-37 -89t37 -89t89 -37t89 37t37 89q0 3 -0.5 7.5t-1 8t-1 8t-0.5 8.5l642 160q23 -84 23 -192q0 -160 -62.5 -306t-168 -251.5T1314 282.5T1008 220T702 282.5t-251.5 168T282.5 702T220 1008Z"
337></glyph
338><glyph unicode="&#xf175;" d="M126 1827V0H252V1827q0 28 -17.5 45.5T189 1890t-45.5 -17.5T126 1827ZM1789 756H479q-38 0 -69.5 31.5T378 857v806q0 15 5.5 30t15.5 27.5t22.5 22.5t27.5 15.5t30 5.5H1789q39 0 52 -23.5T1827 1688L1537 1336q-28 -29 -28 -76t28 -76L1827 832q27 -29 14 -52.5T1789 756Z"
339></glyph
340><glyph unicode="&#xf176;" d="M1701 882v252q0 26 -18.5 44.5T1638 1197t-44.5 -18.5T1575 1134V882H1323q-26 0 -44.5 -18.5T1260 819t18.5 -44.5T1323 756h252V504q0 -26 18.5 -44.5T1638 441t44.5 18.5T1701 504V756h252q26 0 44.5 18.5T2016 819t-18.5 44.5T1953 882H1701ZM693 648q-79 0 -153.5 50t-127 130t-84 182T297 1214q0 67 14 126t40 105.5t62 83t80 60.5t94.5 36.5T693 1638q83 0 154.5 -28.5t125.5 -81T1058 1395t31 -181q0 -102 -31.5 -204t-84 -182T846.5 698T693 648ZM1075 676Q1024 614 966 570T837.5 500.5T693 475q-111 0 -209 54T309 678Q255 659 206 636T135 600L113 587Q83 567 56.5 532.5T15 458T0 383Q0 329 39.5 290.5T135 252H1251q56 0 95.5 38.5T1386 383q0 35 -15.5 75T1329 532t-57 53q-9 5 -25 14t-67.5 33T1075 676Z"
341></glyph
342><glyph unicode="&#xf177;" d="M1664 1166q-24 103 -80 194l80 107q23 31 20.5 73t-30.5 69l-45 45q-27 28 -69 30.5T1467 1664l-107 -80q-91 56 -194 80l-19 132q-5 39 -37 66.5t-70 27.5H976q-25 0 -48.5 -12.5t-39.5 -34T869 1796L850 1664Q747 1640 656 1584l-107 80q-20 15 -46.5 19.5t-52 -3.5T407 1654l-45 -45q-28 -27 -30.5 -69T352 1467l80 -107q-56 -91 -80 -194L220 1147q-39 -5 -66.5 -37T126 1040V976q0 -38 27.5 -70T220 869L352 850q12 -52 32.5 -100.5T432 656L352 549Q329 518 331.5 476T362 407l45 -45q27 -28 69 -30.5T549 352l107 80q91 -56 194 -80L869 220q5 -39 37 -66.5T976 126h64q38 0 70 27.5t37 66.5l19 132q103 24 194 80l107 -80q20 -15 46.5 -19.5t52 3.5t43.5 26l45 45q28 27 30.5 69T1664 549l-80 107q56 91 80 194l132 19q39 5 66.5 37t27.5 70v64q0 19 -7.5 37.5t-20 33t-30 24.5t-36.5 12l-132 19ZM504 1008q0 137 67.5 253T755 1444.5t253 67.5t253 -67.5T1444.5 1261T1512 1008T1444.5 755T1261 571.5T1008 504T755 571.5T571.5 755T504 1008Z"
343></glyph
344><glyph unicode="&#xf178;" d="M781 1134H353q-47 0 -74 27t-27 74v428q0 47 27 74t74 27H794q15 0 28.5 -4.5t24.5 -13T865.5 1726t12 -28t4.5 -35V1235q0 -31 -12 -54t-35 -35t-54 -12ZM781 252H353q-47 0 -74 27t-27 74V781q0 47 27 74t74 27H794q38 0 63 -27t25 -74V353q0 -31 -12 -54T835 264T781 252ZM1663 1134H1235q-47 0 -74 27t-27 74v428q0 47 27 74t74 27h441q25 0 45 -12t31.5 -35t11.5 -54V1235q0 -47 -27 -74t-74 -27ZM1663 252H1235q-47 0 -74 27t-27 74V781q0 47 27 74t74 27h441q38 0 63 -27t25 -74V353q0 -40 -28 -70.5T1663 252Z"
345></glyph
346><glyph unicode="&#xf179;" d="M781 1134H353q-47 0 -74 27t-27 74v428q0 47 27 74t74 27H794q15 0 28.5 -4.5t24.5 -13T865.5 1726t12 -28t4.5 -35V1235q0 -31 -12 -54t-35 -35t-54 -12ZM781 252H353q-47 0 -74 27t-27 74V781q0 47 27 74t74 27H794q38 0 63 -27t25 -74V353q0 -31 -12 -54T835 264T781 252ZM1663 1134H1235q-47 0 -74 27t-27 74v428q0 47 27 74t74 27h441q25 0 45 -12t31.5 -35t11.5 -54V1235q0 -47 -27 -74t-74 -27ZM1663 252H1235q-47 0 -74 27t-27 74V781q0 47 27 74t74 27h441q38 0 63 -27t25 -74V353q0 -40 -28 -70.5T1663 252Z"
347></glyph
348><glyph unicode="&#xf17a;" d="M781 1134H353q-47 0 -74 27t-27 74v428q0 47 27 74t74 27H794q15 0 28.5 -4.5t24.5 -13T865.5 1726t12 -28t4.5 -35V1235q0 -31 -12 -54t-35 -35t-54 -12ZM781 252H353q-47 0 -74 27t-27 74V781q0 47 27 74t74 27H794q38 0 63 -27t25 -74V353q0 -31 -12 -54T835 264T781 252ZM1663 1134H1235q-47 0 -74 27t-27 74v428q0 47 27 74t74 27h441q25 0 45 -12t31.5 -35t11.5 -54V1235q0 -47 -27 -74t-74 -27ZM1663 252H1235q-47 0 -74 27t-27 74V781q0 47 27 74t74 27h441q38 0 63 -27t25 -74V353q0 -40 -28 -70.5T1663 252Z"
349></glyph
350><glyph unicode="&#xf17b;" d="M1449 1764H567q-46 0 -85.5 -28.5T422 1663Q126 838 126 825V302q0 -12 7.5 -23.5t19 -19T176 252H1840q18 0 34 15.5t16 34.5V825q0 3 -10 34t-27.5 80T1813 1051t-46.5 131.5t-49 137t-47 130.5T1631 1559.5t-27 75.5t-10 28q-14 43 -56 72t-89 29ZM567 1638h882q6 0 25 -19L1732 882H1449q-12 0 -23.5 -4.5t-20.5 -12t-16 -18T1380 825L1317 504H712L649 825q-6 16 -18 29t-27 20.5T573 882H277l265 737q0 5 10 12t15 7Z"
351></glyph
352><glyph unicode="&#xf17c;" d="M1688 1386H832q-29 0 -52.5 23.5T756 1462v100q0 29 23.5 52.5T832 1638h856q29 0 52.5 -23.5T1764 1562V1462q0 -29 -23.5 -52.5T1688 1386ZM1688 882H832q-29 0 -52.5 23.5T756 958v100q0 29 23.5 52.5T832 1134h856q29 0 52.5 -23.5T1764 1058V958q0 -29 -23.5 -52.5T1688 882ZM1688 378H832q-29 0 -52.5 23.5T756 454V554q0 29 23.5 52.5T832 630h856q29 0 52.5 -23.5T1764 554V454q0 -29 -23.5 -52.5T1688 378ZM378 1386q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89t-37 -89t-89 -37ZM378 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T467 919T378 882ZM378 378q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T467 415T378 378Z"
353></glyph
354><glyph unicode="&#xf17d;" d="M1688 1386H832q-29 0 -52.5 23.5T756 1462v100q0 29 23.5 52.5T832 1638h856q29 0 52.5 -23.5T1764 1562V1462q0 -29 -23.5 -52.5T1688 1386ZM1688 882H832q-29 0 -52.5 23.5T756 958v100q0 29 23.5 52.5T832 1134h856q29 0 52.5 -23.5T1764 1058V958q0 -29 -23.5 -52.5T1688 882ZM1688 378H832q-29 0 -52.5 23.5T756 454V554q0 29 23.5 52.5T832 630h856q29 0 52.5 -23.5T1764 554V454q0 -29 -23.5 -52.5T1688 378ZM378 1386q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89t-37 -89t-89 -37ZM378 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T467 919T378 882ZM378 378q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T467 415T378 378Z"
355></glyph
356><glyph unicode="&#xf17e;" d="M1688 1386H832q-29 0 -52.5 23.5T756 1462v100q0 29 23.5 52.5T832 1638h856q29 0 52.5 -23.5T1764 1562V1462q0 -29 -23.5 -52.5T1688 1386ZM1688 882H832q-29 0 -52.5 23.5T756 958v100q0 29 23.5 52.5T832 1134h856q29 0 52.5 -23.5T1764 1058V958q0 -29 -23.5 -52.5T1688 882ZM1688 378H832q-29 0 -52.5 23.5T756 454V554q0 29 23.5 52.5T832 630h856q29 0 52.5 -23.5T1764 554V454q0 -29 -23.5 -52.5T1688 378ZM378 1386q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89t-37 -89t-89 -37ZM378 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T467 919T378 882ZM378 378q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T467 415T378 378Z"
357></glyph
358><glyph unicode="&#xf17f;" d="M1512 1279q0 98 -38.5 188t-103 155T1217 1725.5T1030 1764H986q-56 0 -110 -12.5T774.5 1715T685 1658t-75 -75t-57 -89.5T516.5 1392T504 1282V1134q-53 -7 -89.5 -47.5T378 992V400q0 -39 19.5 -72.5t53 -53T523 255h970q39 0 72.5 19.5t53 53T1638 400V989q0 36 -17 67t-46 50.5t-63 24.5v148ZM1030 1638q72 0 138 -28.5t113.5 -76t76 -113.5T1386 1282V1134H630v148q0 72 28.5 138t76 113.5t113.5 76T986 1638h44Z"
359></glyph
360><glyph unicode="&#xf180;" d="M0 1008Q0 721 202 479L63 151Q35 95 60 69.5T151 63L542 227Q764 126 1008 126q204 0 390.5 69.5t322 187t215.5 281t80 344.5t-80 344.5t-215.5 281t-322 187T1008 1890T617.5 1820.5t-322 -187T80 1352.5T0 1008ZM1210 554q-24 -31 -57 -58.5T1082.5 449t-78 -31.5t-81 -15t-78 4t-70.5 25T718 479q-12 12 -20 32t-9.5 44t4.5 50q11 47 48 89.5T828.5 764t106 42.5t109 12.5T1134 794v781q0 28 17.5 45.5T1197 1638t45.5 -17.5T1260 1575V756q0 -65 -11 -110t-39 -92Z"
361></glyph
362><glyph unicode="&#xf181;" d="M479 1134q-47 0 -74 -27t-27 -74V970q0 -15 4.5 -28.5t13 -24.5T416 898.5t28 -12T479 882h63q38 0 63 27t25 74v50q0 31 -12 54t-35 35t-54 12H479ZM983 1134q-47 0 -74 -27t-27 -74V970q0 -38 27 -63t74 -25h63q38 0 63 27t25 74v50q0 47 -27 74t-74 27H983ZM1474 1134q-15 0 -28.5 -4.5t-24.5 -13T1402.5 1096t-12 -28t-4.5 -35V970q0 -38 27 -63t74 -25h63q38 0 63 27t25 74v50q0 47 -27 74t-74 27h-63Z"
363></glyph
364><glyph unicode="&#xf182;" d="M1008 0q71 0 130 36.5t92 97.5q-54 -4 -109.5 -6T1008 126q-113 0 -222 8Q819 73 878 36.5T1008 0ZM1644 1222q-6 67 -28 131.5T1558.5 1474t-82 104T1374 1663.5T1256 1724q2 13 3 22t1 18q0 104 -74 178t-178 74T830 1942T756 1764q0 -14 4 -40Q602 1663 494.5 1526.5T372 1222L322 662Q276 646 240 627.5t-61.5 -38T139.5 548T126 504q0 -68 118 -126.5t321 -92T1008 252t443 33.5t321 92T1890 504q0 30 -23.5 58t-67 53T1694 662l-50 560ZM1008 1922q65 0 111.5 -46.5T1166 1764q0 -2 -1 -4t-1.5 -4t-0.5 -3q-56 11 -112 11H965q-56 0 -112 -12q0 2 -1.5 6t-1.5 6q0 32 12.5 61t34 50.5t50.5 34t61 12.5Z"
365></glyph
366><glyph unicode="&#xf183;" d="M682 1134l289 289q37 37 37 89t-37 89q-18 18 -41.5 27.5T882 1638t-47.5 -9.5T793 1601L289 1097q-37 -37 -37 -89t37 -89L793 415q37 -37 89 -37t89 37t37 89t-37 89L682 882h956q52 0 89 37t37 89t-37 89t-89 37H682Z"
367></glyph
368><glyph unicode="&#xf184;" d="M682 1134l289 289q37 37 37 89t-37 89q-18 18 -41.5 27.5T882 1638t-47.5 -9.5T793 1601L289 1097q-37 -37 -37 -89t37 -89L793 415q37 -37 89 -37t89 37t37 89t-37 89L682 882h956q52 0 89 37t37 89t-37 89t-89 37H682Z"
369></glyph
370><glyph unicode="&#xf185;" d="M606 1102l343 343q28 28 28 67t-28 67q-18 18 -42.5 24.5t-49 0T815 1579L311 1075q-6 -7 -12 -15q0 -1 -1.5 -3.5T296 1053q-1 0 -1.5 -1.5t-1 -2.5t-1.5 -2.5t-1 -2.5q-1 -2 -2 -7l-1 -2q0 -1 -1 -3l-2 -6q-3 -18 0 -36q1 -2 1 -3t1 -3t1 -2.5t0.5 -3t1 -4T291 972q1 -3 3 -7l2 -2q0 -1 1 -3l2 -4q2 -2 3 -4t2.5 -4t3.5 -3.5t3 -3.5L815 437q9 -9 20 -15t23 -9t24 -3q39 0 67 27.5T977 504t-28 67L606 914H1638q26 0 47.5 12.5t34 34T1732 1008q0 39 -27.5 66.5T1638 1102H606Z"
371></glyph
372><glyph unicode="&#xf186;" d="M1334 1134l-289 289q-24 24 -33 56.5t0 65t33 56.5q14 15 32.5 24t37.5 11.5t38 0t37.5 -11.5t32.5 -24l504 -504q24 -24 32.5 -56.5t0 -65T1727 919L1223 415q-37 -37 -89 -37q-25 0 -48 9.5T1045 415q-37 37 -37 89t37 89l289 289H378q-52 0 -89 37t-37 89t37 89t89 37h956Z"
373></glyph
374><glyph unicode="&#xf187;" d="M1334 1134l-289 289q-24 24 -33 56.5t0 65t33 56.5q14 15 32.5 24t37.5 11.5t38 0t37.5 -11.5t32.5 -24l504 -504q24 -24 32.5 -56.5t0 -65T1727 919L1223 415q-37 -37 -89 -37q-25 0 -48 9.5T1045 415q-37 37 -37 89t37 89l289 289H378q-52 0 -89 37t-37 89t37 89t89 37h956Z"
375></glyph
376><glyph unicode="&#xf188;" d="M1410 1102l-343 343q-27 28 -27 67t27.5 66.5T1134 1606t67 -27l504 -504q3 -3 6 -7t6 -8q1 -1 2 -4l1 -3q1 0 2 -2q2 -4 3 -7q1 -1 1.5 -2.5t1 -4t0.5 -3t1 -2.5t1 -3t1 -3q3 -18 0 -36q0 -1 -3 -9q0 -1 -1 -2l-2 -7q0 -2 -5 -9q0 -1 -1 -3q-1 -3 -2 -4q-2 -2 -3 -4t-2.5 -4t-3.5 -3.5t-3 -3.5L1201 437q-7 -7 -15 -12t-16.5 -8.5t-17.5 -5T1134 410q-39 0 -67 27q-27 28 -27 67t27 67l343 343H378q-26 0 -47.5 12.5t-34 34T284 1008q0 39 27.5 66.5T378 1102H1410Z"
377></glyph
378><glyph unicode="&#xf189;" d="M693 252H567q-52 0 -89 37t-37 89V1638q0 52 37 89t89 37H693q52 0 89 -37t37 -89V378q0 -52 -37 -89T693 252ZM1449 252H1323q-52 0 -89 37t-37 89V1638q0 52 37 89t89 37h126q52 0 89 -37t37 -89V378q0 -52 -37 -89t-89 -37Z"
379></glyph
380><glyph unicode="&#xf18a;" d="M504 1661V354q0 -61 40 -80t96 16L1674 924q56 34 56 83t-56 83L640 1725q-56 34 -96 15.5T504 1661Z"
381></glyph
382><glyph unicode="&#xf18b;" d="M1764 1764v189q0 26 -18.5 44.5T1701 2016t-44.5 -18.5T1638 1953V1764H1449q-26 0 -44.5 -18.5T1386 1701t18.5 -44.5T1449 1638h189V1449q0 -26 18.5 -44.5T1701 1386t44.5 18.5T1764 1449v189h189q26 0 44.5 18.5T2016 1701t-18.5 44.5T1953 1764H1764ZM504 1661V354q0 -61 40 -80t96 16L1674 924q56 34 56 83t-56 83L640 1725q-56 34 -96 15.5T504 1661Z"
383></glyph
384><glyph unicode="&#xf18c;" d="M1764 1764v189q0 26 -18.5 44.5T1701 2016t-44.5 -18.5T1638 1953V1764H1449q-26 0 -44.5 -18.5T1386 1701t18.5 -44.5T1449 1638h189V1449q0 -26 18.5 -44.5T1701 1386t44.5 18.5T1764 1449v189h189q26 0 44.5 18.5T2016 1701t-18.5 44.5T1953 1764H1764ZM504 1661V354q0 -61 40 -80t96 16L1674 924q56 34 56 83t-56 83L640 1725q-56 34 -96 15.5T504 1661Z"
385></glyph
386><glyph unicode="&#xf18d;" d="M1764 1764v189q0 26 -18.5 44.5T1701 2016t-44.5 -18.5T1638 1953V1764H1449q-26 0 -44.5 -18.5T1386 1701t18.5 -44.5T1449 1638h189V1449q0 -26 18.5 -44.5T1701 1386t44.5 18.5T1764 1449v189h189q26 0 44.5 18.5T2016 1701t-18.5 44.5T1953 1764H1764ZM504 1661V354q0 -61 40 -80t96 16L1674 924q56 34 56 83t-56 83L640 1725q-56 34 -96 15.5T504 1661Z"
387></glyph
388><glyph unicode="&#xf18e;" d="M1746 1865q-18 15 -41 9L697 1622q-6 -2 -11.5 -5t-10 -7.5T668 1600t-4.5 -11T662 1576V599q-81 46 -190 24Q415 612 362.5 582.5T272 513T211.5 423.5T189 325q0 -100 83 -154T472.5 140.5T673 251.5T756 439v851l914 222V779q-81 45 -190 24q-77 -16 -142 -61.5T1235 633T1197 504q0 -100 83 -154t200 -30q77 15 142.5 60.5T1726 489t38 129q0 2 0 1210q0 23 -18 37Z"
389></glyph
390><glyph unicode="&#xf18f;" d="M1134 1134v529q0 25 -14.5 48.5t-38 38T1033 1764H983q-38 0 -69.5 -31.5T882 1663V1134H353q-19 0 -37.5 -8.5T283 1103t-22.5 -32.5T252 1033V983q0 -25 14.5 -48.5t38 -38T353 882H882V353q0 -38 31.5 -69.5T983 252h50q19 0 37.5 8.5T1103 283t22.5 32.5T1134 353V882h529q38 0 69.5 31.5T1764 983v50q0 25 -14.5 48.5t-38 38T1663 1134H1134Z"
391></glyph
392><glyph unicode="&#xf190;" d="M126 1008q0 -181 69 -344.5T382 382T663.5 195T1008 126t344.5 69T1634 382t187 281.5t69 344.5t-69 344.5T1634 1634t-281.5 187T1008 1890T663.5 1821T382 1634T195 1352.5T126 1008ZM473 441q58 164 -7 202Q400 678 356 749T295.5 903.5T286 1074q9 27 24 49t39 40.5t44.5 31t54.5 32t56 33.5q13 10 20.5 24.5T534 1317t0.5 38.5t-7 43t-12 44T500 1487t-17 42t-18 39q108 104 248 162.5t295 58.5q173 0 329 -73q-25 -13 -64 -53q-20 -19 -36.5 -38.5t-26 -33t-18 -26.5t-14 -22t-13 -17T1151 1513.5t-18 -8t-26 -5t-36 -1.5q-63 0 -123 -96q-49 -80 -54 -145q-3 -45 24 -41q6 1 14 5q383 192 435 163q22 -12 -5 -73q-31 -75 -35 -90q-17 -71 61 -75q5 0 11 0q54 0 93.5 -14t61 -36.5t34 -51t16 -58.5t4.5 -58.5t1 -51t4 -36T1629 828t34 16q91 54 126 176q0 -7 0 -12q0 -257 -155 -465Q1492 353 1271 273Q1143 227 1008 227q-152 0 -290 56.5T473 441ZM995 1147q-38 -5 -82 -39.5t-74 -84T805.5 916T844 806q23 -27 51.5 -40.5T949 750t51.5 -3.5T1048 737t38 -28t26 -65t9 -115q0 -29 5 -51.5T1137.5 441t18 -24.5t20.5 -15t24.5 -7.5t23.5 -3t23 0q16 0 44.5 26t62 73T1417 594t50 127.5T1487 857q0 43 -10.5 76T1449 985.5t-41.5 32t-48 17t-52 5.5t-49.5 -1t-43 -4t-31 -2q-6 -3 -14 8.5t-20 30t-29.5 37t-50.5 30t-75 8.5Z"
393></glyph
394><glyph unicode="&#xf191;" d="M374 1342q-1 4 -2 9t-1.5 9.5T368 1369q-3 7 -6 10t-4 5q-1 2 -2.5 4t-3 4t-3 4.5t-3.5 5t-3 4.5t-2 3l-1 1l-16 91q-12 -9 -22.5 -22.5T280 1448q0 0 -1 0Q210 1337 178 1213q8 2 13 4l-5 -21q2 5 18 16t22 20q6 8 11.5 9.5t14.5 0t14 -1.5q4 1 7 2t4.5 2t3 3t2.5 4t4 5t7 6q22 16 25 29q2 6 22 6q5 0 8 0q0 -1 -0.5 -1t-0.5 -1q2 0 5 2q9 0 11 0q1 0 3 0q1 0 1 0q0 0 0 -0.5t1 -1.5q8 2 10 5q9 4 2 12q-1 2 -1.5 5.5t-2 11.5t-3.5 13ZM126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM450 410q0 4 0.5 17.5T452 446t4 13.5T466 472t17 5q14 -13 29 29q5 12 10 32q1 4 -0.5 22t-2 30.5T522 607q10 2 18.5 19.5T551 660q2 13 -1.5 22.5t-11 15t-18 9.5T499 712t-21.5 1.5t-19 0T446 714q-5 6 -17 8t-20 5.5T402 742q-8 5 -24 -1q-1 0 -2 0q0 0 3 3q7 23 -11 40t-44.5 25.5t-49.5 21T250 855q-4 1 -9 1.5t-8 1t-3 0.5q-20 1 -27 1q-14 77 -14 149q0 117 32.5 227.5t91 203.5T452 1608q2 -2 2 -4t-0.5 -4t0.5 -8q0 -3 0.5 -5.5t0 -4.5t-0.5 -3t-1 -3t-1.5 -3t-2 -3t-2.5 -4q-3 -5 -4 -13.5T440 1537q-2 -9 -1.5 -13t1.5 -8.5t1 -7.5q0 -3 0 -4.5t1.5 -3.5t2 -2.5t3.5 -3t5 -4.5q4 -3 5 -7t1 -8.5t1 -7.5q2 -5 13 -9.5t15 -4.5q2 0 7.5 6.5T503 1472q3 6 16 23.5t19 20.5q39 19 45 23q7 4 26.5 12t38.5 15.5t24 10.5q8 4 12 5.5t9 4.5t5 7.5t-1.5 13T696 1621q2 9 8 10.5t7 4.5q0 3 -0.5 5.5t-1 4T709 1649t1 4q2 4 29 24q3 3 12.5 7.5t15.5 8t5 3.5q-2 1 -31 0t-34 -2q-2 0 -4 -0.5t-3.5 -0.5t-3 -0.5T693 1692t-4 0q-65 0 -70 -1q-5 -1 -11.5 -2T593 1686t-13.5 -3T567 1680.5t-8 -2.5q-4 -1 -21 0q102 71 221.5 110t248.5 39q118 0 228 -32.5T1443 1701l-15 -11q-17 -18 -24 -18h-17q-6 1 -17.5 3.5t-16 3.5t-10.5 -1q-2 -1 -7.5 -5.5t-11 -9.5t-12 -10.5T1303 1644q-7 -5 -21.5 -10t-18.5 -5q-2 0 -13.5 -3.5t-24 -7.5t-16.5 -5q-6 -2 -51 -3q-16 -1 -31.5 1t-22.5 2h-19q-10 2 -18 6.5t-13 6.5t-10 2q-5 0 -20.5 -7.5T996 1606l-13 -8q-1 -1 -2.5 -2.5t-3.5 -3t-5 -4.5t-8 -7q-3 -3 -6 -6t-5.5 -5.5t-5 -5.5t-4.5 -5t-3.5 -4t-2 -3t-0.5 -1l-34 -19q3 -18 -2 -27q-1 -2 -2 -4t-1.5 -4.5T897 1492t0.5 -4t2 -3.5t4.5 -2t7.5 -0.5t8.5 0t7 0.5t6 1.5t4.5 1.5t3 1t2.5 1.5q19 -17 23 -23q2 -3 6 -8t7 -8l2 -3l-63 -19l-40 -47l-24 -13l-38 -18q9 -13 15 -13h17q2 0 4.5 -1.5t4.5 -3t3.5 -3T862 1326l1 -2q-21 -10 -28 -10l-40 -12l-15 -30l5 -23q0 0 -5 -16q2 -2 5 -1q14 7 19 4t10 -8.5t11 -3.5q7 2 21 14.5t22 13.5q6 2 27 18t39 31l18 16l36 -19q2 -34 12 -39q4 -1 10 -0.5t13.5 1.5t14 2.5t11.5 2.5l4 1q3 1 6 2.5t11.5 4T1081 1272q6 -4 36 -10q5 -2 12 -3t25.5 -4t23.5 0q8 2 18 4.5t17 3.5l6 2l-14 -65q11 -21 28 -38q8 -8 15 -16.5t12 -12.5q6 -5 9.5 -20.5T1280 1090q3 -3 17 -14.5t23 -21t10 -14.5q1 -5 0.5 -10.5t-0.5 -10t2.5 -8.5t8.5 -5q12 -4 23 -3.5t19 5.5l4 2l24 19q10 8 17.5 13.5t10.5 8.5t5 5.5t4 4.5t5 4q2 1 8 5t8.5 6.5t2.5 9.5t-4 17q-2 5 -6 10.5t-6.5 9t-6.5 8.5q-10 9 -9.5 13.5t15.5 4.5q20 0 40 1.5t30 1.5q55 0 63 -5q2 -1 11.5 -2.5T1615 1139t7 -13q1 -5 2 -9.5t2 -8t2 -6.5t3 -7.5t3.5 -8.5t4.5 -13.5t5.5 -16t7 -15T1662 1027q3 -3 8.5 -8.5t7 -7t5.5 -4t7 -3t8 -0.5q10 0 14 0.5t7.5 3t6.5 8.5q2 5 1 10.5t-1.5 13.5t-0.5 15.5t3 14t10 10.5q12 5 29 31.5t31 27.5q11 1 17 1q12 -71 12 -132q0 -166 -65 -318T1587.5 428.5T1326 254T1008 189q-159 0 -302.5 58T450 410ZM497 485h-1q1 1 1 0ZM1258 963q2 1 -5 8t-19 19t-25.5 26.5t-26 32.5t-19.5 33q-37 44 -74 59q-4 0 -8.5 0.5T1069 1142q-3 1 -5.5 1.5t-5 1t-4 1t-3.5 1t-3 0.5q-2 0 -4 0.5t-3 0.5q-5 -1 -11 -23q-4 -8 -17 -6t-21 8q-5 4 -18.5 9t-24.5 8t-11 2q-6 0 -6 8.5t2 19.5t1 13q-7 -1 -24 -3.5T885.5 1179t-22 -5t-25 -7.5T815 1155l-81 -65q-1 -2 -4 -7t-4.5 -7t-4 -6t-4.5 -7t-4 -6q-1 -3 -4 -8t-4.5 -7.5T700 1034t-4.5 -7.5t-4 -7.5t-4.5 -8t-4 -7.5t-4 -8T675.5 988T672 980q-4 -8 2 -11.5T678 957q-9 -11 -6 -50.5T689 863q3 2 21 -19.5T724 817q11 -3 28.5 -10.5t30 -12.5t29 -4.5T843 799q9 5 17.5 7.5t17 2t15.5 -2T910 803t18 -3q3 0 10 0t8.5 -0.5t6 -1t5 -2.5t3 -4.5t2.5 -7t0.5 -10T964 760q-2 -13 3.5 -29.5T982 700t17 -32t12 -35.5t0 -40.5q-8 -13 -8.5 -28t7.5 -32.5T1024 503t20 -30t16 -23q8 -12 14 -32t11.5 -37T1097 358q21 1 34 3t24.5 8.5T1176 384t23 24q2 2 9.5 10t9.5 11t6 9.5t5 12.5t2 15q-6 3 0 9t15 12.5t9 9.5q0 6 -3.5 19t-4 19t6.5 15q28 23 44 54q9 16 4.5 34T1289 669t-14 29.5t2 29.5q2 1 6 8t8 15t8 16t6 10q8 12 26 34t25 32q10 15 13.5 30.5t5 32.5t5.5 27q-6 2 -23.5 -7T1335 916q-9 -2 -27.5 -4T1285 908q11 4 -4 28t-23 27Z"
395></glyph
396><glyph unicode="&#xf192;" d="M813 1446q32 -7 0 -33q0 -3 9 -3t11 1q-3 -1 -11 -8.5T809 1392q15 -6 40 8.5t25 23.5q0 0 -10.5 9T842 1451.5t-13 9.5q0 -4 6 3q6 6 5 15q-2 0 -4 0.5t-4.5 0.5t-4.5 -0.5t-4 -1.5q-1 2 -0.5 3.5t1 3t2 2.5t3.5 2q-7 0 -11.5 -4t-7.5 -8.5t-5 -4.5q-1 6 -5 2q0 -8 5.5 -11.5T808 1452q0 0 2 0q3 0 3.5 -0.5T813 1446ZM809 1442q-6 8 -24 1q-19 -8 -7 -20l-9 -10l-3 -2q4 0 1 -3q15 -12 27 4.5t15 29.5ZM126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM450 409q1 5 1 18t1 18.5t4 14T466 472t17 5q14 -13 30 30q4 12 9 30v1q1 4 -0.5 22t-2 30.5T522 607q10 2 18.5 19.5T551 660q3 15 -2.5 25.5T533 701t-23 8.5T484.5 713t-23 0.5T446 714q-5 6 -17 8t-20 5.5T402 742q-8 5 -24 -1q-1 0 -2 0q0 0 3 3q6 19 -5 33t-31 23.5T302.5 818t-36 17.5T250 855q-4 1 -9 1.5t-8 1t-3 0.5q-21 1 -27 1q-7 37 -10.5 74t-3.5 75q0 28 2 55.5t5.5 54.5t9 53.5T218 1224q6 5 8 8q6 8 11.5 9.5t14.5 0t14 -1.5q4 1 7 2t4.5 2t3 3t2.5 4t4 5t7 6q22 16 25 29q2 6 22 6q5 0 8 0q0 -1 -0.5 -1t-0.5 -1q2 0 5 2q9 0 11 0q1 0 3 0q1 0 1 0q0 0 0 -0.5t1 -1.5q8 2 10 5q9 4 2 12q-1 2 -1.5 5.5t-2 11.5t-3.5 13q-1 4 -2 9t-1.5 9.5T368 1369q-3 7 -6 10t-4 5q-1 2 -2.5 4t-3 4t-3 4.5t-3.5 5t-3 4.5t-2 3l-1 1l-10 57q52 77 122 142q2 -3 2 -4.5t-0.5 -4T454 1592q0 -3 0.5 -5.5t0 -4.5t-0.5 -3t-1 -3t-1.5 -3t-2 -3t-2.5 -4q-3 -5 -4 -13.5T440 1537q-2 -9 -1.5 -13t1.5 -8.5t1 -7.5q0 -3 0 -4.5t1.5 -3.5t2 -2.5t3.5 -3t5 -4.5q4 -3 5 -7t1 -8.5t1 -7.5q2 -5 13 -9.5t15 -4.5q2 0 7.5 6.5T503 1472q3 6 16 23.5t19 20.5q39 19 45 23q7 4 26.5 12t38.5 15.5t24 10.5q8 4 12 5.5t9 4.5t5 7.5t-1.5 13T696 1621q2 9 8 10.5t7 4.5q0 3 -0.5 5.5t-1 4T709 1649t1 4q0 1 3 4t8.5 7.5t8.5 6.5t9 6q3 3 12.5 7.5t15.5 8t5 3.5q-2 1 -31 0t-34 -2q-2 0 -4 -0.5t-3.5 -0.5t-3 -0.5T693 1692t-4 0q-65 0 -70 -1q-3 0 -6 -0.5t-6 -1.5t-6.5 -1.5t-7 -1.5t-7.5 -1.5t-7 -1.5t-6 -1.5t-5.5 -1t-5 -1T559 1678q-4 -1 -22 0q212 149 471 149q236 0 435 -126l-15 -11q-2 -2 -5 -5t-9.5 -8t-9.5 -5q-2 0 -3 -0.5t-1.5 -0.5t-3.5 0t-9 1q-5 1 -13 2.5t-13 3t-11 2t-7 -1.5q-2 -1 -7.5 -5.5t-11 -9.5t-12 -10.5T1303 1644q-7 -5 -21.5 -10t-18.5 -5q-2 0 -13.5 -3.5t-24 -7.5t-16.5 -5q-6 -2 -51 -3q-16 -1 -31.5 1t-22.5 2h-19q-10 2 -18 6.5t-13 6.5t-10 2q-5 0 -20.5 -7.5T996 1606l-13 -8q-1 -1 -2.5 -2.5t-3.5 -3t-5 -4.5t-8 -7q-3 -3 -6 -6t-5.5 -5.5t-5 -5.5t-4.5 -5t-3.5 -4t-2 -3t-0.5 -1l-34 -19q3 -18 -2 -27q-12 -23 10 -23q6 0 11.5 0.5t9 1.5t6.5 2t4 1l1 1q19 -17 23 -23l15 -19l-63 -19l-40 -47l-24 -13l-38 -18q9 -13 15 -13h17l15 -12q-1 0 -2.5 -0.5T855 1321t-7.5 -3t-7 -2.5T835 1314l-40 -12l-15 -30l5 -23q0 0 -5 -16q1 -3 5 -1q14 7 19 4t10.5 -8.5T825 1224q7 2 21 14.5t22 13.5q6 2 27 18t39 31l18 16l36 -19q2 -34 12 -39q4 -1 10 -0.5t13.5 1.5t14 2.5t11.5 2.5l4 1l28 6q1 -1 5.5 -2.5t9.5 -3t9.5 -2.5t8.5 -2h3q5 -2 12 -3t25.5 -4t23.5 0q8 2 18 4.5t17 3.5l6 2l-14 -65q11 -21 28 -38q6 -5 10 -10t6 -8t5 -6t6 -5q6 -5 9.5 -20.5T1280 1090q3 -3 12 -11t17 -14.5t14.5 -13.5t6.5 -11q1 -5 0.5 -10.5t-0.5 -10t2.5 -8.5t8.5 -5q12 -4 23 -3.5t19 5.5l4 2l24 19q23 16 32.5 26t9.5 10q2 1 8 5t8.5 6.5t2.5 9.5t-4 17q-2 5 -6 10.5t-6.5 9t-6.5 8.5q-10 9 -9.5 13.5t15.5 4.5q20 0 40 1.5t30 1.5q55 0 63 -5q3 -1 9 -2t11 -2.5t9 -5.5t5 -11t2.5 -12t2.5 -8.5t3.5 -9T1635 1086q1 -4 4 -13.5t5.5 -16t7 -15T1662 1027q3 -3 8.5 -8.5t7 -7t5.5 -4t7 -3t8 -0.5q10 0 14 0.5t7.5 3t6.5 8.5q2 5 1 10.5t-1.5 13.5t-0.5 15.5t3 14t10 10.5q11 5 20.5 19.5t19 26.5t20.5 13q12 1 18 1q11 -66 11 -132q0 -166 -65 -318T1587.5 428.5T1326 254T1008 189Q686 189 450 409ZM497 485h-1q1 1 1 0ZM1268 969q2 0 -16 18t-43.5 48t-35.5 53q-17 20 -35.5 35.5T1099 1146q-5 1 -20 2q-7 1 -21 5q-4 0 -7 1q-5 -1 -11 -23q-4 -9 -17 -6.5t-21 8.5q-5 4 -18.5 9t-24.5 8t-11 2q-4 0 -5.5 3.5t-1 9t1.5 11t1.5 10.5t0.5 7q-7 -1 -24 -3.5T895.5 1185t-22 -5t-25 -8T825 1161l-81 -65q-1 -2 -4 -6.5t-4.5 -7t-4 -6.5t-4.5 -7t-4 -7q-31 -52 -41 -76q-4 -8 2 -11.5T688 963q-9 -11 -6 -50.5T699 869q3 2 21 -19.5T734 822q11 -2 28.5 -9.5t30 -12.5t29 -5T853 805q14 8 26.5 9T910 811t28 -5q3 0 10 0t8.5 -0.5t6 -1t5 -2.5t2.5 -4.5t2.5 -7t1 -10.5T974 766q-2 -16 6.5 -37t20 -38.5t18.5 -43t2 -49.5q-8 -13 -8.5 -28t7 -32.5t14 -28.5t20 -30T1070 456q9 -14 19 -49.5T1107 364q27 1 43.5 6t28.5 14t30 30q2 2 9.5 10t9 11t5.5 9.5t5.5 12.5t1.5 14q-8 5 15 22q9 7 10 9q0 7 -3.5 20t-4 19t6.5 15q13 11 24.5 25t19.5 29q8 16 4 34t-13 31t-14 29.5t2 29.5q1 1 3.5 4.5t5 8T1301 757t5.5 11t4.5 9t3 6q4 5 8.5 11t8.5 11t9 11t9 11t8.5 11t8.5 11q8 11 12 24t4.5 23t2 22t5.5 21q-6 1 -24 -7.5T1345 922q-8 -2 -19 -3.5t-19.5 -2T1294 914q12 4 -3 28t-23 27Z"
397></glyph
398><glyph unicode="&#xf193;" d="M1890 315q0 -26 -18.5 -44.5T1827 252H189q-26 0 -44.5 18.5T126 315t18.5 44.5T189 378H1827q26 0 44.5 -18.5T1890 315ZM1890 819q0 -26 -18.5 -44.5T1827 756H189q-26 0 -44.5 18.5T126 819t18.5 44.5T189 882H1827q26 0 44.5 -18.5T1890 819ZM1890 1619V1405q0 -60 -42.5 -102.5T1745 1260H271q-39 0 -72.5 19.5t-53 53T126 1405v214q0 60 42.5 102.5T271 1764H1745q60 0 102.5 -42.5T1890 1619Z"
399></glyph
400><glyph unicode="&#xf194;" d="M1259 1008q0 -104 -73.5 -177.5T1008 757q-41 0 -79.5 12.5t-69 36t-54 54.5t-36 69T757 1008q0 104 73.5 177.5T1008 1259t177.5 -73.5T1259 1008ZM1442 610q-13 15 -12.5 34.5T1444 677q69 65 106 150.5t37 180.5t-37 180.5T1444 1339q-14 13 -14.5 32.5t13 34t33 15T1509 1408q82 -78 127 -182.5T1681 1008q0 -57 -11 -112T1637 790.5T1582.5 694T1509 609q-14 -13 -32 -13q-21 0 -35 14ZM1589 305q-12 16 -9 35t19 31q152 111 237.5 280t85.5 357t-85.5 357T1599 1645q-16 12 -19 31t8.5 35t31 18.5T1655 1721q169 -125 265 -314t96 -399T1920 609T1655 295q-3 -1 -5 -2.5t-4.5 -2.5t-4.5 -2t-4.5 -1.5t-5 -0.5t-4.5 0q-5 0 -9 0.5t-8 2.5t-8 4t-7 5t-6 7ZM507 609q-17 15 -32 32t-28.5 34.5T421 712t-22.5 38.5t-19.5 40T363 832t-12 42.5T342 918t-5.5 44.5T335 1008q0 75 20 147t59 136.5T507 1407q14 14 33.5 13.5T574 1406q8 -10 11 -22t-0.5 -24T572 1339q-28 -26 -50.5 -55.5t-40 -62t-29 -67.5T435 1082.5T429 1008q0 -63 16.5 -122.5T494 773t78 -96q9 -9 12.5 -21T585 632T574 610q-4 -3 -8 -6t-8.5 -4.5t-9 -2.5T539 596q-9 0 -17 3t-15 10ZM361 295Q192 420 96 609T0 1008t96 399t265 314q7 4 14 6.5t14 2.5t14 -2t13.5 -6.5T427 1711q12 -16 9 -35t-19 -31Q265 1534 179.5 1365T94 1008T179.5 651T417 371q10 -8 15 -19.5t4 -24T427 305q-4 -6 -10.5 -10.5t-13 -6.5T389 286q-15 0 -28 9Z"
401></glyph
402><glyph unicode="&#xf195;" d="M1731 1008v1q0 147 -57 281t-154.5 231.5t-231.5 155T1007 1734q-245 0 -440 -149Q388 1447 318 1233Q283 1124 282 1009q0 -147 57.5 -281t155 -231.5T726 342t281 -57q75 0 147.5 14.5T1295 344q36 16 50.5 52.5T1344 468q-7 18 -21 31t-30.5 19.5T1257 525t-37 -8Q1118 474 1007 474q-109 0 -208 42T628.5 630t-114 171T472 1009q0 73 19 142t53.5 128t84 108.5t108.5 84t128 54t142 19.5q109 0 208 -42.5T1386 1388t114.5 -171.5T1543 1008H1336q-32 0 -38.5 -15.5T1313 955L1584 684q22 -22 53.5 -22t53.5 22l271 271q15 14 17 26.5t-8 19.5t-31 7H1731Z"
403></glyph
404><glyph unicode="&#xf196;" d="M1731 1008v1q0 98 -26 192t-72.5 173.5T1519 1521t-146.5 113.5t-173.5 73T1007 1734q-245 0 -440 -149Q388 1447 318 1233Q283 1124 282 1009q0 -147 57.5 -281t155 -231T726 342.5T1007 285q30 0 59.5 2t59 7t58 12t56.5 16.5t55 21.5q36 16 50.5 52.5T1344 469q-10 23 -30.5 38T1269 524.5T1220 518q-34 -15 -69 -25t-71 -14.5T1007 474Q812 474 663 599Q521 718 483 898q-11 55 -12 111q0 62 14.5 122.5t40.5 113t63 99t83.5 83.5t99 63t113 40.5T1007 1545q73 0 142 -19.5t128 -54t108.5 -84t84 -108.5T1523 1150.5T1542 1008H1336q-32 0 -38.5 -15.5T1313 955L1585 683q14 -14 33.5 -19t39 0t33.5 19l272 272q22 22 15.5 37.5T1940 1008H1731Z"
405></glyph
406><glyph unicode="&#xf197;" d="M1731 1008v1q0 147 -57 281t-154.5 231.5t-231.5 155T1007 1734T726 1676.5t-231.5 -155T339.5 1290T282 1009T339.5 728t155 -231.5T726 342t281 -57q151 0 288 59q36 16 50.5 52.5t-1 72t-52 50T1220 518q-51 -22 -104 -33T1007 474q-109 0 -208 42.5t-171 114T513.5 801T471 1009q0 73 19.5 142.5t54 128t84 108t108 84t128 54T1007 1545q109 0 208 -42.5T1386 1388t114 -171.5T1542 1008H1336q-32 0 -38.5 -15.5T1313 955L1585 683q22 -22 53 -22t53 22l272 272q22 22 15.5 37.5T1940 1008H1731Z"
407></glyph
408><glyph unicode="&#xf198;" d="M1512 1449v378q0 26 -18.5 44.5T1449 1890t-44.5 -18.5T1386 1827V1449q0 -26 18.5 -44.5T1449 1386t44.5 18.5T1512 1449ZM1638 1638V1449q0 -78 -55.5 -133.5T1449 1260t-133.5 55.5T1260 1449v189H756V1449q0 -78 -55.5 -133.5T567 1260t-133.5 55.5T378 1449v189H252q-52 0 -89 -37t-37 -89V252q0 -52 37 -89t89 -37H1764q52 0 89 37t37 89V1512q0 52 -37 89t-89 37H1638ZM252 252v882H1764V252H252ZM630 1449v378q0 26 -18.5 44.5T567 1890t-44.5 -18.5T504 1827V1449q0 -26 18.5 -44.5T567 1386t44.5 18.5T630 1449Z"
409></glyph
410><glyph unicode="&#xf199;" d="M1512 1449v378q0 26 -18.5 44.5T1449 1890t-44.5 -18.5T1386 1827V1449q0 -26 18.5 -44.5T1449 1386t44.5 18.5T1512 1449ZM630 1449v378q0 26 -18.5 44.5T567 1890t-44.5 -18.5T504 1827V1449q0 -26 18.5 -44.5T567 1386t44.5 18.5T630 1449ZM1638 1638V1449q0 -78 -55.5 -133.5T1449 1260t-133.5 55.5T1260 1449v189H756V1449q0 -78 -55.5 -133.5T567 1260t-133.5 55.5T378 1449v189H252q-52 0 -89 -37t-37 -89V252q0 -52 37 -89t89 -37H1764q52 0 89 37t37 89V1512q0 52 -37 89t-89 37H1638ZM252 252v882H1764V252H252Z"
411></glyph
412><glyph unicode="&#xf19a;" d="M1638 1638V1449q0 -78 -55.5 -133.5T1449 1260t-133.5 55.5T1260 1449v189H756V1449q0 -78 -55.5 -133.5T567 1260t-133.5 55.5T378 1449v189H252q-52 0 -89 -37t-37 -89V252q0 -52 37 -89t89 -37H1764q52 0 89 37t37 89V1512q0 52 -37 89t-89 37H1638ZM220 220v914H1796V220H220ZM1512 1449v378q0 26 -18.5 44.5T1449 1890t-44.5 -18.5T1386 1827V1449q0 -26 18.5 -44.5T1449 1386t44.5 18.5T1512 1449ZM630 1449v378q0 26 -18.5 44.5T567 1890t-44.5 -18.5T504 1827V1449q0 -26 18.5 -44.5T567 1386t44.5 18.5T630 1449Z"
413></glyph
414><glyph unicode="&#xf19b;" d="M1670 1008V911q0 -51 -17.5 -98.5t-48.5 -86T1531.5 659t-93 -45T1332 598H630V806q0 16 -4.5 25.5T614 844t-17 -1T577 829L305 557Q283 535 283 504t22 -53L577 179q10 -10 20 -14t17 -1t11.5 12.5T630 202V410h702q107 0 204.5 39.5t168 107t112 160T1858 911v97q0 39 -27.5 66.5T1764 1102t-66.5 -27.5T1670 1008ZM346 1105q0 32 7 63t20 58.5t31.5 53t41 46.5t50 38t57 29t63 18.5T684 1418h702V1210q0 -32 15.5 -38.5T1439 1187l272 272q22 22 22 53t-22 53l-272 272q-22 22 -37.5 15.5T1386 1814V1606H684q-107 0 -204.5 -39.5T311.5 1460t-112 -160T158 1105v-97q0 -39 27.5 -66.5T252 914t66.5 27.5T346 1008v97Z"
415></glyph
416><glyph unicode="&#xf19c;" d="M2016 1008q0 179 -80 342.5T1721 1632t-321.5 188T1008 1890T616.5 1820T295 1632T80 1350.5T0 1008T80 665.5T295 384T616.5 196T1008 126q251 0 473 103L1871 62q60 -25 84.5 -1t-1.5 84L1812 477q97 113 150.5 248.5T2016 1008ZM1331 920q-34 -25 -49 -72t-2 -87l85 -263q14 -41 -1.5 -52T1314 460L1091 623q-35 25 -84 25T924 623L700 460Q677 444 662 443t-18.5 13.5T648 498l86 263q13 40 -2 87t-49 72L461 1081q-34 25 -28.5 43t48.5 18H754q43 0 82.5 29t53.5 69l85 261q13 41 32 41t32 -41l85 -261q14 -40 53.5 -69t82.5 -29h274q42 0 48 -18t-29 -43L1331 920Z"
417></glyph
418><glyph unicode="&#xf19d;" d="M2016 1008q0 179 -80 342.5T1721 1632t-321.5 188T1008 1890T616.5 1820T295 1632T80 1350.5T0 1008T80 665.5T295 384T616.5 196T1008 126q251 0 473 103L1871 62q60 -26 84.5 -1.5T1954 145L1812 477q97 113 150.5 248.5T2016 1008ZM1331 920q-34 -25 -49 -72t-2 -87l86 -263q13 -41 -2.5 -52T1314 460L1091 623q-23 16 -53.5 22t-61 0T924 623L700 460Q666 435 650.5 446T648 498l86 263q13 40 -2 87t-49 72L461 1081q-34 25 -28.5 43t48.5 18H754q43 0 83 29t53 69l85 261q14 41 32.5 41t31.5 -41l85 -261q13 -40 53 -69t83 -29h274q42 0 48 -18t-28 -43L1331 920Z"
419></glyph
420><glyph unicode="&#xf19e;" d="M2016 1008q0 179 -80 342.5T1721 1632t-321.5 188T1008 1890T616.5 1820T295 1632T80 1350.5T0 1008T80 665.5T295 384T616.5 196T1008 126q251 0 473 103L1871 62q60 -25 84.5 -1t-1.5 84L1812 477q97 113 150.5 248.5T2016 1008ZM1331 920q-34 -25 -49 -72t-2 -87l85 -263q14 -41 -1.5 -52T1314 460L1091 623q-35 25 -84 25T924 623L700 460Q677 444 662 443t-18.5 13.5T648 498l86 263q13 40 -2 87t-49 72L461 1081q-34 25 -28.5 43t48.5 18H754q43 0 82.5 29t53.5 69l85 261q13 41 32 41t32 -41l85 -261q14 -40 53.5 -69t82.5 -29h274q42 0 48 -18t-29 -43L1331 920Z"
421></glyph
422><glyph unicode="&#xf19f;" d="M1596 598Q1520 496 1418 420L1675 163q37 -37 89 -37t89 37q24 24 33 56.5t0 65T1853 341L1596 598ZM1544 1134q0 -134 -52.5 -256.5T1350 666T1138.5 524.5T882 472T625.5 524.5T414 666T272.5 877.5T220 1134t52.5 256.5T414 1602t211.5 141.5T882 1796t256.5 -52.5T1350 1602t141.5 -211.5T1544 1134ZM126 1134q0 -154 60 -294T347 599T588 438T882 378t294 60t241 161t161 241t60 294t-60 294t-161 241t-241 161t-294 60T588 1830T347 1669T186 1428T126 1134Z"
423></glyph
424><glyph unicode="&#xf1a0;" d="M618 1244q23 39 49.5 79t58.5 81Q524 1606 252 1606q-39 0 -66.5 -27.5T158 1512t27.5 -66.5T252 1418q33 0 63.5 -4T374 1402.5T428.5 1384t51 -25T528 1327t46 -38.5T618 1244ZM1512 1210q0 -32 15.5 -38.5T1565 1187l272 272q22 22 22 53t-22 53l-272 272q-22 22 -37.5 15.5T1512 1814V1598q-110 -14 -208 -53t-169 -89T999 1335.5t-108 -133T804 1062Q751 968 706 900.5T608.5 773T503 676.5T387 619T252 598q-39 0 -66.5 -27.5T158 504t27.5 -66.5T252 410q77 0 148 17t128.5 45T641 545t97 89.5t86.5 106t75.5 112T969 969q113 201 243.5 306.5T1512 1408V1210ZM1512 806V604q-68 7 -123 21t-99 36t-78 49.5T1147 774q-25 -44 -51 -85t-54 -81q81 -81 193.5 -130.5T1512 415V202q0 -32 15.5 -38.5T1565 179l272 272q22 22 22 53t-22 53L1565 829q-22 22 -37.5 15.5T1512 806Z"
425></glyph
426><glyph unicode="&#xf1a1;" d="M630 1119v517q0 48 -34 82.5T514 1753H494q-31 0 -58 -15.5T393.5 1695T378 1636V368q0 -48 34 -82t82 -34h20q48 0 82 34t34 82V896L1516 290q17 -12 32.5 -17t29 -5t25 6t19 17t12 27t4.5 36V1661q0 61 -35.5 79.5T1516 1725L630 1119Z"
427></glyph
428><glyph unicode="&#xf1a2;" d="M1502 1753q-19 0 -36.5 -6t-32 -17t-25 -25T1392 1673t-6 -37V1119L500 1725q-51 34 -86.5 15.5T378 1661V354q0 -61 35.5 -80T500 290l886 606V368q0 -48 34 -82t82 -34h20q48 0 82 34t34 82V1636q0 32 -15.5 59t-42.5 42.5t-58 15.5h-20Z"
429></glyph
430><glyph unicode="&#xf1a3;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4ZM1532 590q-26 16 -32.5 45.5T1509 690q92 145 92 318q0 175 -94 321q-6 10 -9 21.5t-2.5 22.5t4.5 21.5t11.5 20T1529 1430q12 8 26.5 10.5t28 -0.5t25.5 -11t20 -21q29 -44 51 -92.5t37 -98.5t22.5 -103t7.5 -106q0 -215 -115 -396q-10 -16 -26.5 -25T1571 578q-22 0 -39 12ZM1747 430q-25 17 -31 46.5t11 54.5q143 216 143 477q0 264 -147 482q-17 25 -11 54.5t31 46.5t54.5 11.5T1844 1572q172 -255 172 -564q0 -305 -168 -557q-22 -33 -61 -33q-22 0 -40 12ZM0 1008q0 205 80 391.5T295 1721t321.5 215t391.5 80q124 0 243 -29.5t227.5 -87T1680 1760q22 -20 23.5 -50.5T1685 1657t-50 -24t-52 18q-119 106 -267.5 162.5T1008 1870q-100 0 -197 -22.5t-182 -65T469 1681T335 1547T233.5 1387t-65 -182T146 1008q0 -117 31 -229T263.5 572.5t135 -174t174 -135T779 177t229 -31q159 0 307.5 56.5T1583 365q22 20 52 18t50 -24t18.5 -52.5T1680 256Q1610 195 1531.5 147T1368 66.5T1192 17T1008 0Q803 0 616.5 80T295 295T80 616.5T0 1008Z"
431></glyph
432><glyph unicode="&#xf1a4;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4ZM1532 590q-26 16 -32.5 45.5T1509 690q92 145 92 318q0 175 -94 321q-6 10 -9 21.5t-2.5 22.5t4.5 21.5t11.5 20T1529 1430q12 8 26.5 10.5t28 -0.5t25.5 -11t20 -21q29 -44 51 -92.5t37 -98.5t22.5 -103t7.5 -106q0 -215 -115 -396q-10 -16 -26.5 -25T1571 578q-22 0 -39 12ZM1747 430q-25 17 -31 46.5t11 54.5q143 216 143 477q0 264 -147 482q-17 25 -11 54.5t31 46.5t54.5 11.5T1844 1572q172 -255 172 -564q0 -305 -168 -557q-22 -33 -61 -33q-22 0 -40 12ZM0 1008q0 205 80 391.5T295 1721t321.5 215t391.5 80q124 0 243 -29.5t227.5 -87T1680 1760q22 -20 23.5 -50.5T1685 1657t-50 -24t-52 18q-119 106 -267.5 162.5T1008 1870q-100 0 -197 -22.5t-182 -65T469 1681T335 1547T233.5 1387t-65 -182T146 1008q0 -117 31 -229T263.5 572.5t135 -174t174 -135T779 177t229 -31q159 0 307.5 56.5T1583 365q22 20 52 18t50 -24t18.5 -52.5T1680 256Q1610 195 1531.5 147T1368 66.5T1192 17T1008 0Q803 0 616.5 80T295 295T80 616.5T0 1008Z"
433></glyph
434><glyph unicode="&#xf1a5;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4ZM1532 590q-26 16 -32.5 45.5T1509 690q92 145 92 318q0 175 -94 321q-6 10 -9 21.5t-2.5 22.5t4.5 21.5t11.5 20T1529 1430q12 8 26.5 10.5t28 -0.5t25.5 -11t20 -21q29 -44 51 -92.5t37 -98.5t22.5 -103t7.5 -106q0 -215 -115 -396q-10 -16 -26.5 -25T1571 578q-22 0 -39 12ZM1747 430q-25 17 -31 46.5t11 54.5q143 216 143 477q0 264 -147 482q-17 25 -11 54.5t31 46.5t54.5 11.5T1844 1572q172 -255 172 -564q0 -305 -168 -557q-22 -33 -61 -33q-22 0 -40 12ZM0 1008q0 205 80 391.5T295 1721t321.5 215t391.5 80q124 0 243 -29.5t227.5 -87T1680 1760q22 -20 23.5 -50.5T1685 1657t-50 -24t-52 18q-119 106 -267.5 162.5T1008 1870q-100 0 -197 -22.5t-182 -65T469 1681T335 1547T233.5 1387t-65 -182T146 1008q0 -117 31 -229T263.5 572.5t135 -174t174 -135T779 177t229 -31q159 0 307.5 56.5T1583 365q22 20 52 18t50 -24t18.5 -52.5T1680 256Q1610 195 1531.5 147T1368 66.5T1192 17T1008 0Q803 0 616.5 80T295 295T80 616.5T0 1008Z"
435></glyph
436><glyph unicode="&#xf1a6;" d="M103 1177L621 800L582 680L421 186q-8 -25 -7 -40.5t9.5 -22t24 -2T484 141l15 11l506 367L1526 141q42 -31 60.5 -17.5T1588 186L1389 800l519 377q42 30 34.5 52t-58.5 22H1243l-39 119l-160 490q-10 32 -24.5 43.5t-28.5 0T966 1860L767 1251H127q-52 0 -59 -22t35 -52Z"
437></glyph
438><glyph unicode="&#xf1a7;" d="M189 1512H315q26 0 44.5 -18.5T378 1449V693q0 -26 -18.5 -44.5T315 630H189q-26 0 -44.5 18.5T126 693v756q0 26 18.5 44.5T189 1512ZM1764 883h-26q32 -3 58 -18.5t41.5 -42T1853 764q0 -52 -51 -82.5T1645 638q-44 -5 -130 -7t-169 -2q-13 -9 -16 -23.5t5 -32.5q11 -8 28.5 -26t46 -96.5T1438 267q0 -146 -24.5 -206.5T1338 0q-31 0 -55 18t-28 44q-15 88 -49 165t-75.5 131t-94 100T937 532.5t-97.5 50T756 614t-62 16h-1q-26 0 -44.5 18.5T630 693v756q0 36 51 72.5t122 61t143.5 40T1065 1638h230q82 0 151 -12t113.5 -30t75.5 -41t44.5 -44.5T1693 1471q0 -18 -5 -33t-12 -24t-14 -15t-12 -9t-4 -4h57q52 0 89 -37t37 -89q0 -50 -35 -86t-85 -39h55q52 0 89 -37t37 -89t-37 -89t-89 -37Z"
439></glyph
440><glyph unicode="&#xf1a8;" d="M189 504H315q26 0 44.5 18.5T378 567v756q0 26 -18.5 44.5T315 1386H189q-26 0 -44.5 -18.5T126 1323V567q0 -26 18.5 -44.5T189 504ZM1764 1133h-26q49 4 82 37.5t33 81.5q0 21 -8 38.5t-24.5 31T1779 1346t-58 19t-76 13q-44 5 -130 7t-169 2q-6 4 -10.5 10t-6 13.5t0 15.5t5.5 17q2 1 5.5 4t14.5 15t20.5 27t21.5 40.5t20.5 55.5t14.5 73t6 91q0 99 -12 159t-33 84t-55 24q-31 0 -55 -18t-28 -44q-15 -88 -49 -165t-75.5 -131t-94 -100T937 1483.5t-97.5 -50T756 1402t-62 -16h-1q-26 0 -44.5 -18.5T630 1323V567q0 -36 51 -72.5t122 -61t143.5 -40T1065 378h230q69 0 128.5 8t102 22t75.5 31.5t52.5 36.5t29.5 36.5t10 32.5q0 18 -5 33t-12 24t-14 15t-12 9t-4 4h57q52 0 89 37t37 89q0 25 -9.5 47.5t-25.5 39t-38 27T1709 881h55q34 0 63 17t46 46t17 63q0 52 -37 89t-89 37Z"
441></glyph
442><glyph unicode="&#xf1a9;" d="M1134 1764h63q26 0 44.5 18.5T1260 1827t-18.5 44.5T1197 1890H819q-26 0 -44.5 -18.5T756 1827t18.5 -44.5T819 1764h63V1627Q711 1599 570 1498l-56 56q-9 9 -20 15.5t-22.5 9.5t-24 3t-24 -3T401 1569.5T380 1554l-44 -45q-18 -18 -24.5 -42t0 -48.5T336 1376l56 -56Q252 1123 252 882q0 -154 60 -294T473 347T714 186t294 -60t294 60t241 161t161 241t60 294q0 138 -48.5 265.5T1583 1373t-200 165t-249 89v137ZM346 882q0 134 52.5 256.5T540 1350t211.5 141.5T1008 1544t256.5 -52.5T1476 1350t141.5 -211.5T1670 882T1617.5 625.5T1476 414T1264.5 272.5T1008 220T751.5 272.5T540 414T398.5 625.5T346 882ZM1301 712L1131 856q2 6 2.5 12.5T1134 882q0 52 -37 89t-89 37T919 971T882 882t37 -89t89 -37q10 0 19.5 2t19.5 5L1220 616q33 -27 72 -44l118 -51q17 -7 21.5 -1.5T1427 540l-70 108q-23 36 -56 64Z"
443></glyph
444><glyph unicode="&#xf1aa;" d="M1008 126q-179 0 -342.5 70T384 384T196 665.5T126 1008t70 342.5T384 1632t281.5 188t342.5 70t342.5 -70T1632 1632t188 -281.5T1890 1008T1820 665.5T1632 384T1350.5 196T1008 126ZM1260 1573q0 26 -18.5 44.5T1197 1636t-44.5 -18.5T1134 1573V794q-37 23 -90 26.5t-107.5 -12T832 765.5T746.5 697T701 611q-6 -26 -4.5 -51.5t8 -46.5T722 479q34 -41 85 -61T913 401t110.5 21.5T1129 476t86 80q30 38 37.5 79t7.5 121v817Z"
445></glyph
446><glyph unicode="&#xf1ab;" d="M1457 1638q-30 0 -36 -14.5t15 -35.5l152 -152L1119 1006L772 1122q-37 13 -65 -15L220 614V1764q0 20 -13.5 33.5t-33 13.5T140 1797.5T126 1764V306q0 -49 24 -90.5T215.5 150T305 126H1764q20 0 33.5 14t13.5 33.5t-13.5 33T1764 220H305q-35 0 -60 25.5T220 306V434L769 990L1114 875q35 -12 63 13l500 459l163 -163q21 -21 35.5 -15t14.5 36v362q0 30 -20.5 50.5T1819 1638H1457Z"
447></glyph
448><glyph unicode="&#xf1ac;" d="M0 636Q0 509 32 385q7 -27 30.5 -41T113 337q27 7 41 30.5t8 50.5q-14 54 -21 108.5T134 636q0 119 31.5 231.5T253 1076t136.5 176.5T566 1389t208.5 87.5t231 31.5T1237 1476.5T1445.5 1389t176 -136.5t137 -176.5T1846 867.5T1877 636q0 -111 -27 -218q-7 -27 7 -50.5T1898 337q4 -1 8.5 -1.5T1915 335q22 0 40.5 13.5T1980 385q32 123 32 251q0 92 -16.5 181t-47 170t-74 156.5T1775 1284t-121.5 121t-141 99.5T1356 1579t-170 47t-180 16q-137 0 -267 -36T498.5 1505T295 1347T137 1143.5T36 903T0 636ZM1406 951q-8 -3 -18 -8t-19.5 -11t-20 -12.5t-20 -13t-18 -13T1295 881L1118 728q-55 28 -112 28q-30 0 -58 -6.5t-53 -19t-47 -30t-39 -39T779.5 615t-19 -53.5T754 504q0 -68 33.5 -126.5t91.5 -92T1006 252q104 0 178 74t74 178q0 37 -14 79l177 153q21 18 46 47t39 52l105 167q15 23 7.5 31.5T1586 1031L1406 951Z"
449></glyph
450><glyph unicode="&#xf1ad;" d="M0 636Q0 509 32 385q7 -27 30.5 -41T113 337q27 7 41 30.5t8 50.5q-14 54 -21 108.5T134 636q0 119 31.5 231.5T253 1076t136.5 176.5T566 1389t208.5 87.5t231 31.5T1237 1476.5T1445.5 1389t176 -136.5t137 -176.5T1846 867.5T1877 636q0 -111 -27 -218q-7 -27 7 -50.5T1898 337q4 -1 8.5 -1.5T1915 335q22 0 40.5 13.5T1980 385q32 123 32 251q0 92 -16.5 181t-47 170t-74 156.5T1775 1284t-121.5 121t-141 99.5T1356 1579t-170 47t-180 16q-137 0 -267 -36T498.5 1505T295 1347T137 1143.5T36 903T0 636ZM1406 951q-8 -3 -18 -8t-19.5 -11t-20 -12.5t-20 -13t-18 -13T1295 881L1118 728q-55 28 -112 28q-30 0 -58 -6.5t-53 -19t-47 -30t-39 -39T779.5 615t-19 -53.5T754 504q0 -68 33.5 -126.5t91.5 -92T1006 252q104 0 178 74t74 178q0 37 -14 79l177 153q21 18 46 47t39 52l105 167q15 23 7.5 31.5T1586 1031L1406 951Z"
451></glyph
452><glyph unicode="&#xf1ae;" d="M0 636Q0 509 32 385q7 -27 30.5 -41T113 337q27 7 41 30.5t8 50.5q-14 54 -21 108.5T134 636q0 119 31.5 231.5T253 1076t136.5 176.5T566 1389t208.5 87.5t231 31.5T1237 1476.5T1445.5 1389t176 -136.5t137 -176.5T1846 867.5T1877 636q0 -111 -27 -218q-7 -27 7 -50.5T1898 337q4 -1 8.5 -1.5T1915 335q22 0 40.5 13.5T1980 385q32 123 32 251q0 92 -16.5 181t-47 170t-74 156.5T1775 1284t-121.5 121t-141 99.5T1356 1579t-170 47t-180 16q-137 0 -267 -36T498.5 1505T295 1347T137 1143.5T36 903T0 636ZM1406 951q-8 -3 -18 -8t-19.5 -11t-20 -12.5t-20 -13t-18 -13T1295 881L1118 728q-55 28 -112 28q-30 0 -58 -6.5t-53 -19t-47 -30t-39 -39T779.5 615t-19 -53.5T754 504q0 -68 33.5 -126.5t91.5 -92T1006 252q104 0 178 74t74 178q0 37 -14 79l177 153q21 18 46 47t39 52l105 167q15 23 7.5 31.5T1586 1031L1406 951Z"
453></glyph
454><glyph unicode="&#xf1af;" d="M1448 681Q1358 575 1246 515.5T1008 456q-127 0 -239.5 60.5T565 684Q485 658 411 625T304 572L270 552Q211 514 168.5 437.5T126 292.5T176.5 175T297 126H1719q70 0 120.5 49T1890 292.5t-42.5 144T1745 550q-13 8 -37.5 21.5t-102 48.5T1448 681ZM1008 630q-68 0 -134 29.5t-120.5 80T652 859.5t-79.5 149T522 1176t-18 174q0 127 39.5 230.5t108 170.5t160 103t196.5 36t196.5 -36t160 -103t108 -170.5T1512 1350q0 -129 -40 -259T1365 859.5T1203.5 694T1008 630Z"
455></glyph
456><glyph unicode="&#xf1b0;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4ZM1532 590q-26 16 -32.5 45.5T1509 690q92 145 92 318q0 175 -94 321q-6 10 -9 21.5t-2.5 22.5t4.5 21.5t11.5 20T1529 1430q12 8 26.5 10.5t28 -0.5t25.5 -11t20 -21q29 -44 51 -92.5t37 -98.5t22.5 -103t7.5 -106q0 -215 -115 -396q-10 -16 -26.5 -25T1571 578q-22 0 -39 12ZM1747 430q-25 17 -31 46.5t11 54.5q143 216 143 477q0 264 -147 482q-17 25 -11 54.5t31 46.5t54.5 11.5T1844 1572q172 -255 172 -564q0 -305 -168 -557q-22 -33 -61 -33q-22 0 -40 12Z"
457></glyph
458><glyph unicode="&#xf1b1;" d="M1681 1512q14 14 22.5 31t11 35.5t0 36.5t-11 35t-22.5 31q-17 17 -39.5 26t-45 9t-45 -9T1512 1681L1008 1177L504 1681q-17 17 -39.5 26t-45 9t-45 -9T335 1681q-35 -35 -35 -84.5T335 1512L839 1008L335 504Q312 481 303.5 450t0 -61.5T335 335q17 -17 39 -26t45 -9q50 0 85 35l504 504L1512 335q35 -35 85 -35q49 1 84 35q17 17 26 39.5t9 45t-9 45T1681 504l-504 504l504 504Z"
459></glyph
460><glyph unicode="&#xf1b2;" d="M126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM220 1008q0 160 62.5 306t168 251.5t251.5 168t306 62.5t306 -62.5t251.5 -168t168 -251.5T1796 1008T1733.5 702t-168 -251.5T1314 282.5T1008 220T702 282.5t-251.5 168T282.5 702T220 1008ZM1134 1008v435q0 28 -20.5 48.5T1065 1512H951q-28 0 -48.5 -20.5T882 1443V1008H579q-31 0 -37.5 -15.5T557 955L955 557q22 -22 53 -22t53 22l398 398q14 14 16.5 26.5t-8 19.5t-30.5 7H1134Z"
461></glyph
462><glyph unicode="&#xf1b3;" d="M1000 1000v16h16v-16h-16ZM1000 1000v16h16v-16h-16ZM1014 1010q1 0 1 0v2q0 0 -1 0h-12q-1 0 -1 0v-2q0 0 1 0v-1h1q0 0 0 -1q0 0 0 -1h-1v-1q-1 0 -1 0v-2q0 0 1 0h12q1 0 1 0v2q0 0 -1 0v1h-1q0 0 0 1q0 0 0 1h1v1ZM1004 1005v6h8v-6h-8ZM1005 1010v-4h6v4h-6ZM1792 1240l35 14q17 1 31.5 11t23 25.5t8.5 32.5v126q0 26 -18.5 44.5T1827 1512H189q-26 0 -44.5 -18.5T126 1449V1323q0 -26 18.5 -46.5T189 1254q0 -1 0.5 -1t3 -0.5t6 -2t10.5 -4t15 -6.5q45 -19 80 -54t54 -80q20 -47 20 -98q0 -10 -1 -20.5T374.5 967t-4 -19.5t-5.5 -19T358 910Q339 865 304 830T224 776L189 762q-13 -1 -24.5 -7t-20 -15.5T131 718t-5 -25V567q0 -26 18.5 -44.5T189 504H1827q26 0 44.5 18.5T1890 567V693q0 17 -8.5 32.5t-23 25.5T1827 762q-5 1 -35 14q-23 9 -43 23t-37 31q-4 3 -7 6.5t-6 7.5t-6.5 7.5t-6 7.5t-5.5 8t-5.5 8t-5 8.5t-4.5 9t-4 8.5t-4 9q-20 47 -20 98q0 26 5 50.5t15 47.5q4 9 8.5 18t9.5 17t10.5 16t12 15t13.5 14q17 17 37 31t43 23ZM504 630v756H1512V630H504ZM630 1260V756h756v504H630Z"
463></glyph
464><glyph unicode="&#xf1b4;" d="M1000 1000v16h16v-16h-16ZM1000 1000v16h16v-16h-16ZM1014 1010q1 0 1 0v2q0 0 -1 0h-12q-1 0 -1 0v-2q0 0 1 0v-1h1q0 0 0 -1q0 0 0 -1h-1v-1q-1 0 -1 0v-2q0 0 1 0h12q1 0 1 0v2q0 0 -1 0v1h-1q0 0 0 1q0 0 0 1h1v1ZM1004 1005v6h8v-6h-8ZM1005 1010v-4h6v4h-6ZM1792 1240l35 14q17 1 31.5 11t23 25.5t8.5 32.5v126q0 26 -18.5 44.5T1827 1512H189q-26 0 -44.5 -18.5T126 1449V1323q0 -26 18.5 -46.5T189 1254q0 -1 0.5 -1t3 -0.5t6 -2t10.5 -4t15 -6.5q45 -19 80 -54t54 -80q20 -47 20 -98q0 -10 -1 -20.5T374.5 967t-4 -19.5t-5.5 -19T358 910Q339 865 304 830T224 776L189 762q-13 -1 -24.5 -7t-20 -15.5T131 718t-5 -25V567q0 -26 18.5 -44.5T189 504H1827q26 0 44.5 18.5T1890 567V693q0 17 -8.5 32.5t-23 25.5T1827 762q-5 1 -35 14q-23 9 -43 23t-37 31q-4 3 -7 6.5t-6 7.5t-6.5 7.5t-6 7.5t-5.5 8t-5.5 8t-5 8.5t-4.5 9t-4 8.5t-4 9q-20 47 -20 98q0 26 5 50.5t15 47.5q4 9 8.5 18t9.5 17t10.5 16t12 15t13.5 14q17 17 37 31t43 23ZM504 630v756H1512V630H504ZM630 1260V756h756v504H630Z"
465></glyph
466><glyph unicode="&#xf1b5;" d="M1000 1000v16h16v-16h-16ZM1000 1000v16h16v-16h-16ZM1014 1010q1 0 1 0v2q0 0 -1 0h-12q-1 0 -1 0v-2q0 0 1 0v-1h1q0 0 0 -1q0 0 0 -1h-1v-1q-1 0 -1 0v-2q0 0 1 0h12q1 0 1 0v2q0 0 -1 0v1h-1q0 0 0 1q0 0 0 1h1v1ZM1004 1005v6h8v-6h-8ZM1005 1010v-4h6v4h-6ZM1792 1240l35 14q17 1 31.5 11t23 25.5t8.5 32.5v126q0 26 -18.5 44.5T1827 1512H189q-26 0 -44.5 -18.5T126 1449V1323q0 -26 18.5 -46.5T189 1254q0 -1 0.5 -1t3 -0.5t6 -2t10.5 -4t15 -6.5q45 -19 80 -54t54 -80q20 -47 20 -98q0 -10 -1 -20.5T374.5 967t-4 -19.5t-5.5 -19T358 910Q339 865 304 830T224 776L189 762q-13 -1 -24.5 -7t-20 -15.5T131 718t-5 -25V567q0 -26 18.5 -44.5T189 504H1827q26 0 44.5 18.5T1890 567V693q0 17 -8.5 32.5t-23 25.5T1827 762q-5 1 -35 14q-23 9 -43 23t-37 31q-4 3 -7 6.5t-6 7.5t-6.5 7.5t-6 7.5t-5.5 8t-5.5 8t-5 8.5t-4.5 9t-4 8.5t-4 9q-20 47 -20 98q0 26 5 50.5t15 47.5q4 9 8.5 18t9.5 17t10.5 16t12 15t13.5 14q17 17 37 31t43 23ZM504 630v756H1512V630H504ZM630 1260V756h756v504H630Z"
467></glyph
468><glyph unicode="&#xf1b6;" d="M1260 252V756q0 52 -37 89t-89 37H882q-52 0 -89 -37T756 756V252H378v755L252 917V252q0 -52 37 -89t89 -37H882h252h504q52 0 89 37t37 89V917l-126 90V252H1260ZM1156 1755q-41 29 -94.5 39.5t-107 0T860 1755L80 1198Q54 1179 48.5 1147T62 1088.5t51 -32t59 13.5l779 557q22 15 57 15t57 -15l779 -557q21 -15 46 -15q41 0 64 33q19 27 13.5 59t-31.5 51l-780 557Z"
469></glyph
470><glyph unicode="&#xf1b7;" d="M1260 252V756q0 52 -37 89t-89 37H882q-52 0 -89 -37T756 756V252H378v755L252 917V252q0 -52 37 -89t89 -37H882h252h504q52 0 89 37t37 89V917l-126 90V252H1260ZM1156 1755q-41 29 -94.5 39.5t-107 0T860 1755L80 1198Q54 1179 48.5 1147T62 1088.5t51 -32t59 13.5l779 557q22 15 57 15t57 -15l779 -557q21 -15 46 -15q41 0 64 33q19 27 13.5 59t-31.5 51l-780 557Z"
471></glyph
472><glyph unicode="&#xf1b8;" d="M1260 252V756q0 52 -37 89t-89 37H882q-52 0 -89 -37T756 756V252H378v755L252 917V252q0 -52 37 -89t89 -37H882h252h504q52 0 89 37t37 89V917l-126 90V252H1260ZM1156 1755q-41 29 -94.5 39.5t-107 0T860 1755L80 1198Q54 1179 48.5 1147T62 1088.5t51 -32t59 13.5l779 557q22 15 57 15t57 -15l779 -557q21 -15 46 -15q41 0 64 33q19 27 13.5 59t-31.5 51l-780 557Z"
473></glyph
474><glyph unicode="&#xf1b9;" d="M1007 473q-109 0 -207.5 42.5T629 629.5T514.5 800T472 1008H680q32 0 38.5 15.5T703 1061L431 1333q-14 14 -33.5 19t-39 0T325 1333L53 1061Q31 1039 37.5 1023.5T76 1008H282Q283 763 432 569Q569 390 783 320q109 -35 224 -36q50 0 99.5 7t97.5 20.5t94 33.5q36 16 50 52.5t-1.5 72.5t-52 50T1222 518q-34 -14 -69.5 -24t-72 -15.5T1007 473ZM1731 1008v1q0 98 -26 192t-72.5 173.5T1519 1521t-146.5 113.5T1199 1707t-192 26q-50 0 -99 -6.5T811.5 1707T718 1674q-36 -16 -50 -52.5t1 -72.5q16 -36 52.5 -50t72.5 1q50 22 103.5 33t109.5 11q109 0 208 -42t170.5 -114t114 -171T1542 1010v-2H1336q-32 0 -38.5 -15.5T1313 955L1585 683q22 -22 53 -22t53 22l272 272q22 22 15.5 37.5T1940 1008H1731Z"
475></glyph
476><glyph unicode="&#xf1ba;" d="M1007 474q-109 0 -208 42T628.5 629.5T514.5 800T472 1008H680q32 0 38.5 15.5T703 1061L431 1333q-14 14 -33.5 19t-39 0T325 1333L53 1061Q31 1039 37.5 1023.5T76 1008H283q0 -147 57.5 -281T495 496T726 342t281 -57q152 0 291 60q36 16 50 52.5t-1 72.5q-11 23 -31.5 38T1271 525.5T1222 518q-25 -11 -51.5 -19.5t-53.5 -14t-54.5 -8T1007 474ZM1731 1008v1q0 74 -14.5 146t-42 136t-67 122.5T1519 1521t-107.5 88.5t-122.5 67T1153 1719t-146 15q-75 0 -147.5 -15.5T718 1674q-36 -16 -50 -52.5t1.5 -72.5t52 -50t72.5 1q17 8 34 14t34.5 11t35.5 8.5t36 6t36 4t37 1.5q55 0 108 -11t100.5 -31.5T1306 1453t79 -65t65.5 -79.5t50 -91t31 -100.5T1542 1010v-2H1336q-21 0 -31 -7t-8 -19.5T1313 955L1585 683q22 -22 53 -22t53 22l272 272q22 22 15.5 37.5T1940 1008H1731Z"
477></glyph
478><glyph unicode="&#xf1bb;" d="M1007 474q-109 0 -208 42T628.5 629.5T514.5 800T472 1008H680q32 0 38.5 15.5T703 1061L431 1333q-10 10 -24.5 16t-28.5 6t-28.5 -6T325 1333L53 1061Q31 1039 37.5 1023.5T76 1008H282q1 -147 58.5 -281T495 496T726 342t281 -57q51 0 100 6.5t97 20t94 33.5q24 11 39 31.5t17 44.5t-7 49q-16 36 -52.5 50T1222 518Q1120 474 1007 474ZM1731 1008v1q0 147 -57 281t-154.5 231.5t-231.5 155T1007 1734q-75 0 -147.5 -15.5T718 1674q-36 -16 -50 -52.5t1.5 -72.5t52 -50t72.5 1q101 45 213 45q109 0 208 -42.5T1385.5 1388t114 -171T1542 1010v-2H1336q-21 0 -31 -7t-8 -19.5T1313 955L1585 683q22 -22 53 -22t53 22l272 272q22 22 15.5 37.5T1940 1008H1731Z"
479></glyph
480><glyph unicode="&#xf1bc;" d="M1283 1726q-61 53 -104.5 33T1135 1658v-98V1364q0 0 -93 -14Q731 1289 506 1129Q128 857 127 378q3 7 9 18.5t28.5 47t49.5 70t75 81t102.5 87T525 763t166.5 69.5t202.5 47T1135 898V678V579q0 -80 43.5 -100T1282 513l549 481q60 53 60 129t-61 129l-547 474Z"
481></glyph
482><glyph unicode="&#xf1bd;" d="M1890 315q0 -26 -18.5 -44.5T1827 252H189q-26 0 -44.5 18.5T126 315t18.5 44.5T189 378H1827q26 0 44.5 -18.5T1890 315ZM1890 819q0 -26 -18.5 -44.5T1827 756H189q-26 0 -44.5 18.5T126 819t18.5 44.5T189 882H1827q26 0 44.5 -18.5T1890 819ZM1140 1764H271q-29 0 -56 -11.5t-46.5 -31t-31 -46.5T126 1619V1406q0 -61 42.5 -103.5T271 1260H1349q-100 80 -157.5 195T1134 1701q0 6 6 63ZM1764 1764v189q0 26 -18.5 44.5T1701 2016t-44.5 -18.5T1638 1953V1764H1449q-26 0 -44.5 -18.5T1386 1701t18.5 -44.5T1449 1638h189V1449q0 -26 18.5 -44.5T1701 1386t44.5 18.5T1764 1449v189h189q26 0 44.5 18.5T2016 1701t-18.5 44.5T1953 1764H1764Z"
483></glyph
484><glyph unicode="&#xf1be;" d="M1890 315q0 -26 -18.5 -44.5T1827 252H189q-26 0 -44.5 18.5T126 315t18.5 44.5T189 378H1827q26 0 44.5 -18.5T1890 315ZM1890 819q0 -26 -18.5 -44.5T1827 756H189q-26 0 -44.5 18.5T126 819t18.5 44.5T189 882H1827q26 0 44.5 -18.5T1890 819ZM1140 1764H271q-29 0 -56 -11.5t-46.5 -31t-31 -46.5T126 1619V1406q0 -61 42.5 -103.5T271 1260H1349q-100 80 -157.5 195T1134 1701q0 6 6 63ZM1764 1764v189q0 26 -18.5 44.5T1701 2016t-44.5 -18.5T1638 1953V1764H1449q-26 0 -44.5 -18.5T1386 1701t18.5 -44.5T1449 1638h189V1449q0 -26 18.5 -44.5T1701 1386t44.5 18.5T1764 1449v189h189q26 0 44.5 18.5T2016 1701t-18.5 44.5T1953 1764H1764Z"
485></glyph
486><glyph unicode="&#xf1bf;" d="M1890 315q0 -26 -18.5 -44.5T1827 252H189q-26 0 -44.5 18.5T126 315t18.5 44.5T189 378H1827q26 0 44.5 -18.5T1890 315ZM1890 819q0 -26 -18.5 -44.5T1827 756H189q-26 0 -44.5 18.5T126 819t18.5 44.5T189 882H1827q26 0 44.5 -18.5T1890 819ZM1140 1764H271q-29 0 -56 -11.5t-46.5 -31t-31 -46.5T126 1619V1406q0 -61 42.5 -103.5T271 1260H1349q-100 80 -157.5 195T1134 1701q0 6 6 63ZM1764 1764v189q0 26 -18.5 44.5T1701 2016t-44.5 -18.5T1638 1953V1764H1449q-26 0 -44.5 -18.5T1386 1701t18.5 -44.5T1449 1638h189V1449q0 -26 18.5 -44.5T1701 1386t44.5 18.5T1764 1449v189h189q26 0 44.5 18.5T2016 1701t-18.5 44.5T1953 1764H1764Z"
487></glyph
488><glyph unicode="&#xf1c0;" d="M126 126H1890V1890H126V126ZM228 1008q0 159 61.5 303.5t166 249t249 166T1008 1788t303.5 -61.5t249 -166t166 -249T1788 1008T1726.5 704.5t-166 -249t-249 -166T1008 228T704.5 289.5t-249 166t-166 249T228 1008ZM1008 840q-70 0 -119 49t-49 119t49 119t119 49t119 -49t49 -119T1127 889T1008 840Z"
489></glyph
490><glyph unicode="&#xf1c1;" d="M126 126H1890V1890H126V126ZM228 1008q0 159 61.5 303.5t166 249t249 166T1008 1788t303.5 -61.5t249 -166t166 -249T1788 1008T1726.5 704.5t-166 -249t-249 -166T1008 228T704.5 289.5t-249 166t-166 249T228 1008ZM1008 840q-70 0 -119 49t-49 119t49 119t119 49t119 -49t49 -119T1127 889T1008 840Z"
491></glyph
492><glyph unicode="&#xf1c2;" d="M126 126H1890V1890H126V126ZM228 1008q0 159 61.5 303.5t166 249t249 166T1008 1788t303.5 -61.5t249 -166t166 -249T1788 1008T1726.5 704.5t-166 -249t-249 -166T1008 228T704.5 289.5t-249 166t-166 249T228 1008ZM1008 840q-70 0 -119 49t-49 119t49 119t119 49t119 -49t49 -119T1127 889T1008 840Z"
493></glyph
494><glyph unicode="&#xf1c3;" d="M1512 1896q0 49 -34.5 77.5T1394 1992L370 1788q-27 -6 -52 -24H1512v132ZM1742 0H274Q213 0 169.5 43.5T126 148V1490q0 61 43.5 104.5T274 1638H1742q61 0 104.5 -43.5T1890 1490V148q0 -61 -43.5 -104.5T1742 0ZM1426 1377q-11 9 -25 12.5t-28 0.5L741 1259q-22 -5 -35 -22t-13 -40V561q-33 0 -60 -5Q554 539 498 484T442 367t55 -94T631 257q78 17 132.5 70T818 442q0 6 0.5 19t0.5 18V938l504 114V665q-14 1 -30.5 0T1260 661q-78 -15 -133.5 -66.5T1071 485q0 -38 25.5 -65t69 -37t94.5 0q78 15 133.5 66.5T1449 559q0 1 0 3q0 1 0 1.5t0 1.5t0 2v761q0 30 -23 49Z"
495></glyph
496><glyph unicode="&#xf1c4;" d="M253 1851L91 1679l-76 77l253 260H378V1008H253v843ZM515 613q88 69 146 115.5T784 830t105 94t79.5 83.5t60.5 81t34 74.5t13 75q0 47 -18 83.5t-49 58T941.5 1412T864 1423q-59 0 -111 -16.5T661 1362t-70 -66l-77 80q19 25 42.5 47t50.5 39.5t57.5 31t63 22.5t67 13.5T864 1534q65 0 124.5 -18.5t108 -53.5t77.5 -93t29 -131q0 -50 -16 -100.5T1137.5 1036T1064 937.5T964 835T848 732.5T713 623h494V511H515V613ZM1374 245q22 -30 52 -54t65.5 -42T1569 121.5t86 -9.5q109 0 172.5 51T1891 301q0 61 -32.5 101.5T1771 461t-131 18q-89 0 -104 -1V592q5 0 16 -0.5t27.5 -0.5t28 0t32.5 0q66 0 117.5 16.5t84 55T1874 757q0 81 -64.5 126.5T1649 929q-81 0 -145 -30T1383 807l-70 79q58 71 146 113t200 42q73 0 135 -18t108 -51.5T1973.5 887T1999 774q0 -42 -13.5 -79t-35 -63T1900 586.5t-58 -31T1783 540q37 -4 75.5 -21t75 -46T1993 396t23 -106q0 -84 -42.5 -149.5T1849 37.5T1658 0Q1536 0 1442.5 46.5T1300 166l74 79Z"
497></glyph
498><glyph unicode="&#xf1c5;" d="M1712 1564q31 31 31 74t-31 74t-74 31t-74 -31L1008 1156L452 1712q-31 31 -74 31t-74 -31t-31 -74t31 -74L860 1008L304 452Q292 440 284 425T274 394t0 -32t10 -31t20 -27q10 -10 22 -17t25 -10.5T378 273q44 1 74 31l556 556L1564 304q7 -8 16 -14t18.5 -9.5T1618 275t20 -2q7 0 13.5 1t13 2.5t13 4t12.5 6t11.5 8T1712 304q31 31 31 74t-31 74l-556 556l556 556Z"
499></glyph
500><glyph unicode="&#xf1c6;" d="M1092 1092v587q0 35 -24.5 60t-59.5 25t-59.5 -25T924 1679V1092H337q-35 0 -60 -24.5T252 1008q0 -23 11.5 -42t31 -30.5T337 924H924V337q0 -18 6.5 -33.5t18 -27t27 -18T1008 252q35 0 59.5 25t24.5 60V924h587q35 0 60 24.5t25 59.5t-25 59.5t-60 24.5H1092Z"
501></glyph
502><glyph unicode="&#xf1c7;" d="M1008 756q-104 0 -178 74t-74 178t74 178t178 74t178 -74t74 -178T1186 830T1008 756ZM1391 598q-9 9 -13.5 21t-4 24t5.5 23.5t14 20.5q15 14 28.5 29t25 31t22 33t19 35t15.5 36.5t12.5 37.5t9 38.5t5.5 40t2 40.5q0 26 -3 52t-9 50.5t-14.5 48.5t-20 46.5t-25.5 44t-31 41.5t-36 38q-12 12 -17 28t-1 32t16 29q17 19 43.5 19.5T1480 1420q42 -39 75 -87t56 -100.5T1646 1123t12 -115q0 -29 -3 -58t-9 -57t-15 -55.5t-20 -54T1586 732t-30.5 -48.5t-35.5 -46T1480 595q-18 -17 -44 -17q-12 0 -24 5t-21 15ZM1536 293q-15 21 -11 47t25 41q99 73 170.5 172.5T1830 769t38 239q0 185 -84.5 351T1550 1635q-14 10 -20.5 25.5t-5 32T1536 1723q16 21 41.5 25t46.5 -12q69 -50 127.5 -113t103 -134T1930 1339.5T1977.5 1177T1994 1008q0 -215 -98 -408T1624 280q-8 -7 -17.5 -10T1587 267q-15 0 -28.5 7T1536 293ZM536 595Q452 676 405 783.5T358 1008q0 77 21 152t61 141t96 119q19 18 45.5 17.5t44 -19.5t17 -45T623 1329Q556 1266 520 1183T484 1008T520 833T623 687q19 -18 19.5 -44T625 598Q607 578 580 578q-26 1 -44 17ZM392 280Q306 343 236.5 425T120 600T47.5 797T22 1008q0 215 98 408t272 320q13 10 30 12t32 -4.5T479.5 1723t12 -30.5t-5 -32T466 1635Q392 1580 332.5 1509.5T232.5 1359T170 1189.5T148 1008q0 -185 84.5 -351T466 381q21 -15 25 -41T480 293Q461 267 429 267q-21 0 -37 13Z"
503></glyph
504><glyph unicode="&#xf1c8;" d="M504 1661V354q0 -61 37 -82t89 10L1722 933q52 31 52 75t-53 75L631 1733q-53 31 -90 10t-37 -82Z"
505></glyph
506><glyph unicode="&#xf1c9;" d="M876 342L372 805q-32 29 -34 72.5T365.5 953t73 34T514 959L916 590l567 1096q20 39 61.5 52t80.5 -7q25 -13 40 -37t16 -50.5T1670 1590L1040 371q-24 -46 -75 -55q-9 -1 -18 -1q-41 0 -71 27Z"
507></glyph
508><glyph unicode="&#xf1ca;" d="M756 1176H420q-35 0 -59.5 24.5T336 1260v336q0 35 24.5 59.5T420 1680H756q35 0 59.5 -24.5T840 1596V1260q0 -35 -24.5 -59.5T756 1176ZM756 336H420q-35 0 -59.5 24.5T336 420V756q0 35 24.5 59.5T420 840H756q35 0 59.5 -24.5T840 756V420q0 -35 -24.5 -59.5T756 336ZM1596 1176H1260q-35 0 -59.5 24.5T1176 1260v336q0 35 24.5 59.5T1260 1680h336q35 0 59.5 -24.5T1680 1596V1260q0 -35 -24.5 -59.5T1596 1176ZM1596 336H1260q-35 0 -59.5 24.5T1176 420V756q0 35 24.5 59.5T1260 840h336q35 0 59.5 -24.5T1680 756V420q0 -35 -24.5 -59.5T1596 336Z"
509></glyph
510><glyph unicode="&#xf1cb;" d="M1680 1428H840q-35 0 -59.5 24.5T756 1512t24.5 59.5T840 1596h840q35 0 59.5 -24.5T1764 1512t-24.5 -59.5T1680 1428ZM1680 924H840q-35 0 -59.5 24.5T756 1008t24.5 59.5T840 1092h840q35 0 59.5 -24.5T1764 1008t-24.5 -59.5T1680 924ZM1680 420H840q-35 0 -59.5 24.5T756 504t24.5 59.5T840 588h840q35 0 59.5 -24.5T1764 504t-24.5 -59.5T1680 420ZM378 1386q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89t-37 -89t-89 -37ZM378 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T467 919T378 882ZM378 378q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T467 415T378 378Z"
511></glyph
512><glyph unicode="&#xf1cc;" d="M420 840q-69 0 -118.5 49.5T252 1008t49.5 118.5T420 1176t118.5 -49.5T588 1008T538.5 889.5T420 840ZM1008 840q-69 0 -118.5 49.5T840 1008t49.5 118.5T1008 1176t118.5 -49.5T1176 1008T1126.5 889.5T1008 840ZM1596 840q-69 0 -118.5 49.5T1428 1008t49.5 118.5T1596 1176t118.5 -49.5T1764 1008T1714.5 889.5T1596 840Z"
513></glyph
514><glyph unicode="&#xf1cd;" d="M624 1061h-1q-2 -2 -3 -2h-2v-1v-1v0v-1v-1q1 0 2 0l3 -2h1v0v4v0v4ZM626 1053q0 1 0 1q1 1 1 1.5t0 1.5q0 2 -1 3q0 0 0 1l1 -1q1 -1 1 -3t-1 -3l-1 -1ZM628 1052q1 1 1.5 2.5t0.5 2.5q0 3 -2 5q0 0 0 0q1 1 1 0q1 -1 1.5 -2.5T631 1057q0 -3 -2 -5v-1l-1 1ZM615 1057q0 8 8 8q1 0 2 0t1 -1h1q-1 -1 -1 -1q-1 1 -1.5 1t-1.5 0q-7 0 -7 -7t7 -7l3 1q0 0 0.5 -0.5T626 1050q0 -1 -1 -1t-2 0q-8 0 -8 8ZM1105 1507q-9 4 -19 5t-19 -2t-17 -9q-53 -43 -123.5 -92t-167 -101.5T605 1247q-1 0 -2 0q-46 -8 -177 -27h-4q-19 -3 -31.5 -17T378 1170V992q0 -2 0 -3q0 -2 0 -2V846q0 -19 12.5 -33T422 796q0 0 7.5 -1t20 -2.5t28 -4t33 -5t34 -5t32 -5T603 769q0 0 0.5 0t1.5 0q58 -8 154.5 -60.5T926.5 607T1050 515q14 -11 33 -11q12 0 22 5q13 6 21 18.5t8 26.5V987q0 1 0 2q0 1 0 1.5t0 1.5v470q0 31 -29 45ZM1397 559q-20 17 -22.5 43t13.5 46q42 50 71 109t43.5 122.5T1517 1008q0 99 -33.5 192T1388 1369q-11 13 -14 29.5t3 32t19.5 26.5t30 14t32 -3t26.5 -19q77 -93 117.5 -207T1643 1008q0 -80 -18 -157.5t-53.5 -149T1486 568q-19 -23 -49 -23q-3 0 -7 0.5t-7 1t-6.5 2t-7 3T1403 555t-6 4ZM1660 321q-19 18 -20 44t17 45q112 123 172.5 277t60.5 321q0 162 -57.5 313.5T1667 1594q-7 8 -11 17.5t-5 19t1 19t7 18t13 15.5t17 11t19 5t19.5 -1t18 -7t15.5 -13q82 -92 139 -200.5T1986.5 1250T2016 1008q0 -190 -69 -366.5T1749 325q-19 -20 -46 -20q-8 0 -15.5 1.5T1673 312t-13 9ZM0 1008q0 205 80 391.5T295 1721t321.5 215t391.5 80q226 0 429 -95q23 -12 32 -36.5t-2 -48t-35.5 -32T1383 1807q-177 83 -375 83q-179 0 -342.5 -70T384 1632T196 1350.5T126 1008T196 665.5T384 384T665.5 196T1008 126q193 0 366 79q24 11 48.5 2T1458 174.5t1.5 -48T1427 91Q1228 0 1008 0Q803 0 616.5 80T295 295T80 616.5T0 1008Z"
515></glyph
516><glyph unicode="&#xf1ce;" d="M1106 1515q-13 6 -28 4.5T1051 1508q-28 -22 -66 -50t-91.5 -63T790 1330.5t-102.5 -52T598 1251q0 0 -1 0q0 0 -1 0q-10 -2 -26 -4.5t-32.5 -5t-34.5 -5t-34 -5T440.5 1227t-20 -3t-7.5 -1q-20 -3 -32.5 -17.5T368 1172V992q0 -1 0 -3q0 -2 0 -2V844q0 -19 12.5 -33.5T413 793q0 0 4 -1Q550 773 596 765h2q46 -6 113 -37.5T844.5 653t118 -79.5T1051 507q14 -11 33 -11q6 0 11.5 1t10.5 4q14 6 22 18.5t8 27.5V987q0 0 0 1t0 1t0 1t0 1v478q0 32 -30 46ZM1413 565q-15 12 -17 32t11 35q65 79 99.5 176t34.5 200q0 103 -34.5 200T1406 1385q-12 15 -10.5 34.5t17 32.5t35.5 11t32 -17q76 -92 116.5 -205T1637 1008q0 -79 -18 -156.5T1566 703T1481 571q-15 -17 -37 -17q-6 0 -11 1t-10 3.5t-10 6.5ZM1681 322q-14 14 -15 33.5t13 34.5q116 126 178.5 286t62.5 332q0 168 -59.5 324.5T1689 1614q-13 15 -12 35t16 33q10 9 22.5 11.5T1740 1692t21 -14q123 -138 189 -311t66 -359q0 -190 -69 -366.5T1749 325q-14 -16 -35 -16q-19 0 -33 13ZM0 1008q0 205 80 391.5T295 1721t321.5 215t391.5 80q226 0 429 -96q18 -8 24.5 -26.5T1460 1857q-6 -12 -16.5 -19.5t-23 -8.5t-24.5 5q-184 86 -388 86q-185 0 -354 -72.5T363 1653T168.5 1362T96 1008T168.5 654T363 363T654 168.5T1008 96q199 0 379 82q18 8 36.5 1.5t27 -25t1.5 -37T1427 91Q1228 0 1008 0Q803 0 616.5 80T295 295T80 616.5T0 1008Z"
517></glyph
518><glyph unicode="&#xf1cf;" d="M1105 1507q-9 4 -19 5t-19 -2t-17 -9q-53 -43 -123.5 -92t-167 -101.5T605 1247q-1 0 -2 0q-46 -8 -177 -27h-4q-19 -3 -31.5 -17T378 1170V992q0 -2 0 -3q0 -2 0 -2V846q0 -19 12.5 -33T422 796q0 0 7.5 -1t20 -2.5t28 -4t33 -5t34 -5t32 -5T603 769q0 0 0.5 0t1.5 0q58 -8 154.5 -60.5T926.5 607T1050 515q14 -11 33 -11q12 0 22 5q13 6 21 18.5t8 26.5V987q0 1 0 2q0 1 0 1.5t0 1.5v470q0 31 -29 45ZM1407 572q-15 12 -17 31.5t11 34.5q64 78 98 173.5t34 196.5q0 101 -34.5 197T1400 1379q-13 15 -11 34.5t17 31.5q5 4 11 6.5t12 3.5t12 0.5t11.5 -2.5t11 -5.5t9.5 -8.5q37 -45 66 -96.5t48.5 -106t30 -112T1628 1008q0 -117 -40 -228T1474 578q-15 -17 -37 -17q-8 0 -15.5 2.5T1407 572ZM1671 333q-15 13 -15.5 32.5T1668 400q76 82 129.5 180.5t81 206.5t27.5 221q0 66 -9.5 131T1868 1266t-46 121t-63.5 114T1679 1605q-13 14 -12 33.5t15.5 33t34 12T1749 1668q122 -137 186.5 -307T2000 1008q0 -125 -30 -244.5t-89 -228T1738 335q-14 -15 -35 -15q-19 0 -32 13ZM16 1008q0 135 35.5 263.5t99.5 237T307 1709t200.5 156t237 99.5T1008 2000q111 0 217 -23.5T1430 1906q18 -8 24.5 -26.5t-2 -36T1426 1819t-36 2q-90 42 -186 63.5T1008 1906q-122 0 -238.5 -32.5T555 1783T374 1642T233 1461T142.5 1246.5T110 1008T142.5 769.5T233 555T374 374T555 233T769.5 142.5T1008 110q196 0 373 81q18 8 36 1.5T1443.5 168t1.5 -36.5T1420 105Q1323 61 1219.5 38.5T1008 16Q892 16 780.5 42t-209 75T388 234T234 388T117 571.5t-75 209T16 1008Z"
519></glyph
520><glyph unicode="&#xf1d0;" d="M1105 1507q-9 4 -19 5t-19 -2t-17 -9q-53 -43 -123.5 -92t-167 -101.5T605 1247q-1 0 -2 0q-46 -8 -177 -27h-4q-19 -3 -31.5 -17T378 1170V992q0 -2 0 -3q0 -2 0 -2V846q0 -19 12.5 -33T422 796q0 0 7.5 -1t20 -2.5t28 -4t33 -5t34 -5t32 -5T603 769q0 0 0.5 0t1.5 0q58 -8 154.5 -60.5T926.5 607T1050 515q14 -11 33 -11q12 0 22 5q13 6 21 18.5t8 26.5V987q0 1 0 2q0 1 0 1.5t0 1.5v470q0 31 -29 45ZM1397 559q-20 17 -22.5 43t13.5 46q42 50 71 109t43.5 122.5T1517 1008q0 99 -33.5 192T1388 1369q-11 13 -14 29.5t3 32t19.5 26.5t30 14t32 -3t26.5 -19q77 -93 117.5 -207T1643 1008q0 -80 -18 -157.5t-53.5 -149T1486 568q-19 -23 -49 -23q-3 0 -7 0.5t-7 1t-6.5 2t-7 3T1403 555t-6 4ZM1660 321q-19 18 -20 44t17 45q112 123 172.5 277t60.5 321q0 162 -57.5 313.5T1667 1594q-7 8 -11 17.5t-5 19t1 19t7 18t13 15.5q20 18 45.5 16.5T1761 1678q82 -92 139 -200.5T1986.5 1250T2016 1008q0 -190 -69 -366.5T1749 325q-19 -20 -46 -20q-8 0 -15.5 1.5T1673 312t-13 9Z"
521></glyph
522><glyph unicode="&#xf1d1;" d="M1105 1507q-9 4 -19 5t-19 -2t-17 -9q-53 -43 -123.5 -92t-167 -101.5T605 1247q-1 0 -2 0q-46 -8 -177 -27h-4q-19 -3 -31.5 -17T378 1170V992q0 -2 0 -3q0 -2 0 -2V846q0 -19 12.5 -33T422 796q0 0 7.5 -1t20 -2.5t28 -4t33 -5t34 -5t32 -5T603 769q0 0 0.5 0t1.5 0q58 -8 154.5 -60.5T926.5 607T1050 515q14 -11 33 -11q12 0 22 5q13 6 21 18.5t8 26.5V987q0 1 0 2q0 1 0 1.5t0 1.5v470q0 31 -29 45ZM1407 572q-15 12 -17 31.5t11 34.5q64 78 98 173.5t34 196.5q0 101 -34.5 197T1400 1379q-8 10 -10 22t2 24t14 20q15 13 34.5 11t32.5 -17q75 -91 115 -202t40 -229q0 -117 -40 -228T1474 578q-4 -4 -8 -7.5t-9 -5.5t-10 -3t-10 -1q-17 0 -30 11ZM1671 333q-15 13 -15.5 32.5T1668 400q115 124 176.5 281t61.5 327q0 82 -15 163t-44 156.5T1775.5 1473T1679 1605q-5 5 -7.5 10.5t-4 11.5t-1 12t2.5 12t5.5 11t8.5 10q9 8 21.5 10.5T1729 1681t20 -13q122 -137 186.5 -307T2000 1008q0 -188 -67.5 -361.5T1738 335q-14 -15 -35 -15q-19 0 -32 13Z"
523></glyph
524><glyph unicode="&#xf1d2;" d="M1105 1507q-9 4 -19 5t-19 -2t-17 -9q-53 -43 -123.5 -92t-167 -101.5T605 1247q-1 0 -2 0q-46 -8 -177 -27h-4q-19 -3 -31.5 -17T378 1170V992q0 -2 0 -3q0 -2 0 -2V846q0 -19 12.5 -33T422 796q0 0 7.5 -1t20 -2.5t28 -4t33 -5t34 -5t32 -5T603 769q0 0 0.5 0t1.5 0q58 -8 154.5 -60.5T926.5 607T1050 515q14 -11 33 -11q12 0 22 5q13 6 21 18.5t8 26.5V987q0 1 0 2q0 1 0 1.5t0 1.5v470q0 31 -29 45ZM1407 572q-15 12 -17 31.5t11 34.5q64 78 98 173.5t34 196.5q0 101 -34.5 197T1400 1379q-13 15 -11 34.5t17 31.5q10 8 22.5 10t24.5 -2t20 -14q37 -45 66 -96.5t48.5 -106t30 -112T1628 1008q0 -117 -40 -228T1474 578q-15 -17 -37 -17q-8 0 -15.5 2.5T1407 572ZM1671 333q-15 13 -15.5 32.5T1668 400q76 82 129.5 180.5t81 206.5t27.5 221q0 66 -9.5 131T1868 1266t-46 121t-63.5 114T1679 1605q-13 14 -12 33.5t15.5 33t34 12T1749 1668q122 -137 186.5 -307T2000 1008q0 -125 -30 -244.5t-89 -228T1738 335q-14 -15 -35 -15q-19 0 -32 13Z"
525></glyph
526><glyph unicode="&#xf1d3;" d="M630 252H546q-52 0 -89 37t-37 89V1638q0 52 37 89t89 37h84q52 0 89 -37t37 -89V378q0 -52 -37 -89T630 252ZM1470 252h-84q-52 0 -89 37t-37 89V1638q0 52 37 89t89 37h84q52 0 89 -37t37 -89V378q0 -52 -37 -89t-89 -37Z"
527></glyph
528><glyph unicode="&#xf1d4;" d="M1764 1008V911q0 -66 -27 -125.5t-73.5 -103T1553 613.5T1419 588H588V806q0 32 -15.5 38.5T535 829L263 557Q249 543 244 523.5t0 -39T263 451L535 179q22 -22 37.5 -15.5T588 202V420h831q105 0 200 39t163.5 105t109 156.5T1932 911v97q0 35 -24.5 59.5T1848 1092t-59.5 -24.5T1764 1008ZM600 1428h828V1210q0 -32 15.5 -38.5T1481 1187l272 272q14 14 19 33.5t0 39t-19 33.5l-272 272q-22 22 -37.5 15.5T1428 1814V1596H600q-105 0 -200.5 -39T235 1452.5T125 1296T84 1105v-90q0 -17 6.5 -32.5t18 -27t27 -18T168 931q35 0 59.5 24.5T252 1015v90q0 88 46.5 162.5T425 1385t175 43Z"
529></glyph
530><glyph unicode="&#xf1d5;" d="M646 1171q2 2 3.5 4.5t2.5 5t2.5 5t2.5 4.5q23 42 41.5 75.5T736 1331q-47 60 -96.5 106t-109 83t-130 56.5T252 1596q-35 0 -59.5 -24.5T168 1512t24.5 -59.5T252 1428q62 0 118 -19t104.5 -55T564 1273.5T646 1171ZM1512 1210q0 -32 15.5 -38.5T1565 1187l272 272q14 14 19 33.5t0 39t-19 33.5l-272 272q-22 22 -37.5 15.5T1512 1814V1589q-83 -8 -155.5 -30t-126 -47T1126 1443.5t-82.5 -77t-70 -92.5t-58 -93.5T861 1081q-35 -64 -52 -95Q763 906 722.5 847.5t-91 -110T526.5 655T403 606T252 588q-35 0 -59.5 -24.5T168 504t24.5 -59.5T252 420q62 0 119 8.5T476.5 452t94 38T654 539t74 60t65.5 67.5t59 75T906 821t49 83q18 31 54 98q25 47 38.5 71t37.5 65t40.5 62.5t43.5 54t50.5 50t56 40t67 35t77.5 24t92 17.5V1210ZM1512 806V592q-146 9 -235.5 43T1123 734q-45 -77 -94 -142q80 -73 195 -115t288 -53V202q0 -32 15.5 -38.5T1565 179l272 272q14 14 19 33.5t0 39T1837 557L1565 829q-22 22 -37.5 15.5T1512 806Z"
531></glyph
532><glyph unicode="&#xf1d6;" d="M588 1090v547q0 18 -6 36t-16.5 32t-25 25t-32 17t-36.5 6H452q-48 0 -82 -34.5T336 1637V368q0 -48 34 -82t82 -34h20q19 0 36.5 6t32 16.5t25 25t16.5 32t6 36.5V924L1552 288q51 -34 87 -14.5t36 80.5V1661q0 61 -36 80t-87 -14L588 1090Z"
533></glyph
534><glyph unicode="&#xf1d7;" d="M1544 1753q-48 0 -82 -34.5T1428 1637V1090L459 1727q-35 21 -62 20.5T353 1724t-17 -63V354q0 -61 36 -80.5T459 287l969 637V368q0 -31 15.5 -58T1486 267.5T1544 252h20q48 0 82 34t34 82V1637q0 13 -3 26t-9 24.5t-14 21.5t-18 18t-21.5 14t-24.5 9t-26 3h-20Z"
535></glyph
536><glyph unicode="&#xf1d8;" d="M1142 1595q-15 7 -31 5t-29 -12q-3 -3 -35 -29t-48 -39t-52.5 -42T885 1431.5T823.5 1388t-65 -43T698 1311t-60 -27t-51 -13q-1 -1 -2 -1q-50 -9 -200 -31q-21 -3 -35 -19t-14 -37V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V833q0 -14 6.5 -26T360 787t25 -10Q538 754 585 746q2 -1 2 -1q39 -5 94.5 -32T785 656T896.5 578.5t95 -72T1068 444q10 -8 14 -11q16 -13 36 -13q13 0 24 6q33 15 33 51v531v1v1q0 1 0 2t0 1v531q0 11 -4 21t-11.5 17.5T1142 1595ZM1318 759q-23 13 -30 38t6 48q43 75 43 163q0 29 -5 57.5t-14.5 55.5t-24.5 52q-13 22 -6 47.5t29.5 38.5t47.5 6.5t38 -29.5q30 -52 45.5 -110T1463 1008q0 -30 -3.5 -59t-11 -57.5t-19 -56T1404 782q-18 -31 -55 -31q-17 0 -31 8ZM1530 602q-14 9 -22 24t-7.5 32t10.5 31q92 146 92 319q0 176 -95 322q-9 15 -9.5 31.5t7 31.5t21.5 25q22 14 47.5 8.5T1614 1399q57 -87 86 -187t29 -204q0 -29 -2.5 -58.5t-7 -58t-11.5 -57t-16 -56t-20.5 -54t-25 -52.5T1617 621q-19 -29 -53 -29q-9 0 -17.5 2.5T1530 602ZM1743 445q-22 14 -27 39.5t10 47.5q143 216 143 476q0 264 -147 481q-10 15 -11 31.5t6.5 31.5t21.5 25q22 14 47.5 9.5T1826 1560q55 -82 93 -172t57 -185.5T1995 1008q0 -146 -42 -285T1831 462q-19 -28 -53 -28q-19 0 -35 11ZM21 1008q0 200 78.5 383T310 1706t315 210.5t383 78.5q200 0 381.5 -76T1711 1701q7 -8 11.5 -17t6 -18.5t0 -19t-6 -18.5T1710 1612q-6 -6 -13 -10.5t-15 -6.5t-16 -1.5t-16 2.5t-15.5 6t-13.5 10q-122 124 -280.5 190.5T1008 1869q-175 0 -334.5 -68.5T399 1617T215.5 1342.5T147 1008T215.5 673.5T399 399T673.5 215.5T1008 147q174 0 332.5 66.5T1621 404q19 18 45 18.5T1710 404q13 -12 17 -28t0 -32t-16 -29Q1618 221 1505.5 155T1267 55T1008 21Q808 21 625 99.5T310 310T99.5 625T21 1008Z"
537></glyph
538><glyph unicode="&#xf1d9;" d="M231 1512H357q26 0 44.5 -18.5T420 1449V735q0 -26 -18.5 -44.5T357 672H231q-26 0 -44.5 18.5T168 735v714q0 26 18.5 44.5T231 1512ZM1724 905h-26q49 -4 82 -37.5T1813 786q0 -26 -13 -46.5t-39 -36t-64.5 -26T1605 660q-85 -10 -299 -9q-13 -9 -16.5 -24t4.5 -32q5 -3 12 -9t24.5 -31T1362 498.5T1387 411t11 -122q0 -146 -25 -206.5T1298 22q-31 0 -55 18t-28 44q-16 88 -49.5 165t-75 131t-94 100t-100 74.5t-98 50T715 636t-61 16h-1q-13 0 -24.5 5t-20 13.5t-13.5 20T590 715v756q0 29 33.5 58.5t85 52.5t111 41t114 27.5t91.5 9.5h230q69 0 128.5 -8.5t102 -22t75.5 -31t52.5 -36.5t29.5 -36.5t10 -32.5q0 -18 -5 -33t-12 -24t-14 -15t-12 -9.5t-5 -3.5h58q52 0 89 -37t37 -89q0 -25 -9.5 -47.5t-25.5 -39t-38 -27T1669 1157h55q52 0 89 -37t37 -89t-37 -89t-89 -37Z"
539></glyph
540><glyph unicode="&#xf1da;" d="M231 504H357q26 0 44.5 18.5T420 567v714q0 26 -18.5 44.5T357 1344H231q-26 0 -44.5 -18.5T168 1281V567q0 -26 18.5 -44.5T231 504ZM1724 1111h-26q49 4 82 37.5t33 81.5q0 26 -13 46.5t-39 36t-64.5 26T1605 1356q-85 10 -299 9q-7 4 -11 10.5t-5.5 13.5t-0.5 15t5 17q5 3 12 9t24.5 31t31.5 56.5t25 87.5t11 122q0 146 -25 206.5t-75 60.5q-31 0 -55 -18t-28 -44q-11 -62 -31 -119t-46 -102.5T1081.5 1625t-65 -71.5t-69 -57.5t-71 -46t-68 -34.5t-62.5 -25T694 1374t-40 -10h-1q-9 0 -17 -2t-15 -6.5t-12.5 -10t-10 -12.5T592 1318t-2 -17V545q0 -36 51 -72T763 412T906.5 371.5T1025 356h230q69 0 128.5 8.5t102 22t75.5 31t52.5 36.5t29.5 36.5t10 32.5q0 18 -5 33t-12 24t-14 15t-12 9.5t-5 3.5h58q25 0 48.5 10t40.5 27t27 40.5t10 48.5q0 33 -16 61.5t-43.5 45T1669 859h55q52 0 89 37t37 89t-37 89t-89 37Z"
541></glyph
542><glyph unicode="&#xf1db;" d="M1142 1595q-15 7 -31 5t-29 -12q-3 -3 -35 -29t-48 -39t-52.5 -42T885 1431.5T823.5 1388t-65 -43T698 1311t-60 -27t-51 -13q-1 -1 -2 -1q-50 -9 -200 -31q-21 -3 -35 -19t-14 -37V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V833q0 -14 6.5 -26T360 787t25 -10Q538 754 585 746q2 -1 2 -1q39 -5 94.5 -32T785 656T896.5 578.5t95 -72T1068 444q10 -8 14 -11q16 -13 36 -13q13 0 24 6q33 15 33 51v531v1v1q0 1 0 2t0 1v531q0 11 -4 21t-11.5 17.5T1142 1595ZM1318 759q-23 13 -30 38t6 48q43 75 43 163q0 89 -44 165q-13 22 -6 47.5t29.5 38.5t47.5 6.5t38 -29.5q61 -105 61 -228q0 -59 -15 -116.5T1404 782q-18 -31 -55 -31q-17 0 -31 8ZM1530 602q-14 9 -22 24t-7 32t10 31q92 146 92 319q0 176 -95 322q-14 22 -8.5 47.5t27.5 40t47.5 9T1614 1399q38 -58 63.5 -122T1716 1145t13 -137q0 -103 -28.5 -201.5T1617 621q-19 -29 -53 -29q-5 0 -9 0.5t-8.5 2T1538 598t-8 4ZM1743 445q-22 14 -27 39.5t10 47.5q143 216 143 476q0 264 -147 481q-15 22 -10 47.5t27 40t47.5 10T1826 1560q83 -123 126 -263.5T1995 1008q0 -146 -42 -285T1831 462q-9 -13 -23 -20.5T1778 434q-4 0 -8.5 0.5t-9 2t-9 3.5t-8.5 5Z"
543></glyph
544><glyph unicode="&#xf1dc;" d="M1134 1334l289 -289q37 -37 89 -37t89 37t37 89t-37 89l-504 504q-37 37 -89 37t-89 -37L415 1223q-37 -37 -37 -89t37 -89t89 -37t89 37l289 289V378q0 -52 37 -89t89 -37t89 37t37 89v956Z"
545></glyph
546><glyph unicode="&#xf1dd;" d="M1134 1333l289 -289q37 -37 89 -37t89 37q37 38 37 90t-37 89l-504 504q-37 37 -89 37t-89 -37L415 1223q-37 -39 -37 -89q0 -51 37 -90q37 -37 89 -37t89 37l289 289V378q0 -52 37 -89t89 -37t89 37t37 89v955Z"
547></glyph
548><glyph unicode="&#xf1de;" d="M913 1378L571 1035q-28 -28 -67 -28t-67 28t-28 67t28 67l504 504q2 1 4.5 3.5t5 4.5t5.5 4l6 3l10 5l9 3q6 2 8 3q19 3 37 0l9 -3l9 -3q3 -1 9 -5q3 -1 7 -3q3 -2 5.5 -4t5 -4.5t4.5 -3.5l504 -504q27 -29 27 -67t-27 -67q-28 -28 -67 -28t-67 28l-343 343V346q0 -39 -27.5 -66.5T1008 252t-67 27.5T913 346V1378Z"
549></glyph
550><glyph unicode="&#xf1df;" d="M882 682L593 971q-37 37 -89 37T415 971T378 882t37 -88L919 289q37 -37 89 -37t89 37l504 505q37 36 37 88t-37 89t-89 37t-89 -37L1134 682v956q0 53 -36.5 89.5T1008 1764t-89.5 -36.5T882 1638V682Z"
551></glyph
552><glyph unicode="&#xf1e0;" d="M882 683L593 972q-37 37 -89 37T415 972Q377 934 377 882.5T415 793L919 289q36 -37 88.5 -37t89.5 37l504 504q36 37 36 89t-36 90q-37 37 -89 37t-89 -37L1134 683v955q0 52 -37.5 89t-88.5 37q-53 0 -89.5 -36.5T882 1638V683Z"
553></glyph
554><glyph unicode="&#xf1e1;" d="M1103 638l342 343q28 28 67 28t67 -28t28 -67t-28 -67L1075 343q-2 -1 -4.5 -3.5t-5 -4.5t-5.5 -4l-6 -3q-10 -5 -10 -5l-9 -3q-6 -2 -8 -3q-19 -3 -37 0l-9 3l-9 3q-3 1 -9 5q-3 1 -7 3q-3 2 -5.5 4t-5 4.5T941 343L437 847q-27 29 -27 67t27 67q28 28 67 28t67 -28L914 638V1670q0 39 27.5 66.5T1008 1764t67 -27.5t28 -66.5V638Z"
555></glyph
556><glyph unicode="&#xf1e2;" d="M1490 1114q-56 -56 -150 -40t-172 94t-94 172t40 150l-1 1L630 1008L467 845Q430 808 390.5 747.5T331 639L173 243q-7 -18 -8.5 -33T167 185t13.5 -15.5T203 164q18 0 40 9L639 331q32 13 71 35.5T785 416t60 51l200 200l446 446l-1 1ZM296 296L419 604q16 39 50.5 91.5T534 778l62 62q21 -86 89.5 -154.5T840 596L778 534Q748 504 695.5 469.5T604 419L296 296ZM1801 1801q-47 47 -102.5 72T1591 1898q-69 0 -112 -43l-1 1L1248 1626v-1q-55 -56 -39 -150t94 -172t172 -94t150 40l1 -1l230 230l-1 1q18 18 29 42.5t13.5 51t-2.5 56t-17 59t-32 58.5t-45 55ZM1591 1835q27 0 56 -9.5t57 -27t52 -42.5q64 -63 77 -138q1 -10 1.5 -20.5t-1 -24t-7 -26.5T1811 1524q-24 -24 -68 -24q-40 0 -84 20.5t-81 57.5q-38 38 -59 83.5t-20 85.5t25 64q24 24 67 24Z"
557></glyph
558><glyph unicode="&#xf1e3;" d="M1114 1490l-1 1L630 1008L467 845Q430 808 390.5 747.5T331 639L173 243q-15 -37 -6 -58t36 -21q18 0 40 9L639 331q32 13 71 35.5T785 416t60 51l200 200l446 446l-1 1q-56 -56 -150 -40t-172 94t-94 172t40 150ZM616 390L239 239L390 616q17 42 53 97t69 88l78 78q2 -33 13.5 -66T636 747t49 -62q88 -87 194 -95L801 512Q768 479 713 443T616 390ZM1591 1898q-16 0 -31.5 -2.5t-30 -8t-27 -13.5T1479 1855l-1 1L1248 1626l1 -1q-56 -56 -40 -150t94 -172q51 -51 112 -76.5t117 -20t93 42.5l1 -1l230 230l-1 1q56 56 40 150t-94 172q-47 47 -102.5 72T1591 1898ZM1756 1756q59 -58 75 -127t-20 -105q-24 -24 -68 -24q-40 0 -84 20.5t-81 57.5q-38 38 -59 83.5t-20 85.5t25 64q24 24 67 24q41 0 84.5 -21t80.5 -58Z"
559></glyph
560><glyph unicode="&#xf1e4;" d="M1114 1490l-1 1L630 1008L467 845Q443 821 416 785T366.5 710T331 639L173 243q-10 -25 -9 -42.5t11 -27T203 164q9 0 19 2t21 7L639 331q32 13 71 35.5T785 416t60 51l200 200l446 446l-1 1q-56 -56 -150 -40t-172 94t-94 172t40 150ZM616 390L239 239L390 616q17 42 53 97t69 88l77 77q4 -49 29 -99.5t67.5 -93t93 -67.5T878 589L801 512Q768 479 713 443T616 390ZM1591 1898q-33 0 -62 -10.5T1479 1855l-1 1L1248 1626l1 -1q-56 -56 -40 -150t94 -172t172 -94t150 40l1 -1l230 230l-1 1q60 60 37 163q-20 87 -91 159q-47 47 -102.5 72T1591 1898ZM1591 1835q41 0 84.5 -21t80.5 -58q64 -63 77 -138q10 -62 -22 -94q-7 -7 -16 -12t-18 -7.5t-17 -3.5t-17 -1q-40 0 -84 20.5t-81 57.5q-58 58 -74 127.5t20 105.5q24 24 67 24Z"
561></glyph
562><glyph unicode="&#xf1e5;" d="M693 648q-79 0 -153.5 50t-127 130t-84 182T297 1214q0 67 14 126t40 105.5t62 83t80 60.5t94.5 36.5T693 1638q83 0 154.5 -28.5t125.5 -81T1058 1395t31 -181q0 -102 -31.5 -204t-84 -182T846.5 698T693 648ZM1074 675Q997 581 900 528T693 475q-75 0 -145.5 26t-129 70.5T310 678q-25 -9 -49 -19T218 640.5t-36 -17t-29.5 -15T131 597t-13 -8l-5 -2Q66 557 33 497T0 383T39.5 290.5T135 252H1251q37 0 68 17.5t49 47.5t18 66q0 54 -33.5 113.5T1272 585q-9 5 -25 14t-67.5 33T1074 675ZM1764 1260H1512V1008H1260V756h252V504h252V756h252v252H1764v252Z"
563></glyph
564><glyph unicode="&#xf1e6;" d="M1701 882v252q0 26 -18.5 44.5T1638 1197t-44.5 -18.5T1575 1134V882H1323q-26 0 -44.5 -18.5T1260 819t18.5 -44.5T1323 756h252V504q0 -26 18.5 -44.5T1638 441t44.5 18.5T1701 504V756h252q26 0 44.5 18.5T2016 819t-18.5 44.5T1953 882H1701ZM693 648q-79 0 -153.5 50t-127 130t-84 182T297 1214q0 67 14 126t40 105.5t62 83t80 60.5t94.5 36.5T693 1638q83 0 154.5 -28.5t125.5 -81T1058 1395t31 -181q0 -102 -31.5 -204t-84 -182T846.5 698T693 648ZM1074 676Q1024 614 966 570T837.5 500.5T693 475q-111 0 -208.5 54T310 679Q189 635 113 587Q66 557 33 497T0 383T39.5 290.5T135 252H1251q37 0 68 17.5t49 47.5t18 66q0 18 -4 37.5T1370.5 459t-18 37.5t-23 34.5T1302 561t-30 24q-3 2 -9 5.5t-25.5 14t-41 21t-55 24.5T1074 676Z"
565></glyph
566><glyph unicode="&#xf1e7;" d="M1155 996l735 460v56q0 52 -37 89t-89 37H252q-52 0 -89 -37t-37 -89v-56L861 996q58 -36 147 -36t147 36ZM1008 709q-30 0 -60 3t-59.5 9T831 735.5T777 756t-49 27L126 1159V504q0 -52 37 -89t89 -37H1764q52 0 89 37t37 89v655L1288 783Q1171 709 1008 709Z"
567></glyph
568><glyph unicode="&#xf1e8;" d="M1172 970l718 449v93q0 52 -37 89t-89 37H252q-52 0 -89 -37t-37 -89v-93L844 970q43 -27 103.5 -36.5t121 0T1172 970ZM1008 740q-73 0 -141 17.5T744 809L126 1196V504q0 -52 37 -89t89 -37H1764q52 0 89 37t37 89v692L1272 809q-37 -22 -80.5 -38T1102 747.5T1008 740Z"
569></glyph
570><glyph unicode="&#xf1e9;" d="M760 127v882H578v303H760v183q0 76 13 136.5T815 1741t74.5 81.5t112.5 50t153 17.5h244V1586H1247q-42 0 -67 -7t-37 -25t-15 -36.5t-3 -53.5V1312h275l-32 -303H1125V127H760Z"
571></glyph
572><glyph unicode="&#xf1ea;" d="M760 127v882H578v303H760v183q0 76 13 136.5T815 1741t74.5 81.5t112.5 50t153 17.5h244V1586H1247q-42 0 -67 -7t-37 -25t-15 -36.5t-3 -53.5V1312h275l-32 -303H1125V127H760Z"
573></glyph
574><glyph unicode="&#xf1eb;" d="M0 1008Q0 910 24.5 815t70 -179T204 477L62 145Q36 85 60.5 60.5T145 62L535 229Q757 126 1008 126q205 0 391.5 70T1721 384t215 281.5t80 342.5t-80 342.5T1721 1632t-321.5 188T1008 1890T616.5 1820T295 1632T80 1350.5T0 1008ZM378 882v252H630V882H378ZM882 882v252h252V882H882ZM1386 882v252h252V882H1386Z"
575></glyph
576><glyph unicode="&#xf1ec;" d="M0 1008Q0 861 53.5 725.5T204 477L31 72Q18 43 30.5 30.5T72 31L535 229Q757 126 1008 126q205 0 391.5 70T1721 384t215 281.5t80 342.5t-80 342.5T1721 1632t-321.5 188T1008 1890T616.5 1820T295 1632T80 1350.5T0 1008ZM504 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T593 919T504 882ZM1008 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89t-37 -89t-89 -37ZM1512 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89t-37 -89t-89 -37Z"
577></glyph
578><glyph unicode="&#xf1ed;" d="M1706 1526q60 36 103.5 90.5T1874 1738q-113 -68 -243 -93q-53 57 -125.5 89T1352 1766q-103 0 -191 -51.5T1021.5 1575T970 1383q0 -44 10 -87q-234 12 -439 117.5T193 1696q-52 -89 -52 -192q0 -98 46 -182T311 1186q-92 2 -173 47q0 -1 0 -5q0 -39 7.5 -77T168 1079t35.5 -64.5t47 -56.5T307 911t65 -35.5T444 854q-12 -3 -24 -5.5T395 844t-25.5 -3T344 840q-19 0 -37 2t-35 5q18 -56 52.5 -104.5t81 -83.5t104 -55.5T629 582Q563 530 487.5 494T327 438T154 418q-46 0 -91 6q64 -41 133 -73T338.5 297t152 -33.5T649 252q147 0 281 33.5T1172 379t199.5 142t158 178.5T1643 903t70 217t23 219q0 25 -1 50q113 81 190 197q-104 -46 -219 -60Z"
579></glyph
580><glyph unicode="&#xf1ee;" d="M1706 1526q60 36 103.5 90.5T1874 1738q-113 -68 -243 -93q-53 57 -125.5 89T1352 1766q-103 0 -191 -51.5T1021.5 1575T970 1383q0 -44 10 -87q-234 12 -439 117.5T193 1696q-52 -89 -52 -192q0 -98 46 -182T311 1186q-92 2 -173 47q0 -1 0 -5q0 -39 7.5 -77T168 1079t35.5 -64.5t47 -56.5T307 911t65 -35.5T444 854q-12 -3 -24 -5.5T395 844t-25.5 -3T344 840q-19 0 -37 2t-35 5q18 -56 52.5 -104.5t81 -83.5t104 -55.5T629 582Q563 530 487.5 494T327 438T154 418q-46 0 -91 6q64 -41 133 -73T338.5 297t152 -33.5T649 252q147 0 281 33.5T1172 379t199.5 142t158 178.5T1643 903t70 217t23 219q0 25 -1 50q113 81 190 197q-104 -46 -219 -60Z"
581></glyph
582><glyph unicode="&#xf1ef;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52Z"
583></glyph
584><glyph unicode="&#xf1f0;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52Z"
585></glyph
586><glyph unicode="&#xf1f1;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52Z"
587></glyph
588><glyph unicode="&#xf1f2;" d="M1764 1008q0 -205 -101.5 -379T1387 353.5T1008 252T629 353.5T353.5 629T252 1008t101.5 379T629 1662.5T1008 1764t379 -101.5T1662.5 1387T1764 1008ZM126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM1005 763q26 0 50.5 -10.5T1098 724t28.5 -42.5T1137 631q0 -21 -7 -40.5T1111 555t-28.5 -28.5t-36.5 -19T1005 501q-54 0 -92.5 38.5T874 631q0 54 38.5 93t92.5 39ZM921 955l-25 494q-1 10 2 19.5t8.5 17.5t13 14t16.5 9t20 3h101q26 0 44 -18.5t16 -44.5L1094 955q-2 -26 -21 -44.5T1028 892H987q-17 0 -32 8.5t-24 23T921 955Z"
589></glyph
590><glyph unicode="&#xf1f3;" d="M1827 1008q0 -166 -65 -318T1587.5 428.5T1326 254T1008 189T690 254T428.5 428.5T254 690t-65 318t65 318t174.5 261.5T690 1762t318 65t318 -65t261.5 -174.5T1762 1326t65 -318ZM126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM1005 763q26 0 50.5 -10.5T1098 724t28.5 -42.5T1137 631q0 -21 -7 -40.5T1111 555t-28.5 -28.5t-36.5 -19T1005 501q-54 0 -92.5 38.5T874 631q0 54 38.5 93t92.5 39ZM921 955l-25 494q-1 10 2 19.5t8.5 17.5t13 14t16.5 9t20 3h101q26 0 44 -18.5t16 -44.5L1094 955q-2 -26 -21 -44.5T1028 892H987q-17 0 -32 8.5t-24 23T921 955Z"
591></glyph
592><glyph unicode="&#xf1f4;" d="M1827 1008q0 -166 -65 -318T1587.5 428.5T1326 254T1008 189T690 254T428.5 428.5T254 690t-65 318t65 318t174.5 261.5T690 1762t318 65t318 -65t261.5 -174.5T1762 1326t65 -318ZM126 1008q0 -179 70 -342.5T384 384T665.5 196T1008 126t342.5 70T1632 384t188 281.5t70 342.5t-70 342.5T1632 1632t-281.5 188T1008 1890T665.5 1820T384 1632T196 1350.5T126 1008ZM1005 763q26 0 50.5 -10.5T1098 724t28.5 -42.5T1137 631q0 -21 -7 -40.5T1111 555t-28.5 -28.5t-36.5 -19T1005 501q-54 0 -92.5 38.5T874 631q0 54 38.5 93t92.5 39ZM921 955l-25 494q-1 10 2 19.5t8.5 17.5t13 14t16.5 9t20 3h101q26 0 44 -18.5t16 -44.5L1094 955q-2 -26 -21 -44.5T1028 892H987q-17 0 -32 8.5t-24 23T921 955Z"
593></glyph
594><glyph unicode="&#xf1f5;" d="M693 648q-79 0 -153.5 50t-127 130t-84 182T297 1214q0 67 14 126t40 105.5t62 83t80 60.5t94.5 36.5T693 1638q83 0 154.5 -28.5t125.5 -81T1058 1395t31 -181q0 -102 -31.5 -204t-84 -182T846.5 698T693 648ZM1074 675Q997 581 900 528T693 475q-75 0 -145.5 26t-129 70.5T310 678q-25 -9 -49 -19T218 640.5t-36 -17t-29.5 -15T131 597t-13 -8l-5 -2Q66 557 33 497T0 383T39.5 290.5T135 252H1251q37 0 68 17.5t49 47.5t18 66q0 54 -33.5 113.5T1272 585q-9 5 -25 14t-67.5 33T1074 675ZM1764 1260H1512V1008H1260V756h252V504h252V756h252v252H1764v252Z"
595></glyph
596><glyph unicode="&#xf1f6;" d="M1172 970l718 449v93q0 52 -37 89t-89 37H252q-52 0 -89 -37t-37 -89v-93L844 970q43 -27 103.5 -36.5t121 0T1172 970ZM1008 740q-73 0 -141 17.5T744 809L126 1196V504q0 -52 37 -89t89 -37H1764q52 0 89 37t37 89v692L1272 809q-37 -22 -80.5 -38T1102 747.5T1008 740Z"
597></glyph
598><glyph unicode="&#xf1f7;" d="M756 126v882H567v315H756v172q0 95 21.5 166.5t68 123.5t124 78.5T1155 1890h231V1575H1247q-43 0 -67.5 -5.5t-36.5 -21t-15 -33t-3 -51.5V1323h275l-32 -315H1134V126H756Z"
599></glyph
600><glyph unicode="&#xf1f8;" d="M0 1008Q0 861 53.5 725.5T204 477L31 72Q18 43 30.5 30.5T72 31L535 229Q757 126 1008 126q205 0 391.5 70T1721 384t215 281.5t80 342.5t-80 342.5T1721 1632t-321.5 188T1008 1890T616.5 1820T295 1632T80 1350.5T0 1008ZM504 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89T593 919T504 882ZM1008 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89t-37 -89t-89 -37ZM1512 882q-52 0 -89 37t-37 89t37 89t89 37t89 -37t37 -89t-37 -89t-89 -37Z"
601></glyph
602><glyph unicode="&#xf1f9;" d="M1706 1526q60 36 103.5 90.5T1874 1738q-113 -68 -243 -93q-53 57 -125.5 89T1352 1766q-103 0 -191 -51.5T1021.5 1575T970 1383q0 -44 10 -87q-234 12 -439 117.5T193 1696q-52 -89 -52 -192q0 -98 46 -182T311 1186q-92 2 -173 47q0 -1 0 -5q0 -39 7.5 -77T168 1079t35.5 -64.5t47 -56.5T307 911t65 -35.5T444 854q-12 -3 -24 -5.5T395 844t-25.5 -3T344 840q-19 0 -37 2t-35 5q18 -56 52.5 -104.5t81 -83.5t104 -55.5T629 582Q563 530 487.5 494T327 438T154 418q-46 0 -91 6q64 -41 133 -73T338.5 297t152 -33.5T649 252q147 0 281 33.5T1172 379t199.5 142t158 178.5T1643 903t70 217t23 219q0 25 -1 50q113 81 190 197q-104 -46 -219 -60Z"
603></glyph
604><glyph unicode="&#xf1fa;" d="M1134 832q-31 17 -69.5 21.5t-77 -2T911 829T842 790.5T789 738T760 675q-6 -33 -1 -64.5T778 562q48 -58 132.5 -66t167 29.5T1211 628q11 14 19 28t13.5 30.5t9 32.5t5 39.5t2 45.5t0.5 57v714q0 26 -18.5 44.5T1197 1638t-44.5 -18.5T1134 1575V832ZM1638 252H378V1764h943q12 -2 20 -8l45 -44V1559q0 -13 6.5 -23.5t17 -17T1433 1512h153h131h31q-2 4 -6 11q-1 2 -2 4q0 4 -2 8.5t-7 9.5l-312 312q-4 4 -8.5 6.5t-8.5 2.5q-42 24 -79 24H315q-26 0 -44.5 -18.5T252 1827V189q0 -26 18.5 -44.5T315 126H1701q26 0 44.5 18.5T1764 189V1386H1638V252Z"
605></glyph
606><glyph unicode="&#xf1fb;" d="M1134 832q-23 13 -51 18.5t-56.5 4.5T968 847.5t-57.5 -18T858 801.5t-45 -36T779.5 723T760 675q-6 -33 -1 -64.5T778 562q48 -58 132.5 -66t167 29.5T1211 628q11 14 19 28t13.5 30.5t9 32.5t5 39.5t2 45.5t0.5 57v714q0 26 -18.5 44.5T1197 1638t-44.5 -18.5T1134 1575V832ZM1701 189H315V1827H1323q9 0 21.5 -4t24 -10t17.5 -12V1559q0 -13 6.5 -23.5t17 -17T1433 1512h242h42h31q-2 4 -6 11q-1 2 -2 4q0 3 -1 5.5t-3 6t-5 6.5l-312 312q-2 2 -3.5 3.5t-3.5 2.5t-3.5 1.5t-3.5 1t-3 0.5q-42 24 -79 24H315q-26 0 -44.5 -18.5T252 1827V189q0 -26 18.5 -44.5T315 126H1701q26 0 44.5 18.5T1764 189V1386h-63V189Z"
607></glyph
608><glyph unicode="&#xf1fc;" d="M1134 832q-37 20 -84.5 23T956 844.5t-87.5 -37T798 749T760 675q-6 -33 -1 -64.5T778 562q48 -58 132.5 -66t167 29.5T1211 628q11 14 19 28t13.5 30.5t9 32.5t5 39.5t2 45.5t0.5 57v714q0 26 -18.5 44.5T1197 1638t-44.5 -18.5T1134 1575V832ZM1701 189H315V1827H1323q13 0 33 -8.5t30 -17.5V1559q0 -13 6.5 -23.5t17 -17T1433 1512h242h42h31l-7 14q0 4 -2.5 9t-7.5 10l-312 312q-10 10 -18 10q-42 23 -78 23H315q-26 0 -44.5 -18.5T252 1827V189q0 -26 18.5 -44.5T315 126H1701q26 0 44.5 18.5T1764 189V1386h-63V189Z"
609></glyph
610><glyph unicode="&#xf1fd;" d="M1764 1512H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37ZM1764 882H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37ZM1764 252H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37Z"
611></glyph
612><glyph unicode="&#xf1fe;" d="M1764 1512H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37ZM1764 882H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37ZM1764 252H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37Z"
613></glyph
614><glyph unicode="&#xf1ff;" d="M1764 1512H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37ZM1764 882H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37ZM1764 252H252q-52 0 -89 37t-37 89t37 89t89 37H1764q52 0 89 -37t37 -89t-37 -89t-89 -37Z"
615></glyph
616><glyph unicode="&#xf200;" d="M378 1105q0 116 89.5 198.5T684 1386h83q-11 67 -11 126q0 21 1.5 42.5t4 42T767 1638H684q-114 0 -217 -42.5T289 1482T170 1312T126 1105v-97q0 -52 37 -89t89 -37t89 37t37 89v97ZM2016 1512q0 137 -67.5 253T1765 1948.5T1512 2016t-253 -67.5T1075.5 1765T1008 1512t67.5 -253T1259 1075.5T1512 1008t253 67.5T1948.5 1259t67.5 253ZM1638 1890V1149H1512v573l-126 -84l-88 79l208 173h132ZM630 630V806q0 13 -2.5 21.5t-7.5 13t-11.5 5t-15 -4T577 829L305 557Q291 543 286 523.5t0 -39T305 451L577 179q22 -22 37.5 -15.5T630 202V378h702q106 0 203 37t170 101t120.5 152T1884 855q-68 -39 -142 -63T1589 760q-42 -60 -109.5 -95T1332 630H630Z"
617></glyph
618><glyph unicode="&#xf201;" d="M2016 1554q0 191 -135.5 326.5T1554 2016T1227.5 1880.5T1092 1554t135.5 -326.5T1554 1092t326.5 135.5T2016 1554ZM1680 1848V1260H1512v438l-101 -75l-73 70l192 155h150ZM588 588V806q0 32 -15.5 38.5T535 829L263 557Q249 543 244 523.5t0 -39T263 451L535 179q22 -22 37.5 -15.5T588 202V420h831q105 0 200 39t163.5 105t109 156.5T1932 911v63q-40 -26 -82.5 -46.5T1762 893Q1754 765 1655.5 676.5T1419 588H588ZM600 1428H873q-12 65 -12 126q0 6 0.5 12.5t1 16.5t0.5 13H600q-105 0 -200.5 -39T235 1452.5T125 1296T84 1105v-90q0 -17 6.5 -32.5t18 -27t27 -18T168 931q35 0 59.5 24.5T252 1015v90q0 88 46.5 162.5T425 1385t175 43Z"
619></glyph
620><glyph unicode="&#xf202;" d="M1512 1008q-137 0 -253 67.5T1075.5 1259T1008 1512t67.5 253T1259 1948.5t253 67.5t253 -67.5T1948.5 1765T2016 1512t-67.5 -253T1765 1075.5T1512 1008ZM346 1137q0 63 27 121t72 99.5T552.5 1424T684 1449h75q-3 38 -3 63q0 31 3 62.5t8 63.5H684q-107 0 -204.5 -40t-168 -107t-112 -159.5T158 1137v-97q0 -40 27.5 -67.5T252 945t66.5 27.5T346 1040v97ZM1332 567H630V775q0 20 -7 30.5T603.5 814T577 797L305 526Q291 512 286 492.5t0 -39T305 419L577 148q22 -22 37.5 -15.5T630 170V378h702q80 0 152.5 22T1615 463t102.5 96T1789 682t35 142q-98 -44 -206 -60Q1586 675 1511 621T1332 567ZM1638 1890H1506L1298 1717l88 -79l126 84V1149h126v741Z"
621></glyph
622><glyph unicode="&#xf203;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4Z"
623></glyph
624><glyph unicode="&#xf204;" d="M1142 1595q-15 7 -31 5t-29 -12q-3 -3 -35 -29t-48 -39t-52.5 -42T885 1431.5T823.5 1388t-65 -43T698 1311t-60 -27t-51 -13q-1 -1 -2 -1q-50 -9 -200 -31q-21 -3 -35 -19t-14 -37V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V833q0 -14 6.5 -26T360 787t25 -10Q538 754 585 746q2 -1 2 -1q39 -5 94.5 -32T785 656T896.5 578.5t95 -72T1068 444q10 -8 14 -11q16 -13 36 -13q13 0 24 6q33 15 33 51v531v1v1q0 1 0 2t0 1v531q0 11 -4 21t-11.5 17.5T1142 1595ZM1318 759q-23 13 -30 38t6 48q43 75 43 163q0 29 -5 57.5t-14.5 55.5t-24.5 52q-13 22 -6 47.5t29.5 38.5t47.5 6.5t38 -29.5q30 -52 45.5 -110T1463 1008q0 -30 -3.5 -59t-11 -57.5t-19 -56T1404 782q-18 -31 -55 -31q-17 0 -31 8Z"
625></glyph
626><glyph unicode="&#xf205;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4Z"
627></glyph
628><glyph unicode="&#xf206;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4ZM1532 590q-26 16 -32.5 45.5T1509 690q92 145 92 318q0 175 -94 321q-6 10 -9 21.5t-2.5 22.5t4.5 21.5t11.5 20T1529 1430q12 8 26.5 10.5t28 -0.5t25.5 -11t20 -21q29 -44 51 -92.5t37 -98.5t22.5 -103t7.5 -106q0 -215 -115 -396q-10 -16 -26.5 -25T1571 578q-22 0 -39 12Z"
629></glyph
630><glyph unicode="&#xf207;" d="M1142 1595q-15 7 -31 5t-29 -12q-3 -3 -35 -29t-48 -39t-52.5 -42T885 1431.5T823.5 1388t-65 -43T698 1311t-60 -27t-51 -13q-1 -1 -2 -1q-50 -9 -200 -31q-21 -3 -35 -19t-14 -37V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V833q0 -14 6.5 -26T360 787t25 -10Q538 754 585 746q2 -1 2 -1q39 -5 94.5 -32T785 656T896.5 578.5t95 -72T1068 444q10 -8 14 -11q16 -13 36 -13q13 0 24 6q33 15 33 51v531v1v1q0 1 0 2t0 1v531q0 11 -4 21t-11.5 17.5T1142 1595ZM1318 759q-23 13 -30 38t6 48q43 75 43 163q0 29 -5 57.5t-14.5 55.5t-24.5 52q-13 22 -6 47.5t29.5 38.5t47.5 6.5t38 -29.5q30 -52 45.5 -110T1463 1008q0 -30 -3.5 -59t-11 -57.5t-19 -56T1404 782q-18 -31 -55 -31q-17 0 -31 8ZM1530 602q-14 9 -22 24t-7.5 32t10.5 31q92 146 92 319q0 176 -95 322q-9 15 -9.5 31.5t7 31.5t21.5 25q22 14 47.5 8.5T1614 1399q57 -87 86 -187t29 -204q0 -29 -2.5 -58.5t-7 -58t-11.5 -57t-16 -56t-20.5 -54t-25 -52.5T1617 621q-19 -29 -53 -29q-9 0 -17.5 2.5T1530 602Z"
631></glyph
632><glyph unicode="&#xf208;" d="M1161 1602q-33 16 -61 -7q-41 -34 -98 -75T871.5 1431T724 1347.5T600 1305q-1 0 -2 0q-60 -11 -203 -31q-14 -2 -25.5 -10.5t-18 -20.5T345 1217V1013q0 0 0 -2q0 0 0 -1q0 -2 0 -2V804q0 -14 6.5 -26.5t18 -20.5T395 747Q551 724 598 716q0 0 0.5 0t1.5 0q50 -8 124 -43T871.5 590T1002 501t98 -75q16 -13 37 -13q13 0 24 6q33 15 33 52v537q0 0 0 1t0 1v1v2v537q0 37 -33 52ZM1317 748q-26 15 -34 44t7 55q42 75 42 161q0 87 -43 162q-15 26 -7.5 55.5t34 44.5t55.5 7t44 -34q63 -109 63 -235q0 -61 -15.5 -120.5T1416 775q-21 -36 -63 -36q-4 0 -9 0.5t-9.5 1.5t-9 3t-8.5 4ZM1532 590q-26 16 -32.5 45.5T1509 690q92 145 92 318q0 175 -94 321q-6 10 -9 21.5t-2.5 22.5t4.5 21.5t11.5 20T1529 1430q12 8 26.5 10.5t28 -0.5t25.5 -11t20 -21q29 -44 51 -92.5t37 -98.5t22.5 -103t7.5 -106q0 -215 -115 -396q-10 -16 -26.5 -25T1571 578q-22 0 -39 12Z"
633></glyph
634><glyph unicode="&#xf209;" d="M1512 1008q-137 0 -253 67.5T1075.5 1259T1008 1512t67.5 253T1259 1948.5t253 67.5t253 -67.5T1948.5 1765T2016 1512t-67.5 -253T1765 1075.5T1512 1008ZM1332 598H630V806q0 16 -4.5 25.5T614 844t-17 -1T577 829L305 557Q283 535 283 504t22 -53L577 179q10 -10 20 -14t17 -1t11.5 12.5T630 202V410h702q97 0 187 33t158 90t114.5 136T1852 837Q1746 784 1630 765q-17 -29 -40 -55t-52 -46.5t-61.5 -35t-69 -22.5T1332 598ZM346 1105q0 32 7 63t20 58.5t31.5 53t41 46.5t50 38t57 29t63 18.5T684 1418h78q-3 23 -4.5 47t-1.5 47q0 46 6 94H684q-86 0 -166 -25T373 1509.5t-113.5 -108t-75 -138T158 1105v-97q0 -39 27.5 -66.5T252 914t66.5 27.5T346 1008v97ZM1606 1890H1468L1260 1717l88 -79l132 94V1134h126v756Z"
635></glyph
636><glyph unicode="&#xf20a;" d="M1638 126H378q-52 0 -89 37t-37 89V756q0 52 -37 89t-89 37T63 908t26 63l830 830q18 18 41.5 27.5t47.5 9.5t47.5 -9.5T1097 1801L1927 971q24 -24 27.5 -44.5T1941 894t-51 -12q-52 0 -89 -37t-37 -89V252q0 -52 -37 -89t-89 -37ZM1260 1449q0 26 -18.5 44.5T1197 1512t-44.5 -18.5T1134 1449V670q-26 16 -61.5 22.5T999 695T921.5 680t-76 -31T779 605T728.5 550T701 487q-8 -39 -1.5 -75.5T722 355q34 -41 84.5 -61t106 -17t111 21.5T1129 352t86 80q30 38 37.5 79t7.5 121v817Z"
637></glyph
638><glyph unicode="&#xf20b;" d="M1638 126H378q-52 0 -89 37t-37 89V756q0 52 -37 89t-89 37T63 908t26 63l830 830q18 18 41.5 27.5t47.5 9.5t47.5 -9.5T1097 1801L1927 971q24 -24 27.5 -44.5T1941 894t-51 -12q-52 0 -89 -37t-37 -89V252q0 -52 -37 -89t-89 -37ZM1260 1449q0 26 -18.5 44.5T1197 1512t-44.5 -18.5T1134 1449V670q-26 16 -61.5 22.5T999 695T921.5 680t-76 -31T779 605T728.5 550T701 487q-8 -39 -1.5 -75.5T722 355q34 -41 84.5 -61t106 -17t111 21.5T1129 352t86 80q30 38 37.5 79t7.5 121v817Z"
639></glyph
640><glyph unicode="&#xf20c;" d="M1638 126H378q-52 0 -89 37t-37 89V756q0 52 -37 89t-89 37T63 908t26 63l830 830q18 18 41.5 27.5t47.5 9.5t47.5 -9.5T1097 1801L1927 971q24 -24 27.5 -44.5T1941 894t-51 -12q-52 0 -89 -37t-37 -89V252q0 -52 -37 -89t-89 -37ZM1260 1449q0 26 -18.5 44.5T1197 1512t-44.5 -18.5T1134 1449V670q-26 16 -61.5 22.5T999 695T921.5 680t-76 -31T779 605T728.5 550T701 487q-8 -39 -1.5 -75.5T722 355q34 -41 84.5 -61t106 -17t111 21.5T1129 352t86 80q30 38 37.5 79t7.5 121v817Z"
641></glyph
642><glyph unicode="&#xf20d;" d="M1834 476L1190 154q-23 -11 -39.5 -1T1134 189v882q0 17 8 34t22 30.5t30 18.5l636 212q25 8 42.5 -4.5T1890 1323V567q0 -26 -16.5 -53T1834 476ZM948 1404L249 1614q-25 7 -24.5 17t25.5 17l697 179q25 7 61 7t61 -6l705 -175q16 -4 22 -10t0.5 -12T1775 1620L1068 1404q-25 -7 -60 -7t-60 7ZM826 154L182 476q-23 11 -39.5 38T126 567v756q0 26 17.5 38.5T186 1366L822 1154q16 -5 30 -18.5T874 1105t8 -34V189q0 -26 -16.5 -36T826 154ZM555 1184l-144 63L205 644L334 587l34 103L598 588L632 456L761 399L555 1184ZM399 806l84 262L567 732L399 806Z"
643></glyph
644><glyph unicode="&#xf20e;" d="M1132 157l697 348q25 13 43 42t18 57v819q0 28 -19 41.5t-46 4.5L1136 1240q-13 -5 -25 -14.5T1090 1204t-14 -26t-5 -28V194q0 -28 18 -39t43 2ZM948 1349L249 1581q-12 4 -18.5 8.5t-6 9.5t7 9.5T250 1616l697 180q25 6 61 6t61 -6l705 -174q25 -7 25.5 -17T1775 1586L1068 1349q-25 -8 -60 -8t-60 8ZM884 157L187 505q-25 13 -43 42t-18 57v819q0 28 19 41.5t46 4.5L880 1240q27 -9 46 -35.5T945 1150V194q0 -28 -18 -39t-43 2ZM598 1172l-143 63L249 631L378 574l34 103L641 576L675 443L804 386L598 1172ZM443 793l84 262L610 720L443 793Z"
645></glyph
646><glyph unicode="&#xf20f;" d="M1103 158l724 362q26 13 44.5 43t18.5 59v851q0 29 -20 43t-47 5L1107 1282q-28 -9 -47.5 -36.5T1040 1189V197q0 -29 18.5 -40.5T1103 158ZM948 1342L249 1565q-25 8 -24.5 18.5T250 1600l697 180q25 6 61 6.5t61 -6.5l705 -174q25 -6 25.5 -16.5T1775 1571L1068 1342q-25 -8 -60 -8t-60 8ZM913 158L189 520q-17 8 -31.5 25t-23 37.5T126 622v851q0 29 20 43t47 5L909 1282q18 -6 33.5 -20.5t24.5 -34t9 -38.5V197q0 -29 -18.5 -40.5T913 158ZM598 1172l-143 63L249 631L378 574l34 103L642 576L675 443L805 386L598 1172ZM443 793l69 215l15 47L610 720L443 793Z"
647></glyph
648><glyph unicode="&#xf210;" d="M136 1000Q136 756 261 549L104 79L587 234Q783 125 1009 125q119 0 232 31.5t208.5 88t176 137.5t137 176.5t88 209T1882 1000q0 72 -11.5 142t-33 135t-53 125.5t-71 114.5T1626 1619t-101.5 87.5t-114.5 71t-125.5 53t-134.5 33T1009 1875q-178 0 -339.5 -69T391 1619.5T205 1340T136 1000ZM609 392L330 303l91 270Q354 665 318 774t-36 226q0 148 58 283t155 232.5T726.5 1671t282.5 58q85 0 166.5 -19t153 -55T1463 1569t112.5 -113.5t85.5 -135T1716 1167t19 -167q0 -148 -57.5 -282.5T1523 485T1291.5 329.5T1009 272q-109 0 -210.5 31T609 392ZM1269 880q-14 7 -27 6.5T1218 871q-19 -27 -74 -85q-19 -20 -48 -4q-1 0 -24.5 12T1030 816t-49.5 33T921 900q-29 27 -56.5 63.5t-40 56.5T803 1059q-5 8 -5.5 15t2.5 12.5t5.5 9t8.5 8.5q4 3 8.5 8t8.5 9.5t9.5 10.5t8.5 10q9 10 24 36q9 18 -1 40q-2 5 -13.5 35.5t-27.5 74T810 1386q-3 8 -6.5 14.5T797 1411t-6.5 7t-6.5 4.5t-6.5 2T772 1425t-5.5 0t-5.5 0q-6 0 -20.5 1.5T718 1428q-33 2 -60 -25q-1 -2 -5 -5q-7 -7 -11.5 -12T628 1370.5t-15 -20T599 1326t-13 -30t-8.5 -35T573 1219q-1 -38 9 -79t27.5 -75.5t27 -50T655 985q1 -1 7 -11t14 -22t21.5 -31t28 -38T760 840.5T800.5 795t47 -45.5t53 -43.5T959 667t64 -33q64 -28 108.5 -45T1202 567t38.5 -5.5t27 2.5t21.5 4q34 1 87 32.5t67 67.5q14 35 18 68.5t-1 37.5q-2 3 -4.5 5t-7 5t-7.5 5t-11 6t-12 7q-123 67 -149 78Z"
649></glyph
650><glyph unicode="&#xf211;" d="M136 1000Q136 756 261 549L104 79L587 234Q783 125 1009 125q119 0 232 31.5t208.5 88t176 137.5t137 176.5t88 209T1882 1000q0 72 -11.5 142t-33 135t-53 125.5t-71 114.5T1626 1619t-101.5 87.5t-114.5 71t-125.5 53t-134.5 33T1009 1875q-178 0 -339.5 -69T391 1619.5T205 1340T136 1000ZM609 392L330 303l91 270Q354 665 318 774t-36 226q0 148 58 283t155 232.5T726.5 1671t282.5 58q85 0 166.5 -19t153 -55T1463 1569t112.5 -113.5t85.5 -135T1716 1167t19 -167q0 -148 -57.5 -282.5T1523 485T1291.5 329.5T1009 272q-109 0 -210.5 31T609 392ZM1269 880q-14 7 -27 6.5T1218 871q-19 -27 -74 -85q-19 -20 -48 -4q-1 0 -24.5 12T1030 816t-49.5 33T921 900q-29 27 -56.5 63.5t-40 56.5T803 1059q-5 8 -5.5 15t2.5 12.5t5.5 9t8.5 8.5q4 3 8.5 8t8.5 9.5t9.5 10.5t8.5 10q9 10 24 36q9 18 -1 40q-2 5 -13.5 35.5t-27.5 74T810 1386q-3 8 -6.5 14.5T797 1411t-6.5 7t-6.5 4.5t-6.5 2T772 1425t-5.5 0t-5.5 0q-6 0 -20.5 1.5T718 1428q-33 2 -60 -25q-1 -2 -5 -5q-7 -7 -11.5 -12T628 1370.5t-15 -20T599 1326t-13 -30t-8.5 -35T573 1219q-1 -38 9 -79t27.5 -75.5t27 -50T655 985q1 -1 7 -11t14 -22t21.5 -31t28 -38T760 840.5T800.5 795t47 -45.5t53 -43.5T959 667t64 -33q64 -28 108.5 -45T1202 567t38.5 -5.5t27 2.5t21.5 4q34 1 87 32.5t67 67.5q14 35 18 68.5t-1 37.5q-2 3 -4.5 5t-7 5t-7.5 5t-11 6t-12 7q-123 67 -149 78Z"
651></glyph
652><glyph unicode="&#xf212;" d="M136 1000Q136 756 261 549L104 79L587 234Q783 125 1009 125q119 0 232 31.5t208.5 88t176 137.5t137 176.5t88 209T1882 1000q0 72 -11.5 142t-33 135t-53 125.5t-71 114.5T1626 1619t-101.5 87.5t-114.5 71t-125.5 53t-134.5 33T1009 1875q-178 0 -339.5 -69T391 1619.5T205 1340T136 1000ZM609 392L330 303l91 270Q354 665 318 774t-36 226q0 148 58 283t155 232.5T726.5 1671t282.5 58q85 0 166.5 -19t153 -55T1463 1569t112.5 -113.5t85.5 -135T1716 1167t19 -167q0 -148 -57.5 -282.5T1523 485T1291.5 329.5T1009 272q-109 0 -210.5 31T609 392ZM1269 880q-14 7 -27 6.5T1218 871q-19 -27 -74 -85q-19 -20 -48 -4q-1 0 -24.5 12T1030 816t-49.5 33T921 900q-29 27 -56.5 63.5t-40 56.5T803 1059q-5 8 -5.5 15t2.5 12.5t5.5 9t8.5 8.5q4 3 8.5 8t8.5 9.5t9.5 10.5t8.5 10q9 10 24 36q9 18 -1 40q-2 5 -13.5 35.5t-27.5 74T810 1386q-3 8 -6.5 14.5T797 1411t-6.5 7t-6.5 4.5t-6.5 2T772 1425t-5.5 0t-5.5 0q-6 0 -20.5 1.5T718 1428q-33 2 -60 -25q-1 -2 -5 -5q-7 -7 -11.5 -12T628 1370.5t-15 -20T599 1326t-13 -30t-8.5 -35T573 1219q-1 -38 9 -79t27.5 -75.5t27 -50T655 985q1 -1 7 -11t14 -22t21.5 -31t28 -38T760 840.5T800.5 795t47 -45.5t53 -43.5T959 667t64 -33q64 -28 108.5 -45T1202 567t38.5 -5.5t27 2.5t21.5 4q34 1 87 32.5t67 67.5q14 35 18 68.5t-1 37.5q-2 3 -4.5 5t-7 5t-7.5 5t-11 6t-12 7q-123 67 -149 78Z"
653></glyph
654><glyph unicode="&#xf213;" d="M1260 1764h126v63q0 78 -55.5 133.5T1197 2016H441q-78 0 -133.5 -55.5T252 1827V567q0 -78 55.5 -133.5T441 378h63V630H378V1764H504h756ZM819 1638q-78 0 -133.5 -55.5T630 1449V189q0 -78 55.5 -133.5T819 0h756q78 0 133.5 55.5T1764 189V1449q0 78 -55.5 133.5T1575 1638H819ZM756 252V1386h882V252H756Z"
655></glyph
656><glyph unicode="&#xf214;" d="M1260 1764h126v63q0 78 -55.5 133.5T1197 2016H441q-78 0 -133.5 -55.5T252 1827V567q0 -78 55.5 -133.5T441 378h63V630H378V1764H504h756ZM819 1638q-78 0 -133.5 -55.5T630 1449V189q0 -78 55.5 -133.5T819 0h756q78 0 133.5 55.5T1764 189V1449q0 78 -55.5 133.5T1575 1638H819ZM756 252V1386h882V252H756Z"
657></glyph
658><glyph unicode="&#xf215;" d="M1260 1764h126v63q0 78 -55.5 133.5T1197 2016H441q-78 0 -133.5 -55.5T252 1827V567q0 -78 55.5 -133.5T441 378h63V630H378V1764H504h756ZM819 1638q-78 0 -133.5 -55.5T630 1449V189q0 -78 55.5 -133.5T819 0h756q78 0 133.5 55.5T1764 189V1449q0 78 -55.5 133.5T1575 1638H819ZM756 252V1386h882V252H756Z"
659></glyph
660><glyph unicode="&#xf216;" d="M1449 543L624 955q3 13 4.5 26.5T630 1008q0 26 -6 53l825 412q35 -41 84 -64t105 -23q104 0 178 74t74 178t-74 178t-178 74t-178 -74t-74 -178q0 -26 6 -53L567 1173q-35 41 -84 64t-105 23q-104 0 -178 -74T126 1008T200 830T378 756q56 0 105 23t84 64L1392 431q-2 -9 -3.5 -17.5t-2 -17.5T1386 378q0 -104 74 -178t178 -74t178 74t74 178t-74 178t-178 74q-56 0 -105 -23t-84 -64Z"
661></glyph
662><glyph unicode="&#xf217;" d="M1449 543L624 955q3 13 4.5 26.5T630 1008q0 26 -6 53l825 412q35 -41 84 -64t105 -23q104 0 178 74t74 178t-74 178t-178 74t-178 -74t-74 -178q0 -26 6 -53L567 1173q-35 41 -84 64t-105 23q-104 0 -178 -74T126 1008T200 830T378 756q56 0 105 23t84 64L1392 431q-2 -9 -3.5 -17.5t-2 -17.5T1386 378q0 -104 74 -178t178 -74t178 74t74 178t-74 178t-178 74q-56 0 -105 -23t-84 -64Z"
663></glyph
664><glyph unicode="&#xf218;" d="M1449 543L624 955q3 13 4.5 26.5T630 1008q0 26 -6 53l825 412q35 -41 84 -64t105 -23q104 0 178 74t74 178t-74 178t-178 74t-178 -74t-74 -178q0 -26 6 -53L567 1173q-35 41 -84 64t-105 23q-104 0 -178 -74T126 1008T200 830T378 756q56 0 105 23t84 64L1392 431q-2 -9 -3.5 -17.5t-2 -17.5T1386 378q0 -104 74 -178t178 -74t178 74t74 178t-74 178t-178 74q-56 0 -105 -23t-84 -64Z"
665></glyph
666><glyph unicode="&#xf219;" d="M1134 1544q0 38 -28 66t-66 28H976q-38 0 -66 -28t-28 -66v-64q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64ZM1134 1040q0 38 -28 66t-66 28H976q-38 0 -66 -28t-28 -66V976q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64ZM1134 536q0 38 -28 66t-66 28H976q-38 0 -66 -28T882 536V472q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64Z"
667></glyph
668><glyph unicode="&#xf21a;" d="M840 1596q0 69 49.5 118.5T1008 1764t118.5 -49.5T1176 1596t-49.5 -118.5T1008 1428t-118.5 49.5T840 1596ZM840 1008q0 69 49.5 118.5T1008 1176t118.5 -49.5T1176 1008T1126.5 889.5T1008 840T889.5 889.5T840 1008ZM840 420q0 69 49.5 118.5T1008 588t118.5 -49.5T1176 420T1126.5 301.5T1008 252T889.5 301.5T840 420Z"
669></glyph
670><glyph unicode="&#xf21b;" d="M1134 1544q0 38 -28 66t-66 28H976q-38 0 -66 -28t-28 -66v-64q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64ZM1134 1040q0 38 -28 66t-66 28H976q-38 0 -66 -28t-28 -66V976q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64ZM1134 536q0 38 -28 66t-66 28H976q-38 0 -66 -28T882 536V472q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64Z"
671></glyph
672><glyph unicode="&#xf21c;" d="M1134 1544q0 38 -28 66t-66 28H976q-38 0 -66 -28t-28 -66v-64q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64ZM1134 1040q0 38 -28 66t-66 28H976q-38 0 -66 -28t-28 -66V976q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64ZM1134 536q0 38 -28 66t-66 28H976q-38 0 -66 -28T882 536V472q0 -38 28 -66t66 -28h64q38 0 66 28t28 66v64Z"
673></glyph
674><glyph unicode="&#xf21d;" d="M824 1282l-5 -22H378q-104 0 -178 -74T126 1008T200 830T378 756H693l-5 -22q-16 -64 4.5 -118T763 532l238 952q-42 -20 -78 -50.5t-62 -70T824 1282ZM1323 1260l5 22q11 44 5 82.5t-27 69t-53 50.5L1015 532q65 30 113 84t64 118l5 22h441q104 0 178 74t74 178t-74 178t-178 74H1323Z"
675></glyph
676><glyph unicode="&#xf21e;" d="M824 1282l-5 -22H378q-104 0 -178 -74T126 1008T200 830T378 756H693l-5 -22q-16 -64 4.5 -118T763 532l238 952q-42 -20 -78 -50.5t-62 -70T824 1282ZM1323 1260l5 22q11 44 5 82.5t-27 69t-53 50.5L1015 532q65 30 113 84t64 118l5 22h441q104 0 178 74t74 178t-74 178t-178 74H1323Z"
677></glyph
678><glyph unicode="&#xf21f;" d="M824 1282l-5 -22H378q-104 0 -178 -74T126 1008T200 830T378 756H693l-5 -22q-16 -64 4.5 -118T763 532l238 952q-42 -20 -78 -50.5t-62 -70T824 1282ZM1323 1260l5 22q11 44 5 82.5t-27 69t-53 50.5L1015 532q65 30 113 84t64 118l5 22h441q104 0 178 74t74 178t-74 178t-178 74H1323Z"
679></glyph
680></font
681></defs
682><g style="font-family: &quot;Spoticon&quot;; font-size:50;fill:black"
683><text x="20" y="50"
684>!&quot;#$%&amp;&#39;()*+,-./0123456789:;&#229;&lt;&gt;?</text
685><text x="20" y="100"
686>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_</text
687><text x="20" y="150"
688>` abcdefghijklmnopqrstuvwxyz|{}~</text
689></g
690></svg
691> \ No newline at end of file
diff --git a/webapp/vendor/underscore-1.7.0.js b/webapp/vendor/underscore-1.7.0.js
new file mode 100644
index 0000000..afd92e5
--- /dev/null
+++ b/webapp/vendor/underscore-1.7.0.js
@@ -0,0 +1,1416 @@
1// Underscore.js 1.7.0
2// http://underscorejs.org
3// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4// Underscore may be freely distributed under the MIT license.
5
6(function() {
7
8 // Baseline setup
9 // --------------
10
11 // Establish the root object, `window` in the browser, or `exports` on the server.
12 var root = this;
13
14 // Save the previous value of the `_` variable.
15 var previousUnderscore = root._;
16
17 // Save bytes in the minified (but not gzipped) version:
18 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
19
20 // Create quick reference variables for speed access to core prototypes.
21 var
22 push = ArrayProto.push,
23 slice = ArrayProto.slice,
24 concat = ArrayProto.concat,
25 toString = ObjProto.toString,
26 hasOwnProperty = ObjProto.hasOwnProperty;
27
28 // All **ECMAScript 5** native function implementations that we hope to use
29 // are declared here.
30 var
31 nativeIsArray = Array.isArray,
32 nativeKeys = Object.keys,
33 nativeBind = FuncProto.bind;
34
35 // Create a safe reference to the Underscore object for use below.
36 var _ = function(obj) {
37 if (obj instanceof _) return obj;
38 if (!(this instanceof _)) return new _(obj);
39 this._wrapped = obj;
40 };
41
42 // Export the Underscore object for **Node.js**, with
43 // backwards-compatibility for the old `require()` API. If we're in
44 // the browser, add `_` as a global object.
45 if (typeof exports !== 'undefined') {
46 if (typeof module !== 'undefined' && module.exports) {
47 exports = module.exports = _;
48 }
49 exports._ = _;
50 } else {
51 root._ = _;
52 }
53
54 // Current version.
55 _.VERSION = '1.7.0';
56
57 // Internal function that returns an efficient (for current engines) version
58 // of the passed-in callback, to be repeatedly applied in other Underscore
59 // functions.
60 var createCallback = function(func, context, argCount) {
61 if (context === void 0) return func;
62 switch (argCount == null ? 3 : argCount) {
63 case 1: return function(value) {
64 return func.call(context, value);
65 };
66 case 2: return function(value, other) {
67 return func.call(context, value, other);
68 };
69 case 3: return function(value, index, collection) {
70 return func.call(context, value, index, collection);
71 };
72 case 4: return function(accumulator, value, index, collection) {
73 return func.call(context, accumulator, value, index, collection);
74 };
75 }
76 return function() {
77 return func.apply(context, arguments);
78 };
79 };
80
81 // A mostly-internal function to generate callbacks that can be applied
82 // to each element in a collection, returning the desired result — either
83 // identity, an arbitrary callback, a property matcher, or a property accessor.
84 _.iteratee = function(value, context, argCount) {
85 if (value == null) return _.identity;
86 if (_.isFunction(value)) return createCallback(value, context, argCount);
87 if (_.isObject(value)) return _.matches(value);
88 return _.property(value);
89 };
90
91 // Collection Functions
92 // --------------------
93
94 // The cornerstone, an `each` implementation, aka `forEach`.
95 // Handles raw objects in addition to array-likes. Treats all
96 // sparse array-likes as if they were dense.
97 _.each = _.forEach = function(obj, iteratee, context) {
98 if (obj == null) return obj;
99 iteratee = createCallback(iteratee, context);
100 var i, length = obj.length;
101 if (length === +length) {
102 for (i = 0; i < length; i++) {
103 iteratee(obj[i], i, obj);
104 }
105 } else {
106 var keys = _.keys(obj);
107 for (i = 0, length = keys.length; i < length; i++) {
108 iteratee(obj[keys[i]], keys[i], obj);
109 }
110 }
111 return obj;
112 };
113
114 // Return the results of applying the iteratee to each element.
115 _.map = _.collect = function(obj, iteratee, context) {
116 if (obj == null) return [];
117 iteratee = _.iteratee(iteratee, context);
118 var keys = obj.length !== +obj.length && _.keys(obj),
119 length = (keys || obj).length,
120 results = Array(length),
121 currentKey;
122 for (var index = 0; index < length; index++) {
123 currentKey = keys ? keys[index] : index;
124 results[index] = iteratee(obj[currentKey], currentKey, obj);
125 }
126 return results;
127 };
128
129 var reduceError = 'Reduce of empty array with no initial value';
130
131 // **Reduce** builds up a single result from a list of values, aka `inject`,
132 // or `foldl`.
133 _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) {
134 if (obj == null) obj = [];
135 iteratee = createCallback(iteratee, context, 4);
136 var keys = obj.length !== +obj.length && _.keys(obj),
137 length = (keys || obj).length,
138 index = 0, currentKey;
139 if (arguments.length < 3) {
140 if (!length) throw new TypeError(reduceError);
141 memo = obj[keys ? keys[index++] : index++];
142 }
143 for (; index < length; index++) {
144 currentKey = keys ? keys[index] : index;
145 memo = iteratee(memo, obj[currentKey], currentKey, obj);
146 }
147 return memo;
148 };
149
150 // The right-associative version of reduce, also known as `foldr`.
151 _.reduceRight = _.foldr = function(obj, iteratee, memo, context) {
152 if (obj == null) obj = [];
153 iteratee = createCallback(iteratee, context, 4);
154 var keys = obj.length !== + obj.length && _.keys(obj),
155 index = (keys || obj).length,
156 currentKey;
157 if (arguments.length < 3) {
158 if (!index) throw new TypeError(reduceError);
159 memo = obj[keys ? keys[--index] : --index];
160 }
161 while (index--) {
162 currentKey = keys ? keys[index] : index;
163 memo = iteratee(memo, obj[currentKey], currentKey, obj);
164 }
165 return memo;
166 };
167
168 // Return the first value which passes a truth test. Aliased as `detect`.
169 _.find = _.detect = function(obj, predicate, context) {
170 var result;
171 predicate = _.iteratee(predicate, context);
172 _.some(obj, function(value, index, list) {
173 if (predicate(value, index, list)) {
174 result = value;
175 return true;
176 }
177 });
178 return result;
179 };
180
181 // Return all the elements that pass a truth test.
182 // Aliased as `select`.
183 _.filter = _.select = function(obj, predicate, context) {
184 var results = [];
185 if (obj == null) return results;
186 predicate = _.iteratee(predicate, context);
187 _.each(obj, function(value, index, list) {
188 if (predicate(value, index, list)) results.push(value);
189 });
190 return results;
191 };
192
193 // Return all the elements for which a truth test fails.
194 _.reject = function(obj, predicate, context) {
195 return _.filter(obj, _.negate(_.iteratee(predicate)), context);
196 };
197
198 // Determine whether all of the elements match a truth test.
199 // Aliased as `all`.
200 _.every = _.all = function(obj, predicate, context) {
201 if (obj == null) return true;
202 predicate = _.iteratee(predicate, context);
203 var keys = obj.length !== +obj.length && _.keys(obj),
204 length = (keys || obj).length,
205 index, currentKey;
206 for (index = 0; index < length; index++) {
207 currentKey = keys ? keys[index] : index;
208 if (!predicate(obj[currentKey], currentKey, obj)) return false;
209 }
210 return true;
211 };
212
213 // Determine if at least one element in the object matches a truth test.
214 // Aliased as `any`.
215 _.some = _.any = function(obj, predicate, context) {
216 if (obj == null) return false;
217 predicate = _.iteratee(predicate, context);
218 var keys = obj.length !== +obj.length && _.keys(obj),
219 length = (keys || obj).length,
220 index, currentKey;
221 for (index = 0; index < length; index++) {
222 currentKey = keys ? keys[index] : index;
223 if (predicate(obj[currentKey], currentKey, obj)) return true;
224 }
225 return false;
226 };
227
228 // Determine if the array or object contains a given value (using `===`).
229 // Aliased as `include`.
230 _.contains = _.include = function(obj, target) {
231 if (obj == null) return false;
232 if (obj.length !== +obj.length) obj = _.values(obj);
233 return _.indexOf(obj, target) >= 0;
234 };
235
236 // Invoke a method (with arguments) on every item in a collection.
237 _.invoke = function(obj, method) {
238 var args = slice.call(arguments, 2);
239 var isFunc = _.isFunction(method);
240 return _.map(obj, function(value) {
241 return (isFunc ? method : value[method]).apply(value, args);
242 });
243 };
244
245 // Convenience version of a common use case of `map`: fetching a property.
246 _.pluck = function(obj, key) {
247 return _.map(obj, _.property(key));
248 };
249
250 // Convenience version of a common use case of `filter`: selecting only objects
251 // containing specific `key:value` pairs.
252 _.where = function(obj, attrs) {
253 return _.filter(obj, _.matches(attrs));
254 };
255
256 // Convenience version of a common use case of `find`: getting the first object
257 // containing specific `key:value` pairs.
258 _.findWhere = function(obj, attrs) {
259 return _.find(obj, _.matches(attrs));
260 };
261
262 // Return the maximum element (or element-based computation).
263 _.max = function(obj, iteratee, context) {
264 var result = -Infinity, lastComputed = -Infinity,
265 value, computed;
266 if (iteratee == null && obj != null) {
267 obj = obj.length === +obj.length ? obj : _.values(obj);
268 for (var i = 0, length = obj.length; i < length; i++) {
269 value = obj[i];
270 if (value > result) {
271 result = value;
272 }
273 }
274 } else {
275 iteratee = _.iteratee(iteratee, context);
276 _.each(obj, function(value, index, list) {
277 computed = iteratee(value, index, list);
278 if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
279 result = value;
280 lastComputed = computed;
281 }
282 });
283 }
284 return result;
285 };
286
287 // Return the minimum element (or element-based computation).
288 _.min = function(obj, iteratee, context) {
289 var result = Infinity, lastComputed = Infinity,
290 value, computed;
291 if (iteratee == null && obj != null) {
292 obj = obj.length === +obj.length ? obj : _.values(obj);
293 for (var i = 0, length = obj.length; i < length; i++) {
294 value = obj[i];
295 if (value < result) {
296 result = value;
297 }
298 }
299 } else {
300 iteratee = _.iteratee(iteratee, context);
301 _.each(obj, function(value, index, list) {
302 computed = iteratee(value, index, list);
303 if (computed < lastComputed || computed === Infinity && result === Infinity) {
304 result = value;
305 lastComputed = computed;
306 }
307 });
308 }
309 return result;
310 };
311
312 // Shuffle a collection, using the modern version of the
313 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
314 _.shuffle = function(obj) {
315 var set = obj && obj.length === +obj.length ? obj : _.values(obj);
316 var length = set.length;
317 var shuffled = Array(length);
318 for (var index = 0, rand; index < length; index++) {
319 rand = _.random(0, index);
320 if (rand !== index) shuffled[index] = shuffled[rand];
321 shuffled[rand] = set[index];
322 }
323 return shuffled;
324 };
325
326 // Sample **n** random values from a collection.
327 // If **n** is not specified, returns a single random element.
328 // The internal `guard` argument allows it to work with `map`.
329 _.sample = function(obj, n, guard) {
330 if (n == null || guard) {
331 if (obj.length !== +obj.length) obj = _.values(obj);
332 return obj[_.random(obj.length - 1)];
333 }
334 return _.shuffle(obj).slice(0, Math.max(0, n));
335 };
336
337 // Sort the object's values by a criterion produced by an iteratee.
338 _.sortBy = function(obj, iteratee, context) {
339 iteratee = _.iteratee(iteratee, context);
340 return _.pluck(_.map(obj, function(value, index, list) {
341 return {
342 value: value,
343 index: index,
344 criteria: iteratee(value, index, list)
345 };
346 }).sort(function(left, right) {
347 var a = left.criteria;
348 var b = right.criteria;
349 if (a !== b) {
350 if (a > b || a === void 0) return 1;
351 if (a < b || b === void 0) return -1;
352 }
353 return left.index - right.index;
354 }), 'value');
355 };
356
357 // An internal function used for aggregate "group by" operations.
358 var group = function(behavior) {
359 return function(obj, iteratee, context) {
360 var result = {};
361 iteratee = _.iteratee(iteratee, context);
362 _.each(obj, function(value, index) {
363 var key = iteratee(value, index, obj);
364 behavior(result, value, key);
365 });
366 return result;
367 };
368 };
369
370 // Groups the object's values by a criterion. Pass either a string attribute
371 // to group by, or a function that returns the criterion.
372 _.groupBy = group(function(result, value, key) {
373 if (_.has(result, key)) result[key].push(value); else result[key] = [value];
374 });
375
376 // Indexes the object's values by a criterion, similar to `groupBy`, but for
377 // when you know that your index values will be unique.
378 _.indexBy = group(function(result, value, key) {
379 result[key] = value;
380 });
381
382 // Counts instances of an object that group by a certain criterion. Pass
383 // either a string attribute to count by, or a function that returns the
384 // criterion.
385 _.countBy = group(function(result, value, key) {
386 if (_.has(result, key)) result[key]++; else result[key] = 1;
387 });
388
389 // Use a comparator function to figure out the smallest index at which
390 // an object should be inserted so as to maintain order. Uses binary search.
391 _.sortedIndex = function(array, obj, iteratee, context) {
392 iteratee = _.iteratee(iteratee, context, 1);
393 var value = iteratee(obj);
394 var low = 0, high = array.length;
395 while (low < high) {
396 var mid = low + high >>> 1;
397 if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
398 }
399 return low;
400 };
401
402 // Safely create a real, live array from anything iterable.
403 _.toArray = function(obj) {
404 if (!obj) return [];
405 if (_.isArray(obj)) return slice.call(obj);
406 if (obj.length === +obj.length) return _.map(obj, _.identity);
407 return _.values(obj);
408 };
409
410 // Return the number of elements in an object.
411 _.size = function(obj) {
412 if (obj == null) return 0;
413 return obj.length === +obj.length ? obj.length : _.keys(obj).length;
414 };
415
416 // Split a collection into two arrays: one whose elements all satisfy the given
417 // predicate, and one whose elements all do not satisfy the predicate.
418 _.partition = function(obj, predicate, context) {
419 predicate = _.iteratee(predicate, context);
420 var pass = [], fail = [];
421 _.each(obj, function(value, key, obj) {
422 (predicate(value, key, obj) ? pass : fail).push(value);
423 });
424 return [pass, fail];
425 };
426
427 // Array Functions
428 // ---------------
429
430 // Get the first element of an array. Passing **n** will return the first N
431 // values in the array. Aliased as `head` and `take`. The **guard** check
432 // allows it to work with `_.map`.
433 _.first = _.head = _.take = function(array, n, guard) {
434 if (array == null) return void 0;
435 if (n == null || guard) return array[0];
436 if (n < 0) return [];
437 return slice.call(array, 0, n);
438 };
439
440 // Returns everything but the last entry of the array. Especially useful on
441 // the arguments object. Passing **n** will return all the values in
442 // the array, excluding the last N. The **guard** check allows it to work with
443 // `_.map`.
444 _.initial = function(array, n, guard) {
445 return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
446 };
447
448 // Get the last element of an array. Passing **n** will return the last N
449 // values in the array. The **guard** check allows it to work with `_.map`.
450 _.last = function(array, n, guard) {
451 if (array == null) return void 0;
452 if (n == null || guard) return array[array.length - 1];
453 return slice.call(array, Math.max(array.length - n, 0));
454 };
455
456 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
457 // Especially useful on the arguments object. Passing an **n** will return
458 // the rest N values in the array. The **guard**
459 // check allows it to work with `_.map`.
460 _.rest = _.tail = _.drop = function(array, n, guard) {
461 return slice.call(array, n == null || guard ? 1 : n);
462 };
463
464 // Trim out all falsy values from an array.
465 _.compact = function(array) {
466 return _.filter(array, _.identity);
467 };
468
469 // Internal implementation of a recursive `flatten` function.
470 var flatten = function(input, shallow, strict, output) {
471 if (shallow && _.every(input, _.isArray)) {
472 return concat.apply(output, input);
473 }
474 for (var i = 0, length = input.length; i < length; i++) {
475 var value = input[i];
476 if (!_.isArray(value) && !_.isArguments(value)) {
477 if (!strict) output.push(value);
478 } else if (shallow) {
479 push.apply(output, value);
480 } else {
481 flatten(value, shallow, strict, output);
482 }
483 }
484 return output;
485 };
486
487 // Flatten out an array, either recursively (by default), or just one level.
488 _.flatten = function(array, shallow) {
489 return flatten(array, shallow, false, []);
490 };
491
492 // Return a version of the array that does not contain the specified value(s).
493 _.without = function(array) {
494 return _.difference(array, slice.call(arguments, 1));
495 };
496
497 // Produce a duplicate-free version of the array. If the array has already
498 // been sorted, you have the option of using a faster algorithm.
499 // Aliased as `unique`.
500 _.uniq = _.unique = function(array, isSorted, iteratee, context) {
501 if (array == null) return [];
502 if (!_.isBoolean(isSorted)) {
503 context = iteratee;
504 iteratee = isSorted;
505 isSorted = false;
506 }
507 if (iteratee != null) iteratee = _.iteratee(iteratee, context);
508 var result = [];
509 var seen = [];
510 for (var i = 0, length = array.length; i < length; i++) {
511 var value = array[i];
512 if (isSorted) {
513 if (!i || seen !== value) result.push(value);
514 seen = value;
515 } else if (iteratee) {
516 var computed = iteratee(value, i, array);
517 if (_.indexOf(seen, computed) < 0) {
518 seen.push(computed);
519 result.push(value);
520 }
521 } else if (_.indexOf(result, value) < 0) {
522 result.push(value);
523 }
524 }
525 return result;
526 };
527
528 // Produce an array that contains the union: each distinct element from all of
529 // the passed-in arrays.
530 _.union = function() {
531 return _.uniq(flatten(arguments, true, true, []));
532 };
533
534 // Produce an array that contains every item shared between all the
535 // passed-in arrays.
536 _.intersection = function(array) {
537 if (array == null) return [];
538 var result = [];
539 var argsLength = arguments.length;
540 for (var i = 0, length = array.length; i < length; i++) {
541 var item = array[i];
542 if (_.contains(result, item)) continue;
543 for (var j = 1; j < argsLength; j++) {
544 if (!_.contains(arguments[j], item)) break;
545 }
546 if (j === argsLength) result.push(item);
547 }
548 return result;
549 };
550
551 // Take the difference between one array and a number of other arrays.
552 // Only the elements present in just the first array will remain.
553 _.difference = function(array) {
554 var rest = flatten(slice.call(arguments, 1), true, true, []);
555 return _.filter(array, function(value){
556 return !_.contains(rest, value);
557 });
558 };
559
560 // Zip together multiple lists into a single array -- elements that share
561 // an index go together.
562 _.zip = function(array) {
563 if (array == null) return [];
564 var length = _.max(arguments, 'length').length;
565 var results = Array(length);
566 for (var i = 0; i < length; i++) {
567 results[i] = _.pluck(arguments, i);
568 }
569 return results;
570 };
571
572 // Converts lists into objects. Pass either a single array of `[key, value]`
573 // pairs, or two parallel arrays of the same length -- one of keys, and one of
574 // the corresponding values.
575 _.object = function(list, values) {
576 if (list == null) return {};
577 var result = {};
578 for (var i = 0, length = list.length; i < length; i++) {
579 if (values) {
580 result[list[i]] = values[i];
581 } else {
582 result[list[i][0]] = list[i][1];
583 }
584 }
585 return result;
586 };
587
588 // Return the position of the first occurrence of an item in an array,
589 // or -1 if the item is not included in the array.
590 // If the array is large and already in sort order, pass `true`
591 // for **isSorted** to use binary search.
592 _.indexOf = function(array, item, isSorted) {
593 if (array == null) return -1;
594 var i = 0, length = array.length;
595 if (isSorted) {
596 if (typeof isSorted == 'number') {
597 i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
598 } else {
599 i = _.sortedIndex(array, item);
600 return array[i] === item ? i : -1;
601 }
602 }
603 for (; i < length; i++) if (array[i] === item) return i;
604 return -1;
605 };
606
607 _.lastIndexOf = function(array, item, from) {
608 if (array == null) return -1;
609 var idx = array.length;
610 if (typeof from == 'number') {
611 idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
612 }
613 while (--idx >= 0) if (array[idx] === item) return idx;
614 return -1;
615 };
616
617 // Generate an integer Array containing an arithmetic progression. A port of
618 // the native Python `range()` function. See
619 // [the Python documentation](http://docs.python.org/library/functions.html#range).
620 _.range = function(start, stop, step) {
621 if (arguments.length <= 1) {
622 stop = start || 0;
623 start = 0;
624 }
625 step = step || 1;
626
627 var length = Math.max(Math.ceil((stop - start) / step), 0);
628 var range = Array(length);
629
630 for (var idx = 0; idx < length; idx++, start += step) {
631 range[idx] = start;
632 }
633
634 return range;
635 };
636
637 // Function (ahem) Functions
638 // ------------------
639
640 // Reusable constructor function for prototype setting.
641 var Ctor = function(){};
642
643 // Create a function bound to a given object (assigning `this`, and arguments,
644 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
645 // available.
646 _.bind = function(func, context) {
647 var args, bound;
648 if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
649 if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
650 args = slice.call(arguments, 2);
651 bound = function() {
652 if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
653 Ctor.prototype = func.prototype;
654 var self = new Ctor;
655 Ctor.prototype = null;
656 var result = func.apply(self, args.concat(slice.call(arguments)));
657 if (_.isObject(result)) return result;
658 return self;
659 };
660 return bound;
661 };
662
663 // Partially apply a function by creating a version that has had some of its
664 // arguments pre-filled, without changing its dynamic `this` context. _ acts
665 // as a placeholder, allowing any combination of arguments to be pre-filled.
666 _.partial = function(func) {
667 var boundArgs = slice.call(arguments, 1);
668 return function() {
669 var position = 0;
670 var args = boundArgs.slice();
671 for (var i = 0, length = args.length; i < length; i++) {
672 if (args[i] === _) args[i] = arguments[position++];
673 }
674 while (position < arguments.length) args.push(arguments[position++]);
675 return func.apply(this, args);
676 };
677 };
678
679 // Bind a number of an object's methods to that object. Remaining arguments
680 // are the method names to be bound. Useful for ensuring that all callbacks
681 // defined on an object belong to it.
682 _.bindAll = function(obj) {
683 var i, length = arguments.length, key;
684 if (length <= 1) throw new Error('bindAll must be passed function names');
685 for (i = 1; i < length; i++) {
686 key = arguments[i];
687 obj[key] = _.bind(obj[key], obj);
688 }
689 return obj;
690 };
691
692 // Memoize an expensive function by storing its results.
693 _.memoize = function(func, hasher) {
694 var memoize = function(key) {
695 var cache = memoize.cache;
696 var address = hasher ? hasher.apply(this, arguments) : key;
697 if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
698 return cache[address];
699 };
700 memoize.cache = {};
701 return memoize;
702 };
703
704 // Delays a function for the given number of milliseconds, and then calls
705 // it with the arguments supplied.
706 _.delay = function(func, wait) {
707 var args = slice.call(arguments, 2);
708 return setTimeout(function(){
709 return func.apply(null, args);
710 }, wait);
711 };
712
713 // Defers a function, scheduling it to run after the current call stack has
714 // cleared.
715 _.defer = function(func) {
716 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
717 };
718
719 // Returns a function, that, when invoked, will only be triggered at most once
720 // during a given window of time. Normally, the throttled function will run
721 // as much as it can, without ever going more than once per `wait` duration;
722 // but if you'd like to disable the execution on the leading edge, pass
723 // `{leading: false}`. To disable execution on the trailing edge, ditto.
724 _.throttle = function(func, wait, options) {
725 var context, args, result;
726 var timeout = null;
727 var previous = 0;
728 if (!options) options = {};
729 var later = function() {
730 previous = options.leading === false ? 0 : _.now();
731 timeout = null;
732 result = func.apply(context, args);
733 if (!timeout) context = args = null;
734 };
735 return function() {
736 var now = _.now();
737 if (!previous && options.leading === false) previous = now;
738 var remaining = wait - (now - previous);
739 context = this;
740 args = arguments;
741 if (remaining <= 0 || remaining > wait) {
742 clearTimeout(timeout);
743 timeout = null;
744 previous = now;
745 result = func.apply(context, args);
746 if (!timeout) context = args = null;
747 } else if (!timeout && options.trailing !== false) {
748 timeout = setTimeout(later, remaining);
749 }
750 return result;
751 };
752 };
753
754 // Returns a function, that, as long as it continues to be invoked, will not
755 // be triggered. The function will be called after it stops being called for
756 // N milliseconds. If `immediate` is passed, trigger the function on the
757 // leading edge, instead of the trailing.
758 _.debounce = function(func, wait, immediate) {
759 var timeout, args, context, timestamp, result;
760
761 var later = function() {
762 var last = _.now() - timestamp;
763
764 if (last < wait && last > 0) {
765 timeout = setTimeout(later, wait - last);
766 } else {
767 timeout = null;
768 if (!immediate) {
769 result = func.apply(context, args);
770 if (!timeout) context = args = null;
771 }
772 }
773 };
774
775 return function() {
776 context = this;
777 args = arguments;
778 timestamp = _.now();
779 var callNow = immediate && !timeout;
780 if (!timeout) timeout = setTimeout(later, wait);
781 if (callNow) {
782 result = func.apply(context, args);
783 context = args = null;
784 }
785
786 return result;
787 };
788 };
789
790 // Returns the first function passed as an argument to the second,
791 // allowing you to adjust arguments, run code before and after, and
792 // conditionally execute the original function.
793 _.wrap = function(func, wrapper) {
794 return _.partial(wrapper, func);
795 };
796
797 // Returns a negated version of the passed-in predicate.
798 _.negate = function(predicate) {
799 return function() {
800 return !predicate.apply(this, arguments);
801 };
802 };
803
804 // Returns a function that is the composition of a list of functions, each
805 // consuming the return value of the function that follows.
806 _.compose = function() {
807 var args = arguments;
808 var start = args.length - 1;
809 return function() {
810 var i = start;
811 var result = args[start].apply(this, arguments);
812 while (i--) result = args[i].call(this, result);
813 return result;
814 };
815 };
816
817 // Returns a function that will only be executed after being called N times.
818 _.after = function(times, func) {
819 return function() {
820 if (--times < 1) {
821 return func.apply(this, arguments);
822 }
823 };
824 };
825
826 // Returns a function that will only be executed before being called N times.
827 _.before = function(times, func) {
828 var memo;
829 return function() {
830 if (--times > 0) {
831 memo = func.apply(this, arguments);
832 } else {
833 func = null;
834 }
835 return memo;
836 };
837 };
838
839 // Returns a function that will be executed at most one time, no matter how
840 // often you call it. Useful for lazy initialization.
841 _.once = _.partial(_.before, 2);
842
843 // Object Functions
844 // ----------------
845
846 // Retrieve the names of an object's properties.
847 // Delegates to **ECMAScript 5**'s native `Object.keys`
848 _.keys = function(obj) {
849 if (!_.isObject(obj)) return [];
850 if (nativeKeys) return nativeKeys(obj);
851 var keys = [];
852 for (var key in obj) if (_.has(obj, key)) keys.push(key);
853 return keys;
854 };
855
856 // Retrieve the values of an object's properties.
857 _.values = function(obj) {
858 var keys = _.keys(obj);
859 var length = keys.length;
860 var values = Array(length);
861 for (var i = 0; i < length; i++) {
862 values[i] = obj[keys[i]];
863 }
864 return values;
865 };
866
867 // Convert an object into a list of `[key, value]` pairs.
868 _.pairs = function(obj) {
869 var keys = _.keys(obj);
870 var length = keys.length;
871 var pairs = Array(length);
872 for (var i = 0; i < length; i++) {
873 pairs[i] = [keys[i], obj[keys[i]]];
874 }
875 return pairs;
876 };
877
878 // Invert the keys and values of an object. The values must be serializable.
879 _.invert = function(obj) {
880 var result = {};
881 var keys = _.keys(obj);
882 for (var i = 0, length = keys.length; i < length; i++) {
883 result[obj[keys[i]]] = keys[i];
884 }
885 return result;
886 };
887
888 // Return a sorted list of the function names available on the object.
889 // Aliased as `methods`
890 _.functions = _.methods = function(obj) {
891 var names = [];
892 for (var key in obj) {
893 if (_.isFunction(obj[key])) names.push(key);
894 }
895 return names.sort();
896 };
897
898 // Extend a given object with all the properties in passed-in object(s).
899 _.extend = function(obj) {
900 if (!_.isObject(obj)) return obj;
901 var source, prop;
902 for (var i = 1, length = arguments.length; i < length; i++) {
903 source = arguments[i];
904 for (prop in source) {
905 if (hasOwnProperty.call(source, prop)) {
906 obj[prop] = source[prop];
907 }
908 }
909 }
910 return obj;
911 };
912
913 // Return a copy of the object only containing the whitelisted properties.
914 _.pick = function(obj, iteratee, context) {
915 var result = {}, key;
916 if (obj == null) return result;
917 if (_.isFunction(iteratee)) {
918 iteratee = createCallback(iteratee, context);
919 for (key in obj) {
920 var value = obj[key];
921 if (iteratee(value, key, obj)) result[key] = value;
922 }
923 } else {
924 var keys = concat.apply([], slice.call(arguments, 1));
925 obj = new Object(obj);
926 for (var i = 0, length = keys.length; i < length; i++) {
927 key = keys[i];
928 if (key in obj) result[key] = obj[key];
929 }
930 }
931 return result;
932 };
933
934 // Return a copy of the object without the blacklisted properties.
935 _.omit = function(obj, iteratee, context) {
936 if (_.isFunction(iteratee)) {
937 iteratee = _.negate(iteratee);
938 } else {
939 var keys = _.map(concat.apply([], slice.call(arguments, 1)), String);
940 iteratee = function(value, key) {
941 return !_.contains(keys, key);
942 };
943 }
944 return _.pick(obj, iteratee, context);
945 };
946
947 // Fill in a given object with default properties.
948 _.defaults = function(obj) {
949 if (!_.isObject(obj)) return obj;
950 for (var i = 1, length = arguments.length; i < length; i++) {
951 var source = arguments[i];
952 for (var prop in source) {
953 if (obj[prop] === void 0) obj[prop] = source[prop];
954 }
955 }
956 return obj;
957 };
958
959 // Create a (shallow-cloned) duplicate of an object.
960 _.clone = function(obj) {
961 if (!_.isObject(obj)) return obj;
962 return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
963 };
964
965 // Invokes interceptor with the obj, and then returns obj.
966 // The primary purpose of this method is to "tap into" a method chain, in
967 // order to perform operations on intermediate results within the chain.
968 _.tap = function(obj, interceptor) {
969 interceptor(obj);
970 return obj;
971 };
972
973 // Internal recursive comparison function for `isEqual`.
974 var eq = function(a, b, aStack, bStack) {
975 // Identical objects are equal. `0 === -0`, but they aren't identical.
976 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
977 if (a === b) return a !== 0 || 1 / a === 1 / b;
978 // A strict comparison is necessary because `null == undefined`.
979 if (a == null || b == null) return a === b;
980 // Unwrap any wrapped objects.
981 if (a instanceof _) a = a._wrapped;
982 if (b instanceof _) b = b._wrapped;
983 // Compare `[[Class]]` names.
984 var className = toString.call(a);
985 if (className !== toString.call(b)) return false;
986 switch (className) {
987 // Strings, numbers, regular expressions, dates, and booleans are compared by value.
988 case '[object RegExp]':
989 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
990 case '[object String]':
991 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
992 // equivalent to `new String("5")`.
993 return '' + a === '' + b;
994 case '[object Number]':
995 // `NaN`s are equivalent, but non-reflexive.
996 // Object(NaN) is equivalent to NaN
997 if (+a !== +a) return +b !== +b;
998 // An `egal` comparison is performed for other numeric values.
999 return +a === 0 ? 1 / +a === 1 / b : +a === +b;
1000 case '[object Date]':
1001 case '[object Boolean]':
1002 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1003 // millisecond representations. Note that invalid dates with millisecond representations
1004 // of `NaN` are not equivalent.
1005 return +a === +b;
1006 }
1007 if (typeof a != 'object' || typeof b != 'object') return false;
1008 // Assume equality for cyclic structures. The algorithm for detecting cyclic
1009 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1010 var length = aStack.length;
1011 while (length--) {
1012 // Linear search. Performance is inversely proportional to the number of
1013 // unique nested structures.
1014 if (aStack[length] === a) return bStack[length] === b;
1015 }
1016 // Objects with different constructors are not equivalent, but `Object`s
1017 // from different frames are.
1018 var aCtor = a.constructor, bCtor = b.constructor;
1019 if (
1020 aCtor !== bCtor &&
1021 // Handle Object.create(x) cases
1022 'constructor' in a && 'constructor' in b &&
1023 !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
1024 _.isFunction(bCtor) && bCtor instanceof bCtor)
1025 ) {
1026 return false;
1027 }
1028 // Add the first object to the stack of traversed objects.
1029 aStack.push(a);
1030 bStack.push(b);
1031 var size, result;
1032 // Recursively compare objects and arrays.
1033 if (className === '[object Array]') {
1034 // Compare array lengths to determine if a deep comparison is necessary.
1035 size = a.length;
1036 result = size === b.length;
1037 if (result) {
1038 // Deep compare the contents, ignoring non-numeric properties.
1039 while (size--) {
1040 if (!(result = eq(a[size], b[size], aStack, bStack))) break;
1041 }
1042 }
1043 } else {
1044 // Deep compare objects.
1045 var keys = _.keys(a), key;
1046 size = keys.length;
1047 // Ensure that both objects contain the same number of properties before comparing deep equality.
1048 result = _.keys(b).length === size;
1049 if (result) {
1050 while (size--) {
1051 // Deep compare each member
1052 key = keys[size];
1053 if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
1054 }
1055 }
1056 }
1057 // Remove the first object from the stack of traversed objects.
1058 aStack.pop();
1059 bStack.pop();
1060 return result;
1061 };
1062
1063 // Perform a deep comparison to check if two objects are equal.
1064 _.isEqual = function(a, b) {
1065 return eq(a, b, [], []);
1066 };
1067
1068 // Is a given array, string, or object empty?
1069 // An "empty" object has no enumerable own-properties.
1070 _.isEmpty = function(obj) {
1071 if (obj == null) return true;
1072 if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
1073 for (var key in obj) if (_.has(obj, key)) return false;
1074 return true;
1075 };
1076
1077 // Is a given value a DOM element?
1078 _.isElement = function(obj) {
1079 return !!(obj && obj.nodeType === 1);
1080 };
1081
1082 // Is a given value an array?
1083 // Delegates to ECMA5's native Array.isArray
1084 _.isArray = nativeIsArray || function(obj) {
1085 return toString.call(obj) === '[object Array]';
1086 };
1087
1088 // Is a given variable an object?
1089 _.isObject = function(obj) {
1090 var type = typeof obj;
1091 return type === 'function' || type === 'object' && !!obj;
1092 };
1093
1094 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
1095 _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
1096 _['is' + name] = function(obj) {
1097 return toString.call(obj) === '[object ' + name + ']';
1098 };
1099 });
1100
1101 // Define a fallback version of the method in browsers (ahem, IE), where
1102 // there isn't any inspectable "Arguments" type.
1103 if (!_.isArguments(arguments)) {
1104 _.isArguments = function(obj) {
1105 return _.has(obj, 'callee');
1106 };
1107 }
1108
1109 // Optimize `isFunction` if appropriate. Work around an IE 11 bug.
1110 if (typeof /./ !== 'function') {
1111 _.isFunction = function(obj) {
1112 return typeof obj == 'function' || false;
1113 };
1114 }
1115
1116 // Is a given object a finite number?
1117 _.isFinite = function(obj) {
1118 return isFinite(obj) && !isNaN(parseFloat(obj));
1119 };
1120
1121 // Is the given value `NaN`? (NaN is the only number which does not equal itself).
1122 _.isNaN = function(obj) {
1123 return _.isNumber(obj) && obj !== +obj;
1124 };
1125
1126 // Is a given value a boolean?
1127 _.isBoolean = function(obj) {
1128 return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
1129 };
1130
1131 // Is a given value equal to null?
1132 _.isNull = function(obj) {
1133 return obj === null;
1134 };
1135
1136 // Is a given variable undefined?
1137 _.isUndefined = function(obj) {
1138 return obj === void 0;
1139 };
1140
1141 // Shortcut function for checking if an object has a given property directly
1142 // on itself (in other words, not on a prototype).
1143 _.has = function(obj, key) {
1144 return obj != null && hasOwnProperty.call(obj, key);
1145 };
1146
1147 // Utility Functions
1148 // -----------------
1149
1150 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1151 // previous owner. Returns a reference to the Underscore object.
1152 _.noConflict = function() {
1153 root._ = previousUnderscore;
1154 return this;
1155 };
1156
1157 // Keep the identity function around for default iteratees.
1158 _.identity = function(value) {
1159 return value;
1160 };
1161
1162 // Predicate-generating functions. Often useful outside of Underscore.
1163 _.constant = function(value) {
1164 return function() {
1165 return value;
1166 };
1167 };
1168
1169 _.noop = function(){};
1170
1171 _.property = function(key) {
1172 return function(obj) {
1173 return obj[key];
1174 };
1175 };
1176
1177 // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
1178 _.matches = function(attrs) {
1179 var pairs = _.pairs(attrs), length = pairs.length;
1180 return function(obj) {
1181 if (obj == null) return !length;
1182 obj = new Object(obj);
1183 for (var i = 0; i < length; i++) {
1184 var pair = pairs[i], key = pair[0];
1185 if (pair[1] !== obj[key] || !(key in obj)) return false;
1186 }
1187 return true;
1188 };
1189 };
1190
1191 // Run a function **n** times.
1192 _.times = function(n, iteratee, context) {
1193 var accum = Array(Math.max(0, n));
1194 iteratee = createCallback(iteratee, context, 1);
1195 for (var i = 0; i < n; i++) accum[i] = iteratee(i);
1196 return accum;
1197 };
1198
1199 // Return a random integer between min and max (inclusive).
1200 _.random = function(min, max) {
1201 if (max == null) {
1202 max = min;
1203 min = 0;
1204 }
1205 return min + Math.floor(Math.random() * (max - min + 1));
1206 };
1207
1208 // A (possibly faster) way to get the current timestamp as an integer.
1209 _.now = Date.now || function() {
1210 return new Date().getTime();
1211 };
1212
1213 // List of HTML entities for escaping.
1214 var escapeMap = {
1215 '&': '&amp;',
1216 '<': '&lt;',
1217 '>': '&gt;',
1218 '"': '&quot;',
1219 "'": '&#x27;',
1220 '`': '&#x60;'
1221 };
1222 var unescapeMap = _.invert(escapeMap);
1223
1224 // Functions for escaping and unescaping strings to/from HTML interpolation.
1225 var createEscaper = function(map) {
1226 var escaper = function(match) {
1227 return map[match];
1228 };
1229 // Regexes for identifying a key that needs to be escaped
1230 var source = '(?:' + _.keys(map).join('|') + ')';
1231 var testRegexp = RegExp(source);
1232 var replaceRegexp = RegExp(source, 'g');
1233 return function(string) {
1234 string = string == null ? '' : '' + string;
1235 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
1236 };
1237 };
1238 _.escape = createEscaper(escapeMap);
1239 _.unescape = createEscaper(unescapeMap);
1240
1241 // If the value of the named `property` is a function then invoke it with the
1242 // `object` as context; otherwise, return it.
1243 _.result = function(object, property) {
1244 if (object == null) return void 0;
1245 var value = object[property];
1246 return _.isFunction(value) ? object[property]() : value;
1247 };
1248
1249 // Generate a unique integer id (unique within the entire client session).
1250 // Useful for temporary DOM ids.
1251 var idCounter = 0;
1252 _.uniqueId = function(prefix) {
1253 var id = ++idCounter + '';
1254 return prefix ? prefix + id : id;
1255 };
1256
1257 // By default, Underscore uses ERB-style template delimiters, change the
1258 // following template settings to use alternative delimiters.
1259 _.templateSettings = {
1260 evaluate : /<%([\s\S]+?)%>/g,
1261 interpolate : /<%=([\s\S]+?)%>/g,
1262 escape : /<%-([\s\S]+?)%>/g
1263 };
1264
1265 // When customizing `templateSettings`, if you don't want to define an
1266 // interpolation, evaluation or escaping regex, we need one that is
1267 // guaranteed not to match.
1268 var noMatch = /(.)^/;
1269
1270 // Certain characters need to be escaped so that they can be put into a
1271 // string literal.
1272 var escapes = {
1273 "'": "'",
1274 '\\': '\\',
1275 '\r': 'r',
1276 '\n': 'n',
1277 '\u2028': 'u2028',
1278 '\u2029': 'u2029'
1279 };
1280
1281 var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
1282
1283 var escapeChar = function(match) {
1284 return '\\' + escapes[match];
1285 };
1286
1287 // JavaScript micro-templating, similar to John Resig's implementation.
1288 // Underscore templating handles arbitrary delimiters, preserves whitespace,
1289 // and correctly escapes quotes within interpolated code.
1290 // NB: `oldSettings` only exists for backwards compatibility.
1291 _.template = function(text, settings, oldSettings) {
1292 if (!settings && oldSettings) settings = oldSettings;
1293 settings = _.defaults({}, settings, _.templateSettings);
1294
1295 // Combine delimiters into one regular expression via alternation.
1296 var matcher = RegExp([
1297 (settings.escape || noMatch).source,
1298 (settings.interpolate || noMatch).source,
1299 (settings.evaluate || noMatch).source
1300 ].join('|') + '|$', 'g');
1301
1302 // Compile the template source, escaping string literals appropriately.
1303 var index = 0;
1304 var source = "__p+='";
1305 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1306 source += text.slice(index, offset).replace(escaper, escapeChar);
1307 index = offset + match.length;
1308
1309 if (escape) {
1310 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1311 } else if (interpolate) {
1312 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1313 } else if (evaluate) {
1314 source += "';\n" + evaluate + "\n__p+='";
1315 }
1316
1317 // Adobe VMs need the match returned to produce the correct offest.
1318 return match;
1319 });
1320 source += "';\n";
1321
1322 // If a variable is not specified, place data values in local scope.
1323 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1324
1325 source = "var __t,__p='',__j=Array.prototype.join," +
1326 "print=function(){__p+=__j.call(arguments,'');};\n" +
1327 source + 'return __p;\n';
1328
1329 try {
1330 var render = new Function(settings.variable || 'obj', '_', source);
1331 } catch (e) {
1332 e.source = source;
1333 throw e;
1334 }
1335
1336 var template = function(data) {
1337 return render.call(this, data, _);
1338 };
1339
1340 // Provide the compiled source as a convenience for precompilation.
1341 var argument = settings.variable || 'obj';
1342 template.source = 'function(' + argument + '){\n' + source + '}';
1343
1344 return template;
1345 };
1346
1347 // Add a "chain" function. Start chaining a wrapped Underscore object.
1348 _.chain = function(obj) {
1349 var instance = _(obj);
1350 instance._chain = true;
1351 return instance;
1352 };
1353
1354 // OOP
1355 // ---------------
1356 // If Underscore is called as a function, it returns a wrapped object that
1357 // can be used OO-style. This wrapper holds altered versions of all the
1358 // underscore functions. Wrapped objects may be chained.
1359
1360 // Helper function to continue chaining intermediate results.
1361 var result = function(obj) {
1362 return this._chain ? _(obj).chain() : obj;
1363 };
1364
1365 // Add your own custom functions to the Underscore object.
1366 _.mixin = function(obj) {
1367 _.each(_.functions(obj), function(name) {
1368 var func = _[name] = obj[name];
1369 _.prototype[name] = function() {
1370 var args = [this._wrapped];
1371 push.apply(args, arguments);
1372 return result.call(this, func.apply(_, args));
1373 };
1374 });
1375 };
1376
1377 // Add all of the Underscore functions to the wrapper object.
1378 _.mixin(_);
1379
1380 // Add all mutator Array functions to the wrapper.
1381 _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1382 var method = ArrayProto[name];
1383 _.prototype[name] = function() {
1384 var obj = this._wrapped;
1385 method.apply(obj, arguments);
1386 if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
1387 return result.call(this, obj);
1388 };
1389 });
1390
1391 // Add all accessor Array functions to the wrapper.
1392 _.each(['concat', 'join', 'slice'], function(name) {
1393 var method = ArrayProto[name];
1394 _.prototype[name] = function() {
1395 return result.call(this, method.apply(this._wrapped, arguments));
1396 };
1397 });
1398
1399 // Extracts the result from a wrapped and chained object.
1400 _.prototype.value = function() {
1401 return this._wrapped;
1402 };
1403
1404 // AMD registration happens at the end for compatibility with AMD loaders
1405 // that may not enforce next-turn semantics on modules. Even though general
1406 // practice for AMD registration is to be anonymous, underscore registers
1407 // as a named module because, like jQuery, it is a base library that is
1408 // popular enough to be bundled in a third party lib, but not be part of
1409 // an AMD load request. Those cases could generate an error when an
1410 // anonymous define() is called outside of a loader request.
1411 if (typeof define === 'function' && define.amd) {
1412 define('underscore', [], function() {
1413 return _;
1414 });
1415 }
1416}.call(this));