summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--Gruntfile.js339
-rw-r--r--Procfile3
-rw-r--r--README.md17
-rw-r--r--bower.json5
-rw-r--r--config.json.example14
-rw-r--r--package.json57
-rwxr-xr-xpublic/assets/fonts/ionicons.eotbin124752 -> 120724 bytes
-rwxr-xr-xpublic/assets/fonts/ionicons.svg2669
-rwxr-xr-xpublic/assets/fonts/ionicons.ttfbin124588 -> 188508 bytes
-rwxr-xr-xpublic/assets/fonts/ionicons.woffbin124664 -> 67904 bytes
-rw-r--r--public/assets/img/360.pngbin0 -> 7687 bytes
-rw-r--r--public/assets/img/delete-cursor.pngbin0 -> 2635 bytes
-rw-r--r--public/assets/img/keys.pngbin0 -> 8524 bytes
-rw-r--r--public/assets/img/offbeatrepeat.jpgbin0 -> 33207 bytes
-rw-r--r--public/assets/img/plainpattern.pngbin0 -> 39676 bytes
-rw-r--r--public/assets/img/plainpattern2.pngbin0 -> 4898 bytes
-rw-r--r--public/assets/img/plainpattern3.pngbin0 -> 27441 bytes
-rw-r--r--public/assets/img/text-cursor.pngbin0 -> 1622 bytes
-rw-r--r--public/assets/javascripts/app.js69
-rw-r--r--public/assets/javascripts/defaults.js9
-rw-r--r--public/assets/javascripts/mx/extensions/mx.movements.js406
-rw-r--r--public/assets/javascripts/mx/extensions/mx.movementsMobile.js203
-rw-r--r--public/assets/javascripts/mx/extensions/mx.orbitCamera.js97
-rw-r--r--public/assets/javascripts/mx/mx.js16
-rw-r--r--public/assets/javascripts/mx/primitives/mx.grid.js70
-rw-r--r--public/assets/javascripts/mx/primitives/mx.image.js42
-rw-r--r--public/assets/javascripts/mx/primitives/mx.point.js17
-rw-r--r--public/assets/javascripts/mx/primitives/mx.polyline.js57
-rw-r--r--public/assets/javascripts/mx/primitives/mx.soundcloud.js130
-rw-r--r--public/assets/javascripts/mx/primitives/mx.text.js75
-rw-r--r--public/assets/javascripts/mx/primitives/mx.video.js17
-rw-r--r--public/assets/javascripts/mx/primitives/mx.vimeo.js30
-rw-r--r--public/assets/javascripts/mx/primitives/mx.youtube.js28
-rw-r--r--public/assets/javascripts/rectangles/_env.js44
-rw-r--r--public/assets/javascripts/rectangles/engine/map/_map.js43
-rw-r--r--public/assets/javascripts/rectangles/engine/map/draw.js183
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/_base.js11
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/arrow.js83
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/eraser.js29
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/line.js63
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/ortho.js118
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/polyline.js73
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/position.js19
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/start.js29
-rw-r--r--public/assets/javascripts/rectangles/engine/map/ui/editor.js (renamed from public/assets/javascripts/rectangles/engine/map/ui_editor.js)77
-rw-r--r--public/assets/javascripts/rectangles/engine/map/ui/minimap.js (renamed from public/assets/javascripts/rectangles/engine/map/ui_minimap.js)4
-rw-r--r--public/assets/javascripts/rectangles/engine/map/ui/ortho.js107
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/_rooms.js72
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/_walls.js137
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/builder.js16
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/clipper.js3
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/grouper.js21
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/mover.js219
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/projector.js30
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/_scenery.js55
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/move.js58
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/randomize.js115
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/resize.js109
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/sound.js16
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/types/_object.js123
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/types/audio.js77
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/types/image.js19
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/types/text.js58
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/types/video.js35
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/undo.js161
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js105
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/move.js111
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/resize.js208
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/types/_object.js176
-rw-r--r--public/assets/javascripts/rectangles/engine/sculpture/types/image.js38
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/ortho.js66
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/polyline.js212
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/regionlist.js240
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/shapelist.js124
-rw-r--r--public/assets/javascripts/rectangles/models/floor.js218
-rw-r--r--public/assets/javascripts/rectangles/models/mat4.js78
-rw-r--r--public/assets/javascripts/rectangles/models/rect.js62
-rw-r--r--public/assets/javascripts/rectangles/models/room.js27
-rw-r--r--public/assets/javascripts/rectangles/models/surface.js22
-rw-r--r--public/assets/javascripts/rectangles/models/vec2.js42
-rw-r--r--public/assets/javascripts/rectangles/models/vec3.js28
-rw-r--r--public/assets/javascripts/rectangles/models/wall.js219
-rw-r--r--public/assets/javascripts/rectangles/util/constants.js10
-rw-r--r--public/assets/javascripts/rectangles/util/coords.js33
-rw-r--r--public/assets/javascripts/rectangles/util/measurement.js4
-rw-r--r--public/assets/javascripts/rectangles/util/minotaur.js8
-rw-r--r--public/assets/javascripts/rectangles/util/mouse.js25
-rw-r--r--public/assets/javascripts/rectangles/util/permissions.js2
-rw-r--r--public/assets/javascripts/rectangles/util/undostack.js1
-rw-r--r--public/assets/javascripts/rectangles/util/wheel.js33
-rw-r--r--public/assets/javascripts/ui/_router.js129
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintEditor.js129
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintInfo.js92
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintNotice.js62
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintScaler.js158
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintSettings.js123
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintToolbar.js97
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintUploader.js147
-rw-r--r--public/assets/javascripts/ui/blueprint/BlueprintView.js106
-rw-r--r--public/assets/javascripts/ui/builder/BuilderInfo.js101
-rw-r--r--public/assets/javascripts/ui/builder/BuilderSettings.js9
-rw-r--r--public/assets/javascripts/ui/builder/BuilderToolbar.js4
-rw-r--r--public/assets/javascripts/ui/builder/BuilderView.js13
-rw-r--r--public/assets/javascripts/ui/editor/Collaborators.js1
-rw-r--r--public/assets/javascripts/ui/editor/ColorControl.js153
-rw-r--r--public/assets/javascripts/ui/editor/EditorSettings.js109
-rw-r--r--public/assets/javascripts/ui/editor/EditorToolbar.js154
-rw-r--r--public/assets/javascripts/ui/editor/EditorView.js54
-rw-r--r--public/assets/javascripts/ui/editor/HelpCursor.js79
-rw-r--r--public/assets/javascripts/ui/editor/MediaEditor.js63
-rw-r--r--public/assets/javascripts/ui/editor/MediaTumblr.js53
-rw-r--r--public/assets/javascripts/ui/editor/MediaUpload.js19
-rw-r--r--public/assets/javascripts/ui/editor/MediaViewer.js193
-rw-r--r--public/assets/javascripts/ui/editor/Presets.js122
-rw-r--r--public/assets/javascripts/ui/editor/SculptureEditor.js237
-rw-r--r--public/assets/javascripts/ui/editor/TextEditor.js238
-rw-r--r--public/assets/javascripts/ui/editor/WallpaperPicker.js229
-rw-r--r--public/assets/javascripts/ui/lib/AlertModal.js38
-rw-r--r--public/assets/javascripts/ui/lib/AnimatedView.js31
-rw-r--r--public/assets/javascripts/ui/lib/ConfirmModal.js46
-rw-r--r--public/assets/javascripts/ui/lib/ErrorModal.js38
-rw-r--r--public/assets/javascripts/ui/lib/FormView.js227
-rw-r--r--public/assets/javascripts/ui/lib/LabColorPicker.js (renamed from public/assets/javascripts/ui/editor/LightControl.js)184
-rw-r--r--public/assets/javascripts/ui/lib/ModalView.js79
-rw-r--r--public/assets/javascripts/ui/lib/Parser.js118
-rw-r--r--public/assets/javascripts/ui/lib/Router.js1
-rw-r--r--public/assets/javascripts/ui/lib/ToggleableView.js19
-rw-r--r--public/assets/javascripts/ui/lib/Toolbar.js22
-rw-r--r--public/assets/javascripts/ui/lib/UploadView.js152
-rw-r--r--public/assets/javascripts/ui/lib/View.js231
-rw-r--r--public/assets/javascripts/ui/reader/EmbedView.js76
-rw-r--r--public/assets/javascripts/ui/reader/MediaPlayer.js28
-rw-r--r--public/assets/javascripts/ui/reader/ReaderView.js88
-rw-r--r--public/assets/javascripts/ui/reader/ShareView.js62
-rw-r--r--public/assets/javascripts/ui/reader/Tracker.js133
-rw-r--r--public/assets/javascripts/ui/reader/_router.js24
-rw-r--r--public/assets/javascripts/ui/site/EditProfileModal.js9
-rw-r--r--public/assets/javascripts/ui/site/EditSubscriptionModal.js290
-rw-r--r--public/assets/javascripts/ui/site/HomeView.js28
-rw-r--r--public/assets/javascripts/ui/site/LayoutsIndex.js85
-rw-r--r--public/assets/javascripts/ui/site/LayoutsModal.js183
-rw-r--r--public/assets/javascripts/ui/site/NewProjectModal.js118
-rw-r--r--public/assets/javascripts/ui/site/ProfileView.js28
-rw-r--r--public/assets/javascripts/ui/site/ProjectList.js64
-rw-r--r--public/assets/javascripts/ui/site/StaffView.js70
-rw-r--r--public/assets/javascripts/ui/z_share.js25
-rw-r--r--public/assets/javascripts/util.js81
-rw-r--r--public/assets/javascripts/vendor/canvasutilities.js145
-rwxr-xr-xpublic/assets/javascripts/vendor/chardinjs.min.js2
-rw-r--r--public/assets/javascripts/vendor/froogaloop.js287
-rw-r--r--public/assets/javascripts/vendor/polyfill.js10
-rw-r--r--public/assets/javascripts/vendor/wow.js452
-rw-r--r--public/assets/stylesheets/animate.css3158
-rwxr-xr-xpublic/assets/stylesheets/app.css2431
-rwxr-xr-xpublic/assets/stylesheets/chardinjs.css83
-rwxr-xr-xpublic/assets/stylesheets/ionicons.css2809
-rw-r--r--public/assets/stylesheets/staff.css51
-rw-r--r--public/assets/test/bg.html115
-rw-r--r--public/assets/test/intersect.html140
-rw-r--r--public/assets/test/intersect2.html220
-rw-r--r--public/assets/test/intersect3.html320
-rw-r--r--public/assets/test/orbit.html154
-rw-r--r--public/assets/test/ortho.html290
-rw-r--r--public/assets/test/ortho2.html374
-rw-r--r--public/assets/test/ortho3.html258
-rw-r--r--public/assets/test/ortho4.html303
-rw-r--r--public/assets/test/static.html152
-rw-r--r--public/assets/test/surface.html5
-rw-r--r--public/assets/test/wheel.html29
-rw-r--r--public/favicon.icobin0 -> 32988 bytes
-rw-r--r--server/fetch.js41
-rw-r--r--server/index.js45
-rw-r--r--server/lib/api/blueprint.js142
-rw-r--r--server/lib/api/index.js2
-rw-r--r--server/lib/api/layouts.js44
-rw-r--r--server/lib/api/media.js14
-rw-r--r--server/lib/api/profile.js3
-rw-r--r--server/lib/api/projects.js43
-rw-r--r--server/lib/api/rooms.js139
-rw-r--r--server/lib/api/subscription.js206
-rw-r--r--server/lib/auth/index.js28
-rw-r--r--server/lib/auth/mail.js4
-rw-r--r--server/lib/middleware.js98
-rw-r--r--server/lib/schemas/Blueprint.js66
-rw-r--r--server/lib/schemas/Layout.js3
-rw-r--r--server/lib/schemas/Media.js7
-rw-r--r--server/lib/schemas/Plan.js44
-rw-r--r--server/lib/schemas/Project.js7
-rw-r--r--server/lib/schemas/Subscription.js31
-rw-r--r--server/lib/schemas/User.js9
-rw-r--r--server/lib/upload.js2
-rw-r--r--server/lib/util.js18
-rw-r--r--server/lib/views/index.js363
-rw-r--r--server/lib/views/staff.js530
-rw-r--r--server/lib/views/staff/defaults.js6
-rw-r--r--server/lib/views/staff/fields.js10
-rw-r--r--server/lib/views/staff/helpers.js59
-rw-r--r--server/lib/views/staff/index.js511
-rw-r--r--server/lib/views/staff/middleware.js476
-rw-r--r--server/lib/webhook/index.js44
-rw-r--r--server/lib/webhook/recurly-config.js6
-rw-r--r--server/lib/webhook/webhook.js178
-rw-r--r--server/repl.js19
-rw-r--r--views/about/_blank.ejs24
-rw-r--r--views/about/_old_plans.ejs63
-rw-r--r--views/about/_plans.ejs121
-rw-r--r--views/about/about.ejs52
-rw-r--r--views/about/brochure.ejs25
-rw-r--r--views/about/howto.ejs128
-rw-r--r--views/blueprint.ejs30
-rw-r--r--views/builder.ejs18
-rw-r--r--views/controls/blueprint/editor.ejs36
-rw-r--r--views/controls/blueprint/info.ejs30
-rw-r--r--views/controls/blueprint/notice.ejs4
-rw-r--r--views/controls/blueprint/scaler.ejs48
-rw-r--r--views/controls/blueprint/settings.ejs18
-rw-r--r--views/controls/blueprint/toolbar.ejs42
-rw-r--r--views/controls/builder/info.ejs22
-rw-r--r--views/controls/builder/settings.ejs2
-rw-r--r--views/controls/builder/toolbar.ejs14
-rw-r--r--views/controls/editor/collaborators.ejs61
-rw-r--r--views/controls/editor/color-control.ejs27
-rw-r--r--views/controls/editor/light-control.ejs40
-rw-r--r--views/controls/editor/media-drawer.ejs98
-rw-r--r--views/controls/editor/media-editor.ejs22
-rw-r--r--views/controls/editor/presets.ejs5
-rw-r--r--views/controls/editor/sculpture.ejs42
-rw-r--r--views/controls/editor/settings.ejs32
-rw-r--r--views/controls/editor/share.ejs16
-rw-r--r--views/controls/editor/signed-out.ejs2
-rw-r--r--views/controls/editor/text-editor.ejs76
-rw-r--r--views/controls/editor/toolbar.ejs41
-rw-r--r--views/controls/editor/wallpaper.ejs42
-rw-r--r--views/controls/reader/about-room.ejs33
-rw-r--r--views/controls/reader/embed.ejs26
-rw-r--r--views/controls/reader/media-player.ejs12
-rw-r--r--views/docs.ejs8
-rwxr-xr-xviews/editor.ejs15
-rwxr-xr-xviews/home.ejs68
-rw-r--r--views/mail/collaborator.html.ejs2
-rw-r--r--views/mail/collaborator.text.ejs2
-rw-r--r--views/mail/welcome.html.ejs2
-rw-r--r--views/mail/welcome.text.ejs2
-rw-r--r--views/modal.ejs4
-rw-r--r--views/partials/confirm-modal.ejs1
-rw-r--r--views/partials/edit-profile.ejs7
-rw-r--r--views/partials/edit-subscription.ejs78
-rw-r--r--views/partials/footer.ejs30
-rw-r--r--views/partials/header.ejs71
-rw-r--r--views/partials/meta.ejs22
-rw-r--r--views/partials/scripts.ejs93
-rw-r--r--views/partials/sign-in.ejs9
-rw-r--r--views/profile.ejs104
-rw-r--r--views/projects/layouts-modal.ejs26
-rw-r--r--views/projects/list-projects.ejs42
-rw-r--r--views/reader.ejs11
-rw-r--r--views/staff/_blueprints.ejs21
-rw-r--r--views/staff/_gallery.ejs38
-rw-r--r--views/staff/_header.ejs2
-rw-r--r--views/staff/_layouts.ejs22
-rw-r--r--views/staff/_nav.ejs10
-rw-r--r--views/staff/_pagination.ejs2
-rw-r--r--views/staff/_projects.ejs3
-rw-r--r--views/staff/_users.ejs21
-rw-r--r--views/staff/blueprints/index.ejs13
-rw-r--r--views/staff/blueprints/show.ejs59
-rw-r--r--views/staff/blueprints/show_404.ejs9
-rw-r--r--views/staff/index.ejs6
-rw-r--r--views/staff/layouts/index.ejs13
-rw-r--r--views/staff/layouts/show.ejs61
-rw-r--r--views/staff/layouts/show_404.ejs9
-rw-r--r--views/staff/media/index.ejs7
-rw-r--r--views/staff/media/show.ejs7
-rw-r--r--views/staff/media/show_404.ejs9
-rw-r--r--views/staff/plans/_form.ejs154
-rw-r--r--views/staff/plans/edit.ejs13
-rw-r--r--views/staff/plans/index.ejs65
-rw-r--r--views/staff/plans/new.ejs13
-rw-r--r--views/staff/projects/index.ejs7
-rw-r--r--views/staff/projects/show.ejs22
-rw-r--r--views/staff/projects/show_404.ejs7
-rw-r--r--views/staff/subscriptions/index.ejs39
-rw-r--r--views/staff/subscriptions/show.ejs12
-rw-r--r--views/staff/users/index.ejs7
-rw-r--r--views/staff/users/media.ejs15
-rw-r--r--views/staff/users/show.ejs46
-rw-r--r--views/staff/users/show_404.ejs14
288 files changed, 26628 insertions, 5060 deletions
diff --git a/.gitignore b/.gitignore
index c0f4c0c..2a58e7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,9 @@ tmp/
config.json
+app.concat.js
+app.min.js
+
+static.concat.js
+static.min.js
+
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 0000000..988d040
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,339 @@
+module.exports = function(grunt) {
+
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('package.json'),
+ concat: {
+ options: {
+ separator: "\n;\n"
+ },
+ js: {
+ src: [
+ "/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"
+ "/assets/javascripts/vendor/bower_components/lodash/lodash.min.js",
+ "/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js",
+ "/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js",
+ "/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js",
+ "/assets/javascripts/vendor/bower_components/marked/lib/marked.js",
+ "/assets/javascripts/vendor/tube.js",
+ "/assets/javascripts/vendor/loader.js",
+ "/assets/javascripts/vendor/polyfill.js",
+ "/assets/javascripts/vendor/sha1.js",
+ "/assets/javascripts/vendor/dataUriToBlob.js",
+ "/assets/javascripts/vendor/froogaloop.js",
+ "/assets/javascripts/util.js",
+
+ "/assets/javascripts/mx/mx.js",
+
+ "/assets/javascripts/mx/extensions/mx.scene.js",
+ "/assets/javascripts/mx/extensions/mx.movements.js",
+ "/assets/javascripts/mx/extensions/mx.movementsMobile.js",
+ "/assets/javascripts/mx/extensions/mx.orbitCamera.js",
+
+ "/assets/javascripts/mx/primitives/mx.image.js",
+ "/assets/javascripts/mx/primitives/mx.text.js",
+ "/assets/javascripts/mx/primitives/mx.video.js",
+ "/assets/javascripts/mx/primitives/mx.youtube.js",
+ "/assets/javascripts/mx/primitives/mx.vimeo.js",
+ "/assets/javascripts/mx/primitives/mx.soundcloud.js",
+ "/assets/javascripts/mx/primitives/mx.grid.js",
+ "/assets/javascripts/mx/primitives/mx.point.js",
+ "/assets/javascripts/mx/primitives/mx.polyline.js",
+
+ "/assets/javascripts/rectangles/_env.js",
+
+ "/assets/javascripts/rectangles/util/constants.js",
+ "/assets/javascripts/rectangles/util/colors.js",
+ "/assets/javascripts/rectangles/util/coords.js",
+ "/assets/javascripts/rectangles/util/debug.js",
+ "/assets/javascripts/rectangles/util/keys.js",
+ "/assets/javascripts/rectangles/util/measurement.js",
+ "/assets/javascripts/rectangles/util/minotaur.js",
+ "/assets/javascripts/rectangles/util/mouse.js",
+ "/assets/javascripts/rectangles/util/permissions.js",
+ "/assets/javascripts/rectangles/util/sort.js",
+ "/assets/javascripts/rectangles/util/uid.js",
+ "/assets/javascripts/rectangles/util/undostack.js",
+ "/assets/javascripts/rectangles/util/wheel.js",
+
+ "/assets/javascripts/rectangles/models/vec2.js",
+ "/assets/javascripts/rectangles/models/vec3.js",
+ "/assets/javascripts/rectangles/models/rect.js",
+ "/assets/javascripts/rectangles/models/surface.js",
+ "/assets/javascripts/rectangles/models/tree.js",
+ "/assets/javascripts/rectangles/models/room.js",
+ "/assets/javascripts/rectangles/models/wall.js",
+ "/assets/javascripts/rectangles/models/floor.js",
+
+ "/assets/javascripts/rectangles/engine/rooms/_rooms.js",
+ "/assets/javascripts/rectangles/engine/rooms/_walls.js",
+ "/assets/javascripts/rectangles/engine/rooms/builder.js",
+ "/assets/javascripts/rectangles/engine/rooms/clipper.js",
+ "/assets/javascripts/rectangles/engine/rooms/grouper.js",
+ "/assets/javascripts/rectangles/engine/rooms/mover.js",
+
+ "/assets/javascripts/rectangles/engine/scenery/_scenery.js",
+ "/assets/javascripts/rectangles/engine/scenery/move.js",
+ "/assets/javascripts/rectangles/engine/scenery/resize.js",
+ "/assets/javascripts/rectangles/engine/scenery/randomize.js",
+ "/assets/javascripts/rectangles/engine/scenery/sound.js",
+ "/assets/javascripts/rectangles/engine/scenery/undo.js",
+ "/assets/javascripts/rectangles/engine/scenery/types/_object.js",
+ "/assets/javascripts/rectangles/engine/scenery/types/audio.js",
+ "/assets/javascripts/rectangles/engine/scenery/types/image.js",
+ "/assets/javascripts/rectangles/engine/scenery/types/text.js",
+ "/assets/javascripts/rectangles/engine/scenery/types/video.js",
+
+ "/assets/javascripts/rectangles/engine/sculpture/_sculpture.js",
+ "/assets/javascripts/rectangles/engine/sculpture/move.js",
+ "/assets/javascripts/rectangles/engine/sculpture/resize.js",
+ "/assets/javascripts/rectangles/engine/sculpture/types/_object.js",
+ "/assets/javascripts/rectangles/engine/sculpture/types/image.js",
+
+ "/assets/javascripts/rectangles/engine/shapes/polyline.js",
+ "/assets/javascripts/rectangles/engine/shapes/ortho.js",
+ "/assets/javascripts/rectangles/engine/shapes/shapelist.js",
+ "/assets/javascripts/rectangles/engine/shapes/regionlist.js",
+
+ "/assets/javascripts/rectangles/engine/map/_map.js",
+ "/assets/javascripts/rectangles/engine/map/draw.js",
+ "/assets/javascripts/rectangles/engine/map/ui/editor.js",
+ "/assets/javascripts/rectangles/engine/map/ui/minimap.js",
+ "/assets/javascripts/rectangles/engine/map/ui/ortho.js",
+ "/assets/javascripts/rectangles/engine/map/tools/_base.js",
+ "/assets/javascripts/rectangles/engine/map/tools/arrow.js",
+ "/assets/javascripts/rectangles/engine/map/tools/line.js",
+ "/assets/javascripts/rectangles/engine/map/tools/eraser.js",
+ "/assets/javascripts/rectangles/engine/map/tools/ortho.js",
+ "/assets/javascripts/rectangles/engine/map/tools/polyline.js",
+ "/assets/javascripts/rectangles/engine/map/tools/position.js",
+ "/assets/javascripts/rectangles/engine/map/tools/start.js",
+
+ "/assets/javascripts/ui/lib/View.js",
+ "/assets/javascripts/ui/lib/Router.js",
+ "/assets/javascripts/ui/lib/ModalView.js",
+ "/assets/javascripts/ui/lib/FormView.js",
+ "/assets/javascripts/ui/lib/UploadView.js",
+ "/assets/javascripts/ui/lib/AnimatedView.js",
+ "/assets/javascripts/ui/lib/ToggleableView.js",
+ "/assets/javascripts/ui/lib/AlertModal.js",
+ "/assets/javascripts/ui/lib/ConfirmModal.js",
+ "/assets/javascripts/ui/lib/ErrorModal.js",
+ "/assets/javascripts/ui/lib/Parser.js",
+ "/assets/javascripts/ui/lib/LabColorPicker.js",
+
+ "/assets/javascripts/ui/site/SignInModal.js",
+ "/assets/javascripts/ui/site/SignUpModal.js",
+ "/assets/javascripts/ui/site/UsernameTaken.js",
+ "/assets/javascripts/ui/site/PasswordForgot.js",
+ "/assets/javascripts/ui/site/PasswordReset.js",
+ "/assets/javascripts/ui/site/LayoutsIndex.js",
+ "/assets/javascripts/ui/site/LayoutsModal.js",
+ "/assets/javascripts/ui/site/NewProjectModal.js",
+ "/assets/javascripts/ui/site/EditProjectModal.js",
+ "/assets/javascripts/ui/site/EditProfileModal.js",
+ "/assets/javascripts/ui/site/EditSubscriptionModal.js",
+ "/assets/javascripts/ui/site/DocumentModal.js",
+
+ "/assets/javascripts/ui/site/HomeView.js",
+ "/assets/javascripts/ui/site/ProfileView.js",
+ "/assets/javascripts/ui/site/ProjectList.js",
+
+ "/assets/javascripts/ui/builder/BuilderView.js",
+ "/assets/javascripts/ui/builder/BuilderSettings.js",
+ "/assets/javascripts/ui/builder/BuilderToolbar.js",
+ "/assets/javascripts/ui/builder/BuilderInfo.js",
+
+ "/assets/javascripts/ui/blueprint/BlueprintView.js",
+ "/assets/javascripts/ui/blueprint/BlueprintInfo.js",
+ "/assets/javascripts/ui/blueprint/BlueprintSettings.js",
+ "/assets/javascripts/ui/blueprint/BlueprintEditor.js",
+ "/assets/javascripts/ui/blueprint/BlueprintScaler.js",
+ "/assets/javascripts/ui/blueprint/BlueprintToolbar.js",
+ "/assets/javascripts/ui/blueprint/BlueprintUploader.js",
+ "/assets/javascripts/ui/blueprint/BlueprintNotice.js",
+
+ "/assets/javascripts/ui/editor/EditorView.js",
+ "/assets/javascripts/ui/editor/EditorSettings.js",
+ "/assets/javascripts/ui/editor/EditorToolbar.js",
+ "/assets/javascripts/ui/editor/HelpCursor.js",
+ "/assets/javascripts/ui/editor/ColorControl.js",
+ "/assets/javascripts/ui/editor/Collaborators.js",
+ "/assets/javascripts/ui/editor/MediaEditor.js",
+ "/assets/javascripts/ui/editor/MediaTumblr.js",
+ "/assets/javascripts/ui/editor/MediaUpload.js",
+ "/assets/javascripts/ui/editor/MediaViewer.js",
+ "/assets/javascripts/ui/editor/Presets.js",
+ "/assets/javascripts/ui/editor/SculptureEditor.js",
+ "/assets/javascripts/ui/editor/TextEditor.js",
+ "/assets/javascripts/ui/editor/WallpaperPicker.js",
+
+ "/assets/javascripts/ui/reader/ReaderView.js",
+ "/assets/javascripts/ui/reader/ShareView.js",
+ "/assets/javascripts/ui/reader/EmbedView.js",
+ "/assets/javascripts/ui/reader/MediaPlayer.js",
+ "/assets/javascripts/ui/reader/Tracker.js",
+
+ "/assets/javascripts/ui/_router.js",
+
+ "/assets/javascripts/app.js",
+ "/assets/javascripts/defaults.js",
+ ],
+ dest: 'public/assets/javascripts/app.concat.js',
+ },
+
+ // this builds a static version of the vvalls code, suitable for embedding
+ // in another website. see assets/test/static.html
+ 'static': {
+ src: [
+ "public/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js",
+ "public/assets/javascripts/vendor/bower_components/lodash/lodash.min.js",
+ "public/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js",
+ "public/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js",
+ "public/assets/javascripts/vendor/bower_components/marked/lib/marked.js",
+ "public/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js",
+ "public/assets/javascripts/vendor/tube.js",
+ "public/assets/javascripts/vendor/loader.js",
+ "public/assets/javascripts/vendor/polyfill.js",
+ "public/assets/javascripts/vendor/froogaloop.js",
+ "public/assets/javascripts/util.js",
+
+ "public/assets/javascripts/mx/mx.js",
+ "public/assets/javascripts/mx/extensions/mx.scene.js",
+ "public/assets/javascripts/mx/extensions/mx.movements.js",
+ "public/assets/javascripts/mx/extensions/mx.movementsMobile.js",
+ "public/assets/javascripts/mx/primitives/mx.image.js",
+ "public/assets/javascripts/mx/primitives/mx.text.js",
+ "public/assets/javascripts/mx/primitives/mx.video.js",
+ "public/assets/javascripts/mx/primitives/mx.youtube.js",
+ "public/assets/javascripts/mx/primitives/mx.vimeo.js",
+ "public/assets/javascripts/mx/primitives/mx.soundcloud.js",
+ "public/assets/javascripts/mx/primitives/mx.grid.js",
+
+ "public/assets/javascripts/rectangles/_env.js",
+
+ "public/assets/javascripts/rectangles/util/constants.js",
+ "public/assets/javascripts/rectangles/util/colors.js",
+ "public/assets/javascripts/rectangles/util/coords.js",
+ "public/assets/javascripts/rectangles/util/debug.js",
+ "public/assets/javascripts/rectangles/util/keys.js",
+ "public/assets/javascripts/rectangles/util/measurement.js",
+ "public/assets/javascripts/rectangles/util/minotaur.js",
+ "public/assets/javascripts/rectangles/util/mouse.js",
+ "public/assets/javascripts/rectangles/util/permissions.js",
+ "public/assets/javascripts/rectangles/util/sort.js",
+ "public/assets/javascripts/rectangles/util/uid.js",
+ "public/assets/javascripts/rectangles/util/undostack.js",
+ "public/assets/javascripts/rectangles/util/wheel.js",
+
+ "public/assets/javascripts/rectangles/models/vec2.js",
+ "public/assets/javascripts/rectangles/models/vec3.js",
+ "public/assets/javascripts/rectangles/models/rect.js",
+ "public/assets/javascripts/rectangles/models/surface.js",
+ "public/assets/javascripts/rectangles/models/tree.js",
+ "public/assets/javascripts/rectangles/models/room.js",
+ "public/assets/javascripts/rectangles/models/wall.js",
+ "public/assets/javascripts/rectangles/models/floor.js",
+
+ "public/assets/javascripts/rectangles/engine/rooms/_rooms.js",
+ "public/assets/javascripts/rectangles/engine/rooms/_walls.js",
+ "public/assets/javascripts/rectangles/engine/rooms/builder.js",
+ "public/assets/javascripts/rectangles/engine/rooms/clipper.js",
+ "public/assets/javascripts/rectangles/engine/rooms/grouper.js",
+ "public/assets/javascripts/rectangles/engine/rooms/mover.js",
+
+ "public/assets/javascripts/rectangles/engine/scenery/_scenery.js",
+ "public/assets/javascripts/rectangles/engine/scenery/move.js",
+ "public/assets/javascripts/rectangles/engine/scenery/resize.js",
+ "public/assets/javascripts/rectangles/engine/scenery/randomize.js",
+ "public/assets/javascripts/rectangles/engine/scenery/sound.js",
+ "public/assets/javascripts/rectangles/engine/scenery/undo.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/_object.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/image.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/text.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/video.js",
+ "public/assets/javascripts/rectangles/engine/scenery/types/audio.js",
+
+ "public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/move.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/resize.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/types/_object.js",
+ "public/assets/javascripts/rectangles/engine/sculpture/types/image.js",
+
+ "public/assets/javascripts/rectangles/engine/map/_map.js",
+ "public/assets/javascripts/rectangles/engine/map/ui/editor.js",
+ "public/assets/javascripts/rectangles/engine/map/ui/minimap.js",
+ "public/assets/javascripts/rectangles/engine/map/draw.js",
+
+ "public/assets/javascripts/ui/lib/View.js",
+ "public/assets/javascripts/ui/lib/Router.js",
+ "public/assets/javascripts/ui/lib/ModalView.js",
+
+ "public/assets/javascripts/ui/reader/ReaderView.js",
+ "public/assets/javascripts/ui/reader/ShareView.js",
+ "public/assets/javascripts/ui/reader/EmbedView.js",
+ "public/assets/javascripts/ui/reader/MediaPlayer.js",
+ "public/assets/javascripts/ui/reader/Tracker.js",
+
+ "public/assets/javascripts/ui/reader/_router.js",
+
+ "public/assets/javascripts/app.js",
+ "public/assets/javascripts/defaults.js",
+ ],
+ dest: 'public/assets/javascripts/static.concat.js',
+ }
+
+
+ },
+ copy: {
+ concat: {
+ files: [
+ {
+ src: 'public/assets/javascripts/app.concat.js',
+ dest: 'public/assets/javascripts/app.min.js',
+ },
+ ]
+ },
+ 'static': {
+ files: [
+ {
+ src: 'public/assets/javascripts/static.concat.js',
+ dest: 'public/assets/javascripts/static.min.js',
+ },
+ ]
+ },
+ },
+ uglify: {
+ options: {
+ banner: '/* vvalls by okfocus 2016 */\n'
+ },
+ js: {
+ src: 'public/assets/javascripts/app.concat.js',
+ dest: 'public/assets/javascripts/app.min.js',
+ },
+ 'static': {
+ src: 'public/assets/javascripts/static.concat.js',
+ dest: 'public/assets/javascripts/static.min.js',
+ }
+ },
+ clean: {
+ release: [
+ "public/assets/javascripts/static.concat.js",
+ "public/assets/javascripts/app.concat.js",
+ ],
+ }
+ });
+
+ // Load tasks that we'll be using
+ grunt.loadNpmTasks('grunt-contrib-concat');
+ grunt.loadNpmTasks('grunt-contrib-copy');
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+ grunt.loadNpmTasks('grunt-contrib-clean');
+
+ // Default task(s).
+ grunt.registerTask('js', ['concat:js', 'uglify:js', 'clean:release']);
+ grunt.registerTask('js-test', ['concat:js', 'copy:concat']);
+ grunt.registerTask('static', ['concat:static', 'uglify:static', 'clean:release']);
+ grunt.registerTask('static-test', ['concat:static', 'copy:static']);
+ grunt.registerTask('default', ['js']);
+};
+
diff --git a/Procfile b/Procfile
index 983db91..bab08fb 100644
--- a/Procfile
+++ b/Procfile
@@ -1 +1,2 @@
-web: node server \ No newline at end of file
+web: node server
+webhook: node server/lib/webhook \ No newline at end of file
diff --git a/README.md b/README.md
index 1c95b14..3bb1093 100644
--- a/README.md
+++ b/README.md
@@ -19,3 +19,20 @@ vvalls
| | .' | |/ | | \| | `. | |
+------+' +------+ +------+ +------+ `+------+
```
+
+Installing VValls
+=================
+
+1) Install mongodb, nodejs, npm (probably comes with node) and bower
+2) `git clone git@github.com:okfocus/vvalls.git`
+3) `cd vvalls ; git checkout subscriptions`
+4) `npm install`
+5) `bower install`
+6) `cp config.json.example config.json`
+7) Start the mongod server (if it isn't running already)
+8) `node server`
+
+Server will be running on http://lvh.me:3000/
+
+To give yourself superuser access, visit http://lvh.me:3000/staff/authorize (development mode only)
+
diff --git a/bower.json b/bower.json
index ee8f9ba..e3e83ca 100644
--- a/bower.json
+++ b/bower.json
@@ -7,6 +7,9 @@
"momentjs": "~2.5.1",
"lodash": "",
"fiber": "",
- "jquery-jsonview": "1.2.0"
+ "jquery-jsonview": "1.2.0",
+ "prefixfree": "",
+ "marked": "0.3.2",
+ "hidpi-canvas": "git://github.com/julescarbon/hidpi-canvas-polyfill.git#master"
}
}
diff --git a/config.json.example b/config.json.example
index 90df381..df4b86e 100644
--- a/config.json.example
+++ b/config.json.example
@@ -1,8 +1,10 @@
{
- "host": "lvh.me:3000",
- "hostName": "lvh.me",
- "port": 3000,
- "socketPort": 1337,
- "pageSize": 10,
- "env": { "development": 1 }
+ "host": "lvh.me:3000",
+ "hostName": "lvh.me",
+ "port": 3000,
+ "socketPort": 1337,
+ "webhookPort": 5000,
+ "databaseHost": "lvh.me",
+ "env": { "development": 1 },
+ "basicAuth": { "user": "vv", "pass": "ok" }
}
diff --git a/package.json b/package.json
index b4ac400..b055b9e 100644
--- a/package.json
+++ b/package.json
@@ -6,40 +6,45 @@
"url": "git://github.com/okfocus/vvalls.git"
},
"dependencies": {
- "express": "~3.4.8",
- "monk": "~0.7.1",
- "socket.io": "~0.9.16",
+ "body-parser": "1.3.0",
"connect-mongo": "~0.4.1",
- "passport": "~0.2.0",
- "passport-local": "~1.0.0",
- "passport-twitter": "~1.0.2",
- "passport-facebook": "~1.0.3",
- "passport.socketio": "~3.0.1",
- "node-restful": "~0.1.14",
"ejs": "^0.8.8",
- "useful-string": "0.0.1",
+ "emailjs": "~0.3.6",
+ "express": "^3.4.8",
"express-subdomain-handler": "~0.1.0",
"express-subdomains": "0.0.5",
- "lodash": "~2.4.1",
- "mongoose": "~3.8.8",
- "mongoose-unique-validator": "~0.3.0",
- "mongoose-lifecycle": "~1.0.0",
+ "express-xml-bodyparser": "0.0.6",
+ "html-entities": "~1.0.10",
+ "inspect": "0.0.2",
+ "intro.js": "^0.9.0",
+ "js2xml": "",
"knox": "~0.8.10",
+ "lodash": "~2.4.1",
+ "marked": "~0.3.2",
+ "method-override": "^2.3.6",
"moment": "~2.6.0",
- "html-entities": "~1.0.10",
+ "mongoose": "^4.2.8",
+ "mongoose-lifecycle": "",
+ "mongoose-unique-validator": "",
"multer": "~0.1.0",
- "body-parser": "1.3.0",
- "marked": "~0.3.2",
- "emailjs": "~0.3.6"
+ "node-recurly": "julescarbon/node-recurly",
+ "passport": "~0.2.0",
+ "passport-facebook": "~1.0.3",
+ "passport-local": "~1.0.0",
+ "passport-twitter": "~1.0.2",
+ "passport.socketio": "~3.0.1",
+ "socket.io": "~0.9.16",
+ "useful-string": "0.0.1",
+ "xml2js": ""
},
"devDependencies": {
- "grunt": "~0.4.1",
- "grunt-contrib-concat": "~0.3.0",
- "grunt-contrib-uglify": "~0.2.5",
- "grunt-contrib-watch": "~0.5.3",
- "grunt-contrib-clean": "~0.5.0",
- "grunt-contrib-copy": "~0.5.0",
- "grunt-dentist": "~0.3.4",
- "mocha": "~1.20.1"
+ "grunt": "",
+ "grunt-contrib-concat": "",
+ "grunt-contrib-uglify": "",
+ "grunt-contrib-watch": "",
+ "grunt-contrib-clean": "",
+ "grunt-contrib-copy": "",
+ "grunt-dentist": "",
+ "mocha": ""
}
}
diff --git a/public/assets/fonts/ionicons.eot b/public/assets/fonts/ionicons.eot
index 6b33288..92a3f20 100755
--- a/public/assets/fonts/ionicons.eot
+++ b/public/assets/fonts/ionicons.eot
Binary files differ
diff --git a/public/assets/fonts/ionicons.svg b/public/assets/fonts/ionicons.svg
index a1ee425..49fc8f3 100755
--- a/public/assets/fonts/ionicons.svg
+++ b/public/assets/fonts/ionicons.svg
@@ -1,447 +1,2230 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<!--
+2014-12-4: Created.
+-->
<svg xmlns="http://www.w3.org/2000/svg">
-<metadata>Generated by IcoMoon</metadata>
+<metadata>
+Created by FontForge 20120731 at Thu Dec 4 09:51:48 2014
+ By Adam Bradley
+Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net)
+</metadata>
<defs>
-<font id="icomoon" horiz-adv-x="1024">
-<font-face units-per-em="1024" ascent="960" descent="-64" />
-<missing-glyph horiz-adv-x="1024" />
-<glyph unicode="&#x20;" d="" horiz-adv-x="512" />
-<glyph unicode="&#xe600;" d="M728.8 318.2c-10.6-15-23.2-29.4-37.6-42.8-14.2-13.2-30.2-25-47.4-34.8-17.2-9.8-35.8-17.6-55-23s-39.6-8.2-60.6-8.2c-31.8 0-62.4 5.2-91 15.2-28.4 10-53.6 25-75 44.8-21.4 19.6-43.4 51.8-56.4 82-11.6 26.8-16.2 55.6-16.2 99 0 31.2 7.2 66 19.6 95.2 12 28 28.6 52.8 49.8 73.8 20.8 20.6 46 37.2 75.2 49.6 26.2 11 57 16.4 94.2 16.4 29.8 0 58-4.8 83.8-14 25.6-9.2 47.8-22.4 66.2-39.2 17.4-15.8 28-34.8 39.4-60.4 10-22.4 13.6-41.8 13.6-71.8 0-24.8-4.4-48.2-13-69.8-8.6-21.2-15-34-28-50-13.2-15.8-21.2-25.4-36.2-34.2-17.2-10-30.6-14.8-42-14.8-7.2 0-12.6 1.4-15.6 4-3 2.6-4.8 6-5.4 10.8-0.8 5.6-0.2 12.6 2 20.8 2.2 8.8 5.6 17.2 9.8 27.4l75.8 203.8h-35.6l-12.4-33c-7.6 12.2-18.2 23-31.8 31-21 12.2-39 17.6-62.4 17.6-27 0-52-7-74.4-20.8-22-13.6-41-31.2-56.4-52.6-15-20.6-18.6-31.4-25.8-52.8l-1.2-3.4c-8.4-24.8-12.6-49.2-12.6-72.4 0-15.4 2.8-30 8.2-43.6 5.4-13.6 12.8-25.6 22.2-35.6 9.4-10.2 20.8-18.2 33.8-24.2s27.4-9 42.6-9c17 0 33.2 2.8 52.2 9.4 12.6 4.4 23.8 11.6 34.8 22.8 2-6.4 5.4-12 10.6-17 10-10 23.4-15.2 39.8-15.2 17.2 0 35.6 6 58 18.6 19.8 11.2 31.4 24 46.6 42.2 16.4 19.6 24.6 36 33.8 59.4 10 25 15 52 15 80.6 0 36-4.8 60.4-17 87.2-13.2 28.6-26.4 51.6-48 70.8-21.8 19.2-47.8 34.2-77 44.6-29 10.2-60.6 15.4-93.4 15.4-40.2 0-74.4-6-104.4-18.2-33-13.4-61.8-32-86-55.2-24.4-23.6-44-51.8-58-83.8-14.6-33.2-22.8-73.4-22.8-110.2 0-50.2 6.2-85.2 20.6-116.8 16-34.6 42-70.8 66.6-92 25.2-21.8 54.2-38.2 86.4-48.4 31.8-10.2 64.6-15.4 97.6-15.4 22.8 0 45.6 3.2 68 9.2 22.4 6.2 44 14.8 64.2 26.2 20.2 11.2 39 25 56.4 41.2 17.2 16.2 37.2 41.6 44 53.8 2.6 4.8 4.4 8.6 5.8 11.6h-37l-1-1.8zM551.6 371.2c-8.8-11.2-15.4-19-23.6-24.4-8.8-6-15.8-9.8-24.8-11.8-9.2-2.4-18.6-3.4-27.4-3.4-11.2 0-21.6 2-30.8 6-9.4 4-17.4 9.6-24.2 16.8-6.8 7.2-12.2 15.8-16.2 25.4-3.8 9.6-5.8 20.4-5.8 32 0 19 3.6 39.4 10.6 60.6 0.8 2.4 1.6 4.8 2.2 6.8 5.6 17.2 8.6 23 19 40 11.4 18.8 28.2 33.2 46 45 17.2 11.6 36.4 17.4 57 17.4 8.4 0 17.2-1 26.4-3 7.2-1.6 11.2-3.8 18-7.8 1.2-0.6 2.2-1.2 3.4-2 7.8-4.4 14.8-10.2 20.8-17.4 5.4-6.4 9.6-14.8 12.6-24.6l-41.2-115.6c-6.4-16.2-13.8-29.6-22-40z" />
-<glyph unicode="&#xe601;" d="M685.8 629.2l18.2 12.8 18.2-12.8 45.8-29v231.8c-41.4 0-89 0-128 0v-231.8l45.8 29zM864 832c0 0-26.6 0-64 0v-293l-96 64-96-64v293c-24.2 0-41.2 0-44.8 0-16.2 0-35.2-14.4-35.2-30s0-658 0-658l-16-11-16 11c0 0 0 644 0 658s-18.4 30-35.2 30-300.8 0-300.8 0c-37.6 0-66-26.6-66-64v-572.2c0-37.6 28.4-67.8 66-67.8 0 0 259 0 286.6 0 27.6 0 49.4-8.4 49.4-38.8 0-18.2 0-25.2 0-25.2h32c0 0 0 6.8 0 25.2 0 30.6 21.8 38.8 49.4 38.8s286.6 0 286.6 0c37.6 0 66 30.2 66 67.8v572.2c0 37.4-28.4 64-66 64z" />
-<glyph unicode="&#xe602;" d="M864 832h-300.8c-20.6 0-38.6-9.2-51.2-23.4v0 0c-12.4 14.4-30.6 23.4-51.2 23.4h-300.8c-37.6 0-66-26.6-66-64v-572.2c0-37.6 28.4-67.8 66-67.8 0 0 259 0 286.6 0 27.6 0 49.4-8.4 49.4-38.8 0-18.2 0-25.2 0-25.2h32c0 0 0 6.8 0 25.2 0 30.6 21.8 38.8 49.4 38.8s286.6 0 286.6 0c37.6 0 66 30.2 66 67.8v572.2c0 37.4-28.4 64-66 64zM496 137.8c-9.4 15.6-27 22.2-47.6 22.2h-288.4c-18.8 0-32 17-32 35.8v572.2c0 18.8 13.2 32 32 32 0 0 261.2 0 286.6 0 25.6 0 49.4-25.6 49.4-44.4v-617.8zM640 800c37.6 0 86 0 128 0v-200.8l-45.8 29-18.2 12.8-18.2-12.8-45.8-29v200.8zM896 195.8c0-18.8-13.2-35.8-32-35.8h-288.4c-20.6 0-38.2-4.6-47.6-22.2v617.8c0 18.8 23.8 44.4 49.4 44.4 4.4 0 15.4 0 30.6 0v-262l96 64 96-64v262c37.2 0 64 0 64 0 18.8 0 32-13.4 32-32v-572.2z" />
-<glyph unicode="&#xe603;" d="M684.6 281.2c-14-13-29.4-24.2-46-33.8-16.8-9.6-34.6-17-53.2-22.2-18.6-5.2-38.2-8-58.4-8-30.6 0-60.4 5-88.4 14.8-27.4 9.6-51.8 24.2-72.2 43.2-20.4 18.6-41.8 49.8-54.4 79.2-11 25.6-15.6 53.2-15.6 95.8 0 30.2 7 63.6 19 92 11.6 27.2 27.8 51.2 48 71.2 20 19.8 44.4 36 72.6 48 25.2 10.6 55 15.8 91.2 15.8 28.6 0 56-4.6 81-13.6 24.4-8.8 45.8-21.4 63.6-37.6 16.4-15 26.6-33.2 37.4-57.8 9.4-21 13-39.6 13-68.6 0-23.6-4.2-46.2-12.4-66.8-8.2-20.2-14.4-32.6-26.8-48-13-15.6-20.2-24.2-34-32.2-16-9.4-28.2-13.8-38-13.8-7.8 0-10.2 1.8-10.4 2-1.2 1-2.2 2.4-2.8 5.8-0.6 4.6 0 10.8 1.8 17.8 2 8 5 15.6 9.4 26.2l80 214.8h-52.6l-9.2-24.4c-7.2 8.4-15.8 15.6-25.4 21.2-22.8 13.2-42 18.6-66.4 18.6-28.4 0-55-7.4-78.6-22-23-14.2-42.8-32.6-58.6-54.6-15.6-21.6-19.6-33.2-26.8-54.6l-1.2-3.6c-8.6-25.6-13-50.8-13-75 0-16.2 3-32 8.8-46.6 5.8-14.8 13.8-27.6 23.8-38 9.8-10.8 22-19.4 36.4-26 14-6.4 29.4-9.8 46-9.8 18.4 0 35.2 3 54.8 9.8 10.8 3.8 20.4 9.2 29.6 17 2-3.4 4.6-6.4 7.6-9.2 11.6-11.6 27-17.6 45.4-17.6 18.4 0 38.2 6.2 62 19.6 21.2 12 33.6 25.8 48.8 44 17.2 20.6 25.8 38.2 35 61.6 10.4 25.8 15.6 54 15.6 83.6 0 37.2-5 62.6-17.8 90.6-13.6 29.6-27.4 53.4-50 73.4-22.4 20-49.2 35.4-79.6 46.2-30 10.6-62.2 15.8-96 15.8-41.2 0-76.4-6.2-107.4-18.8-33.6-13.6-63.4-32.8-88.6-56.8-25.2-24.4-45.4-53.6-59.8-86.4-15-34-23.4-75.2-23.4-113.4 0-51.4 6.4-87.4 21.4-120.2 16.6-36 43.6-73 68.6-94.6 26.2-22.8 56.2-39.6 89.2-50 32.6-10.4 66.4-15.8 100-15.8 23 0 46.6 3.2 70.2 9.4 23.8 6.6 46 15.6 66 27 20.4 11.4 40 25.6 58 42.4 18 16.8 38.4 43 45.6 55.8 3.8 7 6.2 12.2 7.4 15.4h-55.2c-10.6-13-22-26-35-38.2zM544.2 376.2c-9-11.4-14.8-18.2-21.8-22.8-7.8-5.4-14-8.8-22-10.6h-0.2c-8-2-16.6-3.2-25.4-3.2-10.2 0-19.4 1.8-27.6 5.4-8.4 3.6-15.4 8.4-21.6 15-6 6.4-11 14-14.6 22.8-3.4 8.8-5.2 18.6-5.2 29 0 18 3.4 37.6 10.2 58 0.8 2.4 1.6 5 2.2 6.8 5.4 16.6 8.2 21.8 18.2 38.4 9.2 15.2 23.6 29.2 43.6 42.6 15.8 10.6 33.4 16 52.6 16 7.8 0 16-1 24.6-2.8 6.2-1.4 9.4-3.2 15.6-6.8l0.4-0.2c0.8-0.4 1.6-0.8 2.6-1.4l0.6-0.4c7-4 13.2-9.2 18.6-15.6 4.2-5 7.6-11.4 10.2-19.4l-40.2-113c-6.2-15.2-13.2-28-20.8-37.8z" />
-<glyph unicode="&#xe604;" d="M795.2 666.6l-3.6 3.4h36.8l17-15.6 45 45.6-81.6 80.6-46.4-44.6 17.6-18.4v-37.2l-10 9.4c-62.6 56.6-140 90.4-226 97.8v76.4h-64v-76h-4c-87.4-6-170-45-232-106v35.6l17.8 18.4-45.8 44.4-81.6-80.4 45-45.6 17 15.6h35.6c-0.6 0-1.4-1.4-2-2.2-65.6-70.2-102-161.8-102-257 0-208.8 172.2-378.8 384.2-378.8 211.6 0 383.8 169.8 383.8 378.6 0 95.2-36 186.2-100.8 256zM528 323.6l-16-35.6-16 35.6c-28 7-48 31.6-48 61 0 27.6 23 52 48 60.6v258.8h32v-258.6c27-7.4 48-31.8 48-60.8 0-29.4-20-54-48-61z" />
-<glyph unicode="&#xe605;" d="M795.2 666.6l-3.6 3.4h36.8l17-15.6 45 45.6-81.6 80.6-46.4-44.6 17.6-18.4v-37.2l-10 9.4c-62.6 56.6-140 90.4-226 97.8v76.4h-64v-76h-4c-87.4-6-170-45-232-106v35.6l17.8 18.4-45.8 44.4-81.6-80.4 45-45.6 17 15.6h35.6c-0.6 0-1.4-1.4-2-2.2-65.6-70.2-102-161.8-102-257 0-208.8 172.2-378.8 384.2-378.8 211.6 0 383.8 169.8 383.8 378.6 0 95.2-36 186.2-100.8 256zM512.6 68.6c-191 0-346.2 153.4-346.2 341.8 0 188.6 155.4 341.8 346.2 341.8 191 0 346.2-153.4 346.2-341.8 0.2-188.4-155.2-341.8-346.2-341.8zM528 445.4v258.6h-32v-258.8c-25-8.6-48-33-48-60.6 0-29.4 20-54 48-61l16-35.6 16 35.6c28 7 48 31.6 48 61 0 29-21 53.4-48 60.8z" />
-<glyph unicode="&#xe606;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM301 659c5.2 4.6 239.8-169.8 239.8-169.8 2-1.4 3.2-3 4.4-4.4 10-9.2 16.4-22 16.4-36.6 0-27.4-22.2-49.8-49.8-49.8-15.6 0-29.4 7.4-38.6 18.8-0.8 0.8-1.6 1.4-2.2 2.2 0.2-0.2-175 234.8-170 239.6zM512.2 65.6c-211.4 0-382.8 171.4-382.8 382.8 0 105.6 42.8 201.4 112 270.6l23.6-23.6c-63.2-63.2-102.4-150.6-102.4-247 0-192.6 156.8-349.4 349.4-349.4s349 156.8 349 349.4c0 180.6-141 330.2-317 348v-156.4h-32v191.2c211.4 0 383-171.4 383-382.8s-171.6-382.8-382.8-382.8z" />
-<glyph unicode="&#xe607;" d="M473.2 416.8c9.2-11.4 23-18.8 38.8-18.8 27.6 0 50 22.4 50 50 0 14.6-6.4 27.6-16.4 36.8-1.2 1.4-2.6 3-4.4 4.4 0 0-235.4 175-240.6 170.4-5.2-4.6 170.6-240.4 170.6-240.4 0.4-0.8 1.4-1.6 2-2.4zM512.4 864v0h-0.4v-224h32v189.4c195.6-16.6 350.6-181 350.6-381 0-211-171.4-382.8-382.4-382.8-211 0-382.6 171.6-382.6 382.6 0 105.6 43 201.2 112.2 270.4l-23.8 23.6c-75.4-75.4-122-179.4-122-294.2 0-229.8 186.2-416 416-416 229.8 0 416 186.2 416 416 0 229.8-186 416-415.6 416z" />
-<glyph unicode="&#xe608;" d="M876.8 575.2c24.4 28.4 39.2 64.6 39.2 104.4 0.2 87.6-71 159.2-160.8 164.2-3.2 0.2-6.2 0.2-9.6 0.2-40.8 0.2-78.2-13.6-107.6-36.2l107.6-104.8-21.2-20.8c-51.4 38.8-114.4 64-182.4 69.8v0.2c0 17-14 31-31 31s-31-14-31-31v-0.2c-68-5.8-130-31-181.2-69.8l-20.8 20.6 107.6 104.8c-29.4 22.8-66.8 36.4-107.4 36.2-3.2 0-6.4-0.2-9.6-0.2-90-5-161.2-76.6-160.8-164.2 0-39.6 14.8-76 39.2-104.4l108 105.2 19-19c-70.2-63.8-114.2-156-114.2-258.4 0-87.8 32.4-168 86-229.4l-72.8-89.2 25-20.2 70.4 85.8c63.2-60.4 148.8-97.8 243.2-97.8h0.2c0 0 0.4 0 0.6 0 94.4 0 180.4 37.4 243.6 97.8l70.4-86 24.6 20.2-73 89.4c53.6 61.6 86 141.8 86 229.4 0 102.2-44 194.6-114.4 258.6l19 19 108.2-105.2zM544 352h-224v32h192v256h32v-288z" />
-<glyph unicode="&#xe609;" d="M876.8 575.2c24.4 28.4 39.2 64.6 39.2 104.4 0.2 87.6-71 159.2-160.8 164.2-3.2 0.2-6.2 0.2-9.6 0.2-40.8 0.2-78.2-13.6-107.6-36.2l107.6-104.8-21-20.8c-51.4 38.8-114 64-182 69.8v0.2c0 17-14 31-31 31s-31-14-31-31v-0.2c-67.8-5.8-130.2-31-181.4-69.8l-20.8 20.8 107.6 104.8c-29.4 22.8-66.8 36.4-107.4 36.2-3.2 0-6.4-0.2-9.6-0.2-90-5-161.2-76.6-160.8-164.2 0-39.6 14.8-76 39.2-104.4l108 105.2 19-19c-70.2-63.8-114.2-156-114.2-258.4 0-87.8 32.4-168 86-229.4l-72.8-89.2 24.6-20.4 70.4 85.8c63.2-60.4 148.8-97.8 243.2-97.8h0.2c0 0 0.4 0 0.6 0 94.4 0 180.4 37.4 243.6 97.8l70.4-86 24.6 20.2-73 89.4c53.6 61.6 86 141.8 86 229.4 0 102.2-44 194.6-114.4 258.6l19 19 108.2-105.2zM152.4 624.4c-8.4 17.2-12.8 36.8-13 56-0.2 70.2 56.8 129.2 131 133.6 25.4 1.4 46.2-2.8 64.2-12.2l-182.2-177.4zM831.8 407c0-175.4-144-314.2-320.2-314.2-176 0-319.6 138.8-319.6 314.2 0 175.4 143.6 317.4 319.8 317.4 176.2 0 320-141.8 320-317.4zM689.4 801.6c17.6 9.6 38.6 13.6 64.2 12.2 74.4-4 131.2-63 131-133.6 0-19.2-4.6-38.8-13-56.2l-182.2 177.6zM512 640v-256h-192v-32h224v288z" />
-<glyph unicode="&#xe60a;" d="M800 458.8c0 75.4-60.8 138.2-135.8 138.2-5.6 0-11.4 0.2-16.8-0.6-16.6 73.8-82.2 133.6-160.6 133.6-91 0-164.6-78.2-164.6-169.6 0-5.6 0.2-11 0.8-16.4-55.4-5-99-54.6-99-111.8 0-58.6 45.8-109.6 103.2-112.6l-51-74.8 26.6-19.4 64.2 94.2h72.2l-94.2-138.2 26.6-19.4 107.4 157.6h75.8l-52-75.4 26.6-19.4 65.2 94.8h69.4c0.2 0 0.6 0 0.8 0l-94.2-138.2 26.6-19.4 113.2 166.2c52.4 19.8 89.6 71.6 89.6 130.6z" />
-<glyph unicode="&#xe60b;" d="M800 458.8c0 75.4-60.8 138.2-135.8 138.2-5.6 0-11.4 0.2-16.8-0.6-16.6 73.8-82.2 133.6-160.6 133.6-91 0-164.6-78.2-164.6-169.6 0-5.6 0.2-11 0.8-16.4-55.4-5-99-54.6-99-111.8 0-58.6 45.8-109.6 103.2-112.6l-51-74.8 26.6-19.4 64.2 94.2h72.2l-94.2-138.2 26.6-19.4 107.4 157.6h75.8l-52-75.4 26.6-19.4 65.2 94.8h69.4c0.2 0 0.6 0 0.8 0l-94.2-138.2 26.6-19.4 113.2 166.2c52.4 19.8 89.6 71.6 89.6 130.6zM664.2 355.8h-84.2l-0.2 0.2-0.2-0.2h-246.8c-20 0-39 8.8-53.4 23.4s-22.2 34.4-22.2 55c0 39.4 30.4 71.4 69.8 78 3.4 0.6 18.4 2.8 30 3.8 0 0-1 11.2-1.4 20.2-0.4 9-0.2 19.8-0.2 24.2 0 72.8 59 136.2 131.6 136.2 30.4 0 59-14.2 82.6-33.2 23-18.6 39.2-44.8 45.6-73.6l6.6-29.4 29.8 3.6c4.4 0.6 8.6 0.8 12.8 0.8 56.6 0 102.6-47.4 102.6-104.4-0.2-57.4-46.2-104.6-102.8-104.6z" />
-<glyph unicode="&#xe60c;" d="M192 218.2c0-31 25.4-58.2 56.4-58.2h532.6c31 0 51 27.2 51 58.2v325.8h-640v-325.8zM832 622.4c0 31-20 49.6-51 49.6 0 0-309.4 0-334 0-9.4 0-21.4 19.8-37 38-14.2 16.6-29.4 26-41 26-15 0-120.6 0-120.6 0-31 0-56.4-17.8-56.4-48.6v-111.4h640v46.4z" />
-<glyph unicode="&#xe60d;" d="M894.2 447.6c-90.6 104.4-215.8 224.4-382.2 224.4-67.2 0-128.8-19-193.8-59.6-54.8-34.4-111-82.8-188.2-162.4l-2-2 13.4-13.8c110.2-112.8 205.4-210.2 370.6-210.2 73 0 143.8 23.8 216.4 72.8 61.8 41.8 114.4 94.8 156.6 137.6l11 11-1.8 2.2zM512 640c66.2 0 129.8-19 194.4-61.2 47.8-31.2 94.8-73.4 147.4-132.2-76.6-77.4-191.6-190.6-341.8-190.6-68.4 0-128.4 16.8-188.4 56.4-55 36.2-104.6 86.6-152.4 135.6 118.2 119.4 216.8 192 340.8 192zM512 288c88.2 0 160 71.8 160 160s-71.8 160-160 160c-88.2 0-160-71.8-160-160 0-88.2 71.8-160 160-160zM512 575.4c70.4 0 128-57.2 128-127.4s-57.6-127.4-128-127.4c-70.4 0-127.8 57.2-127.8 127.4 0 70.2 57.4 127.4 127.8 127.4zM576 448v0c0-35-28.8-64-63.6-64s-64.4 30.4-64.4 65.4 31.6 62.6 64 62.6v32c-53 0-95.8-43.2-95.8-96.4 0-53.2 43-96.2 95.8-96.2s96 43.2 96 96.2v0.4h-32z" />
-<glyph unicode="&#xe60e;" d="M513.6 640c-51.4 0-99.6-20-135.8-56.2s-56.2-84.4-56.2-135.8 20-99.4 56.2-135.8c36.2-36.2 84.6-56.2 135.8-56.2 51.4 0 99.6 20 135.8 56.2 36.2 36.2 56.2 84.4 56.2 135.8s-20 99.4-56.2 135.8c-36.2 36.2-84.4 56.2-135.8 56.2zM513.6 288c-88.6 0-160 71.8-160 160s71.4 160 160 160c88.6 0 160-71.8 160-160 0-88.2-71.4-160-160-160zM849 528h-30.4c-24.8 0-45.6 20.8-45.6 46.4 0 12.8 5.4 24.2 15 32.8l19.6 19.2c19.4 19.2 19.4 50.4 0 69.8l-44.6 44.2c-8.8 8.8-21.8 14-35 14s-26-5.2-35-14l-18.8-18.8c-9-10-21.4-15.4-34.4-15.4-25.6 0-47.4 20.8-47.4 45.4v30.2c0 27-21 50.2-48 50.2h-60.8c-27.6 0-49.6-23-49.6-50.2v-30.4c0-24.6-21.2-45.4-46.8-45.4-12.8 0-24.4 5.4-33.2 14.8l-19.4 19.2c-8.8 9-21.8 14-35 14s-26-5.2-35-14l-44.6-44c-19.2-19.2-19.2-50.6 0-69.6l18.8-18.8c10-9 15.6-20.4 15.6-33.4 0-25.6-20.8-46.4-45.6-46.4h-30.4c-27.4 0.2-50.4-22.2-50.4-49.4v-30.4-30.4c0-27 23-49.6 50.4-49.6h30.4c24.8 0 45.6-20.8 45.6-46.4 0-12.8-5.6-24.6-15.6-33.6l-18.8-18.4c-19.2-19.2-19.2-50.4 0-69.6l44.6-44.4c8.8-9 21.8-14 35-14s26 5.2 35 14l19.4 19.2c8.4 9.4 20.2 14.8 33 14.8 25.6 0 46.8-20.8 46.8-45.4v-30.4c0-27 22-50.2 49.4-50.2h60.8c27.2 0 49.8 23 49.8 50.2v30.4c0 24.6 21 45.4 46.6 45.4 12.8 0 24.6-5.6 33.8-15.4l18.8-18.8c9-8.8 21.8-14 35-14s26 5.2 35 14l44.6 44.4c19.2 19.2 19.2 50.6 0 69.8l-19.6 19.2c-9.6 8.6-15 20.8-15 33.4 0 25.6 20.8 47.2 45.6 47.2h30.4c27.2 0 46.6 20.6 46.6 47.8v30.8 30.4c0 27.2-19.4 49.6-46.6 49.6zM864 448v-30.2c0-8.4-4.6-15.8-14.6-15.8h-30.4c-20.6 0-40.2-8.8-55-24-14.6-15-22.6-34.8-22.6-55.6 0-21.6 8.8-41.6 25-56.4l19-18.8c6.6-6.8 6.6-18 0-24.6l-44.6-44.4c-3.2-3-7.8-4.8-12.6-4.8-4.8 0-9.6 1.8-12.6 4.8l-18.2 18.2c-15.4 16.2-35.6 25.2-57 25.2-20.8 0-40-8-55-22.4-15.2-14.8-23.2-34.2-23.2-55v-30.4c0-9.8-8.6-18.2-17.8-18.2h-60.8c-9.2 0-17.4 8.4-17.4 18.2v30.4c0 20.6-8.2 40.2-23.4 55-15 14.4-34.6 22.4-55.2 22.4-21.2 0-41.6-9-56.2-24.8l-18.6-18.6c-3.2-3-7.8-4.8-12.6-4.8s-9.6 1.6-12.2 4.4l-0.4 0.4-44.6 44.4c-6.6 6.6-6.6 17.6 0 24.4l18.2 18c16.4 15.2 25.4 35.4 25.4 57 0 20.8-8 39.8-22.6 54.8-14.8 15.2-34.4 23-55 23h-30.6c-10 0-18.4 8.6-18.4 17.6v30.6 30.4c0 9 8.4 17.6 18.4 17.6h30.4c20.6 0 40.2 7.8 55 23 14.6 15 22.6 34.4 22.6 55 0 21.6-9 41.8-25.4 56.8l-18.4 18.2c-4.4 4.4-5 9.4-5 12.2 0 2.6 0.6 7.8 5 12.2l44.4 44.2c3.2 3 7.8 4.8 12.6 4.8s9.6-1.6 12.2-4.4l19.2-19.2c14.8-16 34.8-24.8 56.2-24.8 20.8 0 40.2 8 55.2 22.4 15.2 14.8 23.6 34.2 23.6 55v30.4c0 9.8 8 18.2 17 18.2h61c9 0 16-8.4 16-18.2v-30.4c0-20.6 8.8-40.2 24-55 15-14.4 34.8-22.4 55.6-22.4 21.6 0 42 9 57.2 25.2l18.2 18.2c3.2 3 7.8 4.8 12.6 4.8 4.8 0 9.6-1.8 12.6-4.6l44.6-44.2c3.2-3.2 5.2-7.6 5.2-12.2 0-4.6-1.8-9-5-12.2l-19-18.8c-16-14.8-25-34.8-25-56.4 0-20.8 8-39.8 22.6-54.8 14.8-15.2 34.4-23 55-23h30.4c10.8 0 14.8-10 15-18v-30z" />
-<glyph unicode="&#xe60f;" d="M849 527h-30.4c-24.8 0-45.6 21.4-45.6 46.8 0 12.8 5.4 24.4 15 33l19.6 19.2c19.4 19.2 19.4 50.6 0 69.8l-44.6 44.2c-8.8 8.8-21.8 14-35 14s-26-5.2-35-14l-18.8-18.8c-9-10-21-15.4-34-15.4-25.6 0-47 20.8-47 45.4v30.6c0 27-21.8 50.2-49 50.2h-60.8c-27.2 0-48.8-23-48.8-50.2v-30.4c0-24.6-21.4-45.4-47-45.4-12.8 0-24.6 5.4-33.2 14.8l-19.4 19.2c-8.8 9-21.8 14-35 14s-26-5.2-35-14l-45-44c-19.2-19.2-19.2-50.6 0-69.6l18.8-18.8c10-9 15.6-21 15.6-33.8 0-25.6-20.8-46.8-45.6-46.8h-30.4c-27.4 0-50.4-21.4-50.4-48.6v-30.4-30.4c0-27 23-48.6 50.4-48.6h30.4c24.8 0 45.6-21.4 45.6-46.8 0-12.8-5.6-24.8-15.6-33.8l-18.8-18.6c-19.2-19.2-19.2-50.6 0-69.6l44.6-44.4c8.8-9 21.8-14 35-14s26 5.2 35 14l19.4 19.2c8.4 9.4 20.4 14.8 33.2 14.8 25.6 0 47-20.8 47-45.4v-30.4c0-27 21.6-50.2 49-50.2h60.8c27.2 0 48.8 23 48.8 50.2v30.4c0 24.6 21.4 45.4 47 45.4 12.8 0 24.8-5.6 34-15.4l18.8-18.8c9-8.8 21.8-14 35-14s26 5.2 35 14l44.6 44.4c19.2 19.2 19.2 50.6 0 69.8l-19.6 19.2c-9.6 8.6-15 20.4-15 33 0 25.6 20.8 46.8 45.6 46.8h30.4c27.2 0 46.6 21.4 46.6 48.6v30.6 30.4c0.4 27.2-19 48.6-46.2 48.6zM673.6 448v0c0-88.2-71.4-160-160-160s-160 71.8-160 160v0 0c0 88.2 71.4 160 160 160s160-71.8 160-160v0z" />
-<glyph unicode="&#xe610;" d="M575.6 480c17.6 0 32.2-14.4 32.2-32s-14-32-31.8-32h-128c-17.6 0-32 14.4-32 32s14.4 32 32 32h126M576 512h-128c-35.2 0-64-28.8-64-64s28.8-64 64-64h128c35.2 0 64 28.8 64 64s-28.8 64-64 64v0zM832 736h-640v-160h32v-416h576v416h32v160zM768 192h-512v384h512v-384zM800 608h-576v96h576v-96z" />
-<glyph unicode="&#xe611;" d="M224 160h576v384h-576v-384zM448 480h128c17.6 0 32-14.4 32-32s-14.4-32-32-32h-128c-17.6 0-32 14.4-32 32s14.4 32 32 32zM192 736v-160h640v160z" />
-<glyph unicode="&#xe612;" d="M160 352h704v-32h-704v32zM160 464h704v-32h-704v32zM160 576h704v-32h-704v32z" />
-<glyph unicode="&#xe613;" d="M851 690.4c9.4 11.8 15 27 15 43.2 0 38.4-31.2 69.8-69.6 69.8-16.4 0-31.4-5.6-43.2-15-68 48.4-150 75.6-239.8 75.6-229.8 0-417.4-185-417.4-415.2 0-230.2 187.4-416.8 417.2-416.8 229.8 0 414.8 186.6 414.8 416.8 0 90-28.6 173.4-77 241.6zM796 777.4c24.4 0 44-19.8 44-44 0-24.4-19.8-44-44-44-24.4 0-44 19.8-44 44 0 24.2 19.6 44 44 44zM783.6 176.6c-35.2-35.2-76.4-63.2-122.2-82.6-47.4-20-96.4-30.4-148.4-30.4-51.8 0-103.4 10.2-150.8 30.4-45.8 19.4-86.8 47-122.2 82.6-35.2 35.2-63 76.6-82.4 122.4-20 47.4-30.2 97.8-30.2 149.8 0 51.8 10.2 102.4 30.2 149.8 19.4 45.8 47 87 82.4 122.4s76.4 63.2 122.2 82.6c47.4 20 98.8 28.2 150.8 28.2 51.8 0 101-8 148.4-28.2 25.4-10.8 49.4-24.2 71.8-40-4.2-9-6.6-19-6.6-29.8 0-38.4 31.2-69.8 69.6-69.8 10.6 0 20.6 2.4 29.8 6.6 15.8-22.4 29.2-46.4 40-72 20-47.4 30.2-97.8 30.2-149.8 0-51.8-10.2-102.4-30.2-149.8-19.4-45.8-47-87-82.4-122.4zM513 639.8c-106 0-192-85.6-192-191.8s85.8-192.2 192-192.2c106 0 192 86 192 192.2s-86 191.8-192 191.8zM513 288.4c-88.2 0-159.4 71.6-159.4 159.6 0 88.2 71.2 159.2 159.4 159.2s159.4-71.2 159.4-159.2c0-88.2-71.4-159.6-159.4-159.6z" />
-<glyph unicode="&#xe614;" d="M865 736h-65v96h-576v-96h-63c-35.2 0-65-27.6-65-62.6v-316.8c0-35 29.8-64.6 65-64.6h95v-228h512v228h97c35.2 0 63 29.6 63 64.6v316.8c0 35-27.8 62.6-63 62.6zM256 800h512v-64h-512v64zM736 96h-448v384h448v-384zM896 356.6c0-17.4-13.4-32.6-31-32.6h-97v188h-512v-188h-95c-17.6 0-33 15.2-33 32.6v316.8c0 17.4 15.4 30.6 33 30.6h704c17.6 0 31-13.2 31-30.6v-316.8z" />
-<glyph unicode="&#xe615;" d="M640 734v39.4c0 32.4-26.2 58.6-58.6 58.6h-139c-32.2 0-58.4-26.2-58.4-58.6v-39.4h-160v-30h42.2l47.2-581.4c0-32.4 26.2-58.6 58.6-58.6h282c32.4 0 58.6 26.2 58.6 58.6l46.6 581.4h40.8v30h-160zM414 773.4c0 16.2 12.4 28.6 28.6 28.6h139c16.2 0 28.6-12.4 28.6-28.6v-39.4h-196v39.4h-0.2zM405.4 158l-21.4 482h29l21.8-482h-29.4zM526 158h-28v482h28v-482zM618.6 158h-29.2l21.6 482h29l-21.4-482z" />
-<glyph unicode="&#xe616;" d="M736 736c-22-2.8-49.8-7-79.4-7-46.2 0-88 11.4-130.4 20.4-43 9.2-87.4 18.6-134.4 18.6-93.8 0-125.6-20.2-128.8-22.4l-6.8-4.8v-5.2-323.4-284.2h32v286.6c12 5 43.6 13.8 103.8 13.8 43.6 0 84.4-16.6 127.8-26 44-9.4 89.6-19.2 139-19.2 29.4 0 55.4 4 77.4 6.6 12 1.4 22.6 2.8 32 4.4v313.8 33c-9.4-1.8-20.2-3.4-32.2-5zM736 422c-22-2.8-47.8-7-77.4-7-46.2 0-90 9.4-132.4 18.4-43 9.2-87.2 26.6-134.2 26.6-51.4 0-83.8-6-103.8-12v274.6c12 5 43.8 13.6 103.8 13.6 43.6 0 84.4-8.6 127.8-18 44-9.4 87.6-21.2 137-21.2 29.4 0 57.4 4 79.4 6.6l-0.2-281.6z" />
-<glyph unicode="&#xe617;" d="M930.8 466c-4.4 44-24.8 86-57.8 116.8-34.2 31.8-78.6 49.4-125.4 49.4-83 0-154.6-54.8-177-134-14 14-37 23.4-58.6 23.4-21.6 0-44.6-9.4-58.6-23.4-22.4 79.2-94 134-177 134-46.6 0-91.2-17.4-125.4-49.2-33-31-53.4-73-57.8-117h-29.2v-36h29.2c4.4-44 24.8-86 57.8-116.8 34.2-31.8 78.6-49.4 125.4-49.4 101.6 0 184.2 82.4 184.2 184 0 0.2 0 0.2 0 0.2v0c0 19.8 23 43.2 51.4 43.2s51.4-23.4 51.4-43.2v0c0 0 0 0 0-0.2 0-101.6 82.6-184 184.2-184 46.6 0 91.2 17.4 125.4 49.4 33 30.8 53.4 73 57.8 117h29.2v36h-29.2z" />
-<glyph unicode="&#xe618;" d="M930.8 466c-4.4 44-24.8 86-57.8 116.8-34.2 31.8-78.6 49.4-125.4 49.4-83 0-154.6-54.8-177-134-14 14-37 23.4-58.6 23.4-21.6 0-44.6-9.4-58.6-23.4-22.4 79.2-94 134-177 134-46.6 0-91.2-17.4-125.4-49.2-33-31-53.4-73-57.8-117h-29.2v-36h29.2c4.4-44 24.8-86 57.8-116.8 34.2-31.8 78.6-49.4 125.4-49.4 101.6 0 184.2 82.4 184.2 184 0 0.2 0 0.2 0 0.2v0c0 19.8 23 43.2 51.4 43.2s51.4-23.4 51.4-43.2v0c0 0 0 0 0-0.2 0-101.6 82.6-184 184.2-184 46.6 0 91.2 17.4 125.4 49.4 33 30.8 53.4 73 57.8 117h29.2v36h-29.2zM747.6 294c-85 0-154 69.2-154 154 0 85 69.2 154 154 154 85 0 154-69.2 154-154 0-85-69-154-154-154zM276.4 294c-85 0-154 69.2-154 154 0 85 69.2 154 154 154 85 0 154-69.2 154-154 0-85-69-154-154-154z" />
-<glyph unicode="&#xe619;" d="M736 736c-22-2.8-49.8-7-79.4-7-46.2 0-88 11.4-130.4 20.4-43 9.2-87.4 18.6-134.4 18.6-93.8 0-125.6-20.2-128.8-22.4l-6.8-4.8v-5.2-323.4-284.2h32v286.6c12 5 43.6 13.8 103.8 13.8 43.6 0 84.4-16.6 127.8-26 44-9.4 89.6-19.2 139-19.2 29.4 0 55.4 4 77.4 6.6 12 1.4 22.6 2.8 32 4.4v313.8 33c-9.4-1.8-20.2-3.4-32.2-5z" />
-<glyph unicode="&#xe61a;" d="M843.8 561.4c-33.4 30-78 46.6-125.2 46.6s-91.8-16.6-125.2-46.6l-63.2-57 44.8-40.4 62.2 56c21.6 19.4 50.6 30.2 81.4 30.2s59.8-10.8 81.4-30.2c21.4-19.2 33.2-44.8 33.2-72.2 0-27.2-11.8-52.8-33.2-72-21.6-19.4-50.6-30.2-81.4-30.2-30.8 0-59.8 10.8-81.4 30.2l-206.6 185.4c-33.4 30-78 46.6-125.2 46.6s-91.8-16.6-125.2-46.6c-33.6-30-52.2-70.2-52.2-113.2 0-43 18.6-83.2 52.2-113.4 33.4-30 78-46.6 125.2-46.6 47.2 0 91.8 16.6 125.2 46.6l63.2 56.8-44.8 40.4-62-55.8c-21.6-19.4-50.6-30.2-81.4-30.2s-59.8 10.8-81.4 30.2c-21.4 19.2-33.2 44.8-33.2 72 0 27.2 11.8 52.8 33.2 72.2 21.6 19.4 50.6 30.2 81.4 30.2 30.8 0 59.8-10.8 81.4-30.2l206.6-185.4c33.4-30 78-46.6 125.2-46.6s91.8 16.6 125.2 46.6c33.6 30.2 52.2 70.4 52.2 113.4-0.2 42.8-18.8 83-52.4 113.2z" />
-<glyph unicode="&#xe61b;" d="M846.6 561.2c-31.8 30.2-74.2 46.8-119.4 46.8-45.2 0-87.6-16.6-119.4-46.8l-72.4-68.6 23.4-22.4 72.4 68.8c25.6 24.2 59.6 37.6 95.8 37.6 36.2 0 70.2-13.4 95.8-37.6 52.8-50.2 52.8-131.8 0-181.8-25.6-24.2-59.6-37.6-95.8-37.6-36.2 0-70.2 13.4-95.8 37.6l-215.2 204c-32 30.2-74.4 46.8-119.4 46.8-45.2 0-87.6-16.6-119.4-46.8-65.8-62.4-65.8-163.8 0-226.2 31.8-30.2 74.2-46.8 119.4-46.8 45.2 0 87.6 16.6 119.4 46.8l72.2 68.6-23.4 22.2-72.4-68.6c-25.6-24.2-59.6-37.6-95.8-37.6s-70.2 13.4-95.8 37.6c-52.8 50.2-52.8 131.8 0 181.8 25.6 24.2 59.6 37.6 95.8 37.6 36.2 0 70.2-13.4 95.8-37.6l215.2-204c32-30.2 74.4-46.8 119.4-46.8 45.2 0 87.6 16.6 119.4 46.8 66 62.2 66 163.8 0.2 226.2z" />
-<glyph unicode="&#xe61c;" d="M882 128c0-27.6-22.4-50-50-50s-50 22.4-50 50 22.4 50 50 50 50-22.4 50-50zM306 128c0-27.6-22.4-50-50-50s-50 22.4-50 50 22.4 50 50 50 50-22.4 50-50zM255.8 768l-22.2 64h-105.6v-34h83.4l115-426.6c-64.8-22.6-119.8-75.8-130.6-146.2-3.8-23.4-3.8-33.2-3.8-33.2h704v33.4h-665.4c9.4 63.2 77.6 116.2 148.2 125s486.6 68.4 486.6 68.4l30.6 349.2h-640.2z" />
-<glyph unicode="&#xe61d;" d="M882 128c0-27.6-22.4-50-50-50s-50 22.4-50 50 22.4 50 50 50 50-22.4 50-50zM306 128c0-27.6-22.4-50-50-50s-50 22.4-50 50 22.4 50 50 50 50-22.4 50-50zM255.8 768l-22.2 64h-105.6v-34h83.4l115-426.6c-64.8-22.6-119.8-75.8-130.6-146.2-3.8-23.4-3.8-33.2-3.8-33.2h704v33.4h-665.4c9.4 63.2 77.6 116.2 148.2 125s486.6 68.4 486.6 68.4l30.6 349.2h-640.2zM832 448l-470-66.6c-1.8-0.4-3.6-0.8-5.4-1.2l-89.4 354.6h595.4l-30.6-286.8z" />
-<glyph unicode="&#xe61e;" d="M686.2 330c-3.6-0.2-7-0.2-10.6-0.2-58.2 0-113 22.6-154.2 63.8-41.2 41.2-63.8 96-63.8 154.2 0 33.2 7.4 65.2 21.2 94.2 6.2 12.8 13.6 25 22.2 36.4-15.2-1.6-29.8-4.8-44-9.2-93.6-29.6-161.4-117-161.4-220.4 0-127.6 103.4-231 231-231 70.6 0 133.6 31.6 176 81.4 9.6 11.4 18.4 23.8 25.6 37-13.6-3.4-27.6-5.6-42-6.2z" />
-<glyph unicode="&#xe61f;" d="M686.2 330c-3.6-0.2-7-0.2-10.6-0.2-58.2 0-113 22.6-154.2 63.8-41.2 41.2-63.8 96-63.8 154.2 0 33.2 7.4 65.2 21.2 94.2 6.2 12.8 13.6 25 22.2 36.4-15.2-1.6-29.8-4.8-44-9.2-93.6-29.6-161.4-117-161.4-220.4 0-127.6 103.4-231 231-231 70.6 0 133.6 31.6 176 81.4 9.6 11.4 18.4 23.8 25.6 37-13.6-3.4-27.6-5.6-42-6.2zM526.6 249.8c-109.8 0-199 89.2-199 199 0 78.2 45.2 145.8 110.8 178.4-8.4-25-12.8-51.6-12.8-79.4 0-131.8 102-239.8 231.2-249.4-34.8-30.4-80.4-48.6-130.2-48.6z" />
-<glyph unicode="&#xe620;" d="M427 192l114 152h-64.4zM656.8 606.6c-5.4 0-10.8 0-16-0.6-15.8 70-78.2 122.8-152.8 122.8-86.6 0-156.6-70.4-156.6-157 0-5.2 0.2-10.4 0.8-15.6-52.8-4.6-94.2-51.4-94.2-105.6 0-57.2 46.4-106.6 103.4-106.6h135.2l11 34h-82.6l44 198h106l-40-128h104l-78-104h115.8c71.4 0 129.2 60.2 129.2 131.8 0 71.4-57.8 130.8-129.2 130.8z" />
-<glyph unicode="&#xe621;" d="M619 448h-104l40 128h-106l-44-198h82.6l-60.6-186zM656.8 606.6c-5.4 0-10.8 0-16-0.6-15.8 70-78.2 122.8-152.8 122.8-86.6 0-156.6-70.4-156.6-157 0-5.2 0.2-10.4 0.8-15.6-52.8-4.6-94.2-51.4-94.2-105.6 0-57.2 46.4-106.6 103.4-106.6h22.6v34h-22.6c-19 0-37 8.2-50.8 22-13.6 14-21.2 32.6-21.2 52 0 37.2 29 67.6 66.4 73.8 3.2 0.6 17.6 2.6 28.4 3.6 0 0-1 10.6-1.2 19.2-0.2 8.6-0.2 18.8-0.2 23 0 69.2 56.2 125.4 125.2 125.4 29 0 56.2-9.6 78.6-27.8 21.8-17.8 37.2-42.6 43.4-69.8l6.2-28 28.4 3.6c4.2 0.6 8.2 0.8 12.2 0.8 53.8 0 97.6-44.6 97.6-98.8 0-54.2-43.8-98.8-97.6-98.8h-16.8v-34h16.8c71.4 0 129.2 60.2 129.2 131.8 0 71.2-57.8 130.6-129.2 130.6z" />
-<glyph unicode="&#xe622;" d="M488 608.4c29 0 56.2-9.6 78.6-27.8 21.8-17.8 37.2-42.6 43.4-69.8l6.2-28 28.4 3.6c4.2 0.6 8.2 0.8 12.2 0.8 53.8 0 97.6-44.2 97.6-98.4 0-54.2-43.8-98.4-97.6-98.4h-315.4c-19 0-37 7.8-50.8 21.6-13.6 14-21.2 32.4-21.2 51.8 0 37.2 29 67.6 66.4 73.8 3.2 0.6 17.6 2.4 28.4 3.4 0 0-1 10.6-1.2 19.2-0.2 8.6-0.2 18.8-0.2 23 0.2 68.8 56.2 125.2 125.2 125.2M488 640c-86.6 0-156.6-70.4-156.6-157 0-5.2 0.2-10.4 0.8-15.6-52.8-4.6-94.2-51-94.2-105.2 0-57.2 46.4-106.2 103.4-106.2h315.4c71.4 0 129.2 59.8 129.2 131.4s-57.8 130.6-129.2 130.6c-5.4 0-10.8 0-16-0.6-15.8 70-78.2 122.6-152.8 122.6v0z" />
-<glyph unicode="&#xe623;" d="M496 768h32v-118h-32v118zM496 246h32v-118h-32v118zM714 464h118v-32h-118v32zM192 464h118v-32h-118v32zM736.539 251.474l-23.759-23.759-67.599 67.599 23.759 23.759 67.599-67.599zM383.109 604.814l-23.759-23.759-67.74 67.74 23.759 23.759 67.74-67.74zM712.626 672.51l23.755-23.762-67.608-67.589-23.755 23.762 67.608 67.589zM359.275 319.064l23.755-23.762-67.75-67.731-23.755 23.762 67.75 67.731zM514.2 298.6c-83.6 0-151.6 68-151.6 151.6s68 151.6 151.6 151.6 151.6-68 151.6-151.6c-0.2-83.6-68.2-151.6-151.6-151.6z" />
-<glyph unicode="&#xe624;" d="M496 768h32v-118h-32v118zM496 246h32v-118h-32v118zM714 464h118v-32h-118v32zM192 464h118v-32h-118v32zM736.539 251.474l-23.759-23.759-67.599 67.599 23.759 23.759 67.599-67.599zM383.109 604.814l-23.759-23.759-67.74 67.74 23.759 23.759 67.74-67.74zM712.626 672.51l23.755-23.762-67.608-67.589-23.755 23.762 67.608 67.589zM359.275 319.064l23.755-23.762-67.75-67.731-23.755 23.762 67.75 67.731zM514.2 298.6c-83.6 0-151.6 68-151.6 151.6s68 151.6 151.6 151.6 151.6-68 151.6-151.6c-0.2-83.6-68.2-151.6-151.6-151.6zM514.2 568c-65 0-117.8-52.8-117.8-117.8s52.8-117.8 117.8-117.8c65 0 117.8 52.8 117.8 117.8s-52.8 117.8-117.8 117.8z" />
-<glyph unicode="&#xe625;" d="M512 736.2c0 0 0 0 0 0v0zM698.4 290.4c-22.4 7.8-59 10.2-75 16.4-11.2 4.4-29 9-34.6 16-5.8 6.8-5.8 56.2-5.8 56.2s14 13 19.8 27.6c5.8 14.6 9.6 54.2 9.6 54.2s1.2-0.4 3-0.4c4.2 0 11.8 2.8 15.4 21.2 4.4 22.6 12.8 34.4 10.6 51-1.6 11.2-6.4 13-9.2 13-1.4 0-2.4-0.4-2.4-0.4s11.4 16.8 11.4 74c0 58.8-45.4 116.8-129.2 117-84-0.2-129.2-58.2-129.2-117 0-57 11.4-74 11.4-74s-1 0.4-2.4 0.4c-3 0-7.8-1.8-9.2-13-2.2-16.6 6-28.6 10.6-51 3.6-18.4 11.2-21.2 15.4-21.2 1.8 0 3 0.4 3 0.4s3.8-39.8 9.6-54.2c5.8-14.6 19.8-27.6 19.8-27.6s0-49.4-5.8-56.2c-5.8-6.8-23.4-11.6-34.6-16-16-6.2-52.6-8.6-75-16.4-22.4-7.8-91.6-40.4-91.6-130.4h556c0 90-69 122.6-91.6 130.4zM288.2 316c18 9 35.6 9 49.2 10.8 0 0 7.6 12.4-17.4 16.8 0 0-34.2 8.6-38.2 13.4-4 4.8-1.6 31.4-1.6 31.4s47.8 1.6 66.8 18.4c-31 46.4-14.4 100.6-20.8 151.2-6.2 50.4-36.4 82-94.2 82-0.2 0 0 0-2 0v0c-56 0-84.8-31.6-91.2-82.2-6.4-50.6 12-110.8-19.8-151.4 17.8-15.8 61.8-16.6 66.8-16.6 0.4 0 0.4 0 0.4 0 0 0 0.2 0.2 0.2 0.2s2-28.4-2-33.2c-4-4.8-15.8-9.2-23.8-11-17.6-3.8-36.2-10-51.6-15.4-15.4-5.2-45-36.4-45-74.4h160.4c4.4 16 34.6 45.2 63.8 60zM799.6 256h160.4c0 38-29.6 69.2-45 74.6s-34.2 11.6-51.6 15.4c-8.2 1.8-19.8 6.2-23.8 11-4 4.8-2 33.2-2 33.2s0.2-0.2 0.2-0.2c0 0 0.2 0 0.4 0 5 0 49.2 0.6 67 16.6-31.8 40.6-13.6 100.8-20 151.4-6.4 50.4-35.2 82-91.2 82v0c-2 0-2 0-2 0-57.8 0-88.2-31.6-94.4-82.2-6.4-50.6 10.2-104.8-20.8-151.2 19-16.8 66.8-18.4 66.8-18.4s2.4-26.6-1.6-31.4-38.2-13.4-38.2-13.4c-25-4.4-17.4-16.8-17.4-16.8 13.6-1.8 31.4-1.8 49.2-10.8 29.4-14.6 59.6-43.8 64-59.8z" />
-<glyph unicode="&#xe626;" d="M610 502c-83 0-150.4-68-150.4-151.8 0-5 0.2-10.2 0.8-15-50.8-4.6-90.4-50.8-90.4-103 0-55.4 44.4-104 99.4-104h302.6c68.6 0 124 59.2 124 128.4s-55.6 127-124 127c-5.2 0-10.4 0.4-15.4-0.2-15.2 67.2-75 118.6-146.6 118.6v0zM416 768h32v-110h-32v110zM128 468h112v-34h-112v34zM220.6 648.2l22.4 22.6 63.8-64.2-22.4-22.6zM576.2 584.2l-22.4 22.4 63.6 64.2 22.4-22.6zM243 249l-22.4 22.6 63.8 64.2 22.4-22.6zM413.4 388.8c1 0.2 1.8 0.2 2.8 0.4 0 0.4 0 0.6 0 1-0.4-0.2-1-0.4-1.4-0.6-0.6-0.4-1-0.6-1.4-0.8zM430.2 603.6c-78.8 0-142.8-64.4-142.8-143.6 0-46.8 22.4-88.2 56.8-114.6 6.4-4.8 13-9.2 20.2-12.8 9 24.2 26.6 44.6 49 56.2 0.4 0.2 0.8 0.4 1.4 0.8 0.4 0.2 1 0.4 1.4 0.6-0.4 4.6-0.6 9.4-0.6 14-0.6 63.8 60.6 139.2 122.2 149 0.2 0.2 0.6 0.2 0.8 0.4-26.4 30.6-65.2 50-108.4 50z" />
-<glyph unicode="&#xe627;" d="M512 736.2c0 0 0 0 0 0v0zM698.4 290.4c-22.4 7.8-59 10.2-75 16.4-11.2 4.4-29 9-34.6 16-5.8 6.8-5.8 56.2-5.8 56.2s14 13 19.8 27.6c5.8 14.6 9.6 54.2 9.6 54.2s1.2-0.4 3-0.4c4.2 0 11.8 2.8 15.4 21.2 4.4 22.6 12.8 34.4 10.6 51-1.6 11.2-6.4 13-9.2 13-1.4 0-2.4-0.4-2.4-0.4s11.4 16.8 11.4 74c0 58.8-45.4 116.8-129.2 117-84-0.2-129.2-58.2-129.2-117 0-57 11.4-74 11.4-74s-1 0.4-2.4 0.4c-3 0-7.8-1.8-9.2-13-2.2-16.6 6-28.6 10.6-51 3.6-18.4 11.2-21.2 15.4-21.2 1.8 0 3 0.4 3 0.4s3.8-39.8 9.6-54.2c5.8-14.6 19.8-27.6 19.8-27.6s0-49.4-5.8-56.2c-5.8-6.8-23.4-11.6-34.6-16-16-6.2-52.6-8.6-75-16.4-22.4-7.8-91.6-40.4-91.6-130.4h556c0 90-69 122.6-91.6 130.4zM294.2 232.8c18.4 19.4 39.2 27.6 41.6 28.4 8.8 3 23.2 5.4 35.8 7.4 15 2.2 29 4.4 40 8.6 2 0.8 4.6 1.8 7.4 2.8 14.2 5 30.2 10.6 40.4 22.6 7.8 9.2 10.6 21.8 12.2 49.4 0.8 14 0.4 26.8 0.4 27.4v13.8l-9.8 9.4c-2.2 2-9.4 10-11.8 16-2.4 6-5.6 28.4-7 41-2.4 23-12 11-19.4 30.4-4 10.4-5.8 22.8-8.6 32.4-2.8 9.8 12.8 18.4 9.2 30.6-3.8 12.2-10 27.8-10 66.4 0 41 30.6 84.6 97.2 84.8 66.6 0 97.2-43.8 97.2-84.8 0-38.6-6.2-54.2-10-66.4-3.8-12.2 12-20.8 9.2-30.6-2.8-9.8-4.6-22-8.6-32.4-7.6-19.4-17-7.4-19.4-30.4-1.4-12.6-4.6-34.8-7-41-2.4-6-9.4-14-11.6-16l-9.6-9.4v-13.8c0-0.6-0.4-13.4 0.2-27.4 1.6-27.6 4.2-40.2 12-49.4 10.2-12 26.2-17.6 40.4-22.6 2.8-1 5.4-2 7.4-2.8 11-4.2 25.2-6.4 40-8.6 12.6-1.8 27-4.2 35.8-7.4 2.4-0.8 23.2-9.2 41.6-28.4 11.8-12.4 20-22.8 24.6-40.8h-484.2c4.4 18 12.6 28.2 24.4 40.8zM288.2 316c18 9 35.6 9 49.2 10.8 0 0 7.6 12.4-17.4 16.8 0 0-34.2 8.6-38.2 13.4-4 4.8-1.6 31.4-1.6 31.4s47.8 1.6 66.8 18.4c-31 46.4-14.4 100.6-20.8 151.2-6.2 50.4-36.4 82-94.2 82-0.2 0 0 0-2 0v0c-56 0-84.8-31.6-91.2-82.2-6.4-50.6 12-110.8-19.8-151.4 17.8-15.8 61.8-16.6 66.8-16.6 0.4 0 0.4 0 0.4 0 0 0 0.2 0.2 0.2 0.2s2-28.4-2-33.2c-4-4.8-15.8-9.2-23.8-11-17.6-3.8-36.2-10-51.6-15.4-15.4-5.2-45-36.4-45-74.4h160.4c4.4 16 34.6 45.2 63.8 60zM205.6 288h-97.8c4.8 8 9.8 11.6 12.4 13 14.2 5 31.4 10.2 47.4 13.6 6.8 1.4 29.6 7.4 41.6 21.8 6 7 12 18 9.2 56l-1.2 28.6-28.6 1c0 0-2.2 0-2.2 0h-1.2c-7.4 0-14.8 0.8-21.4 1.8 8.4 27.2 7.6 56.4 6.6 83-0.6 17-1 33.8 0.8 48 4.6 36.4 22.2 55.2 58.6 55.2h1.4c40 0 58.8-18.4 63.6-55.4 1.8-14.2 1.6-29.8 1.2-46-0.6-26.8-1.2-56.2 8.2-85.4-0.8-0.2-1.4-0.4-2.2-0.6-12-2.2-22.4-2.6-22.4-2.6l-28.2-1-2.6-28c-3.2-35 2.4-47 8.8-54.6 0.2-0.2 0.2-0.2 0.4-0.4-11.4-7.2-22.6-16.8-32.6-26-8.2-7-14.6-14-19.8-22zM799.6 256h160.4c0 38-29.6 69.2-45 74.6s-34.2 11.6-51.6 15.4c-8.2 1.8-19.8 6.2-23.8 11-4 4.8-2 33.2-2 33.2s0.2-0.2 0.2-0.2c0 0 0.2 0 0.4 0 5 0 49.2 0.6 67 16.6-31.8 40.6-13.6 100.8-20 151.4-6.4 50.4-35.2 82-91.2 82v0c-2 0-2 0-2 0-57.8 0-88.2-31.6-94.4-82.2-6.4-50.6 10.2-104.8-20.8-151.2 19-16.8 66.8-18.4 66.8-18.4s2.4-26.6-1.6-31.4-38.2-13.4-38.2-13.4c-25-4.4-17.4-16.8-17.4-16.8 13.6-1.8 31.4-1.8 49.2-10.8 29.4-14.6 59.6-43.8 64-59.8zM798.8 310.2c-10 9.2-21.2 18.8-32.6 26 0.2 0.2 0.2 0.2 0.4 0.4 6.4 7.8 12 19.8 8.8 54.6l-2.6 28-28.2 1c0 0-10.4 0.4-22.4 2.6-0.8 0.2-1.6 0.4-2.2 0.6 9.4 29 8.8 58.6 8.2 85.4-0.4 16.2-0.6 31.8 1.2 46 4.6 37 23.6 55.4 63.6 55.4h1.4c36.4 0 53.8-18.8 58.6-55.2 1.8-14.2 1.2-31 0.8-48-0.8-26.6-1.8-55.8 6.6-83-6.6-1-14-1.8-21.4-1.8h-1.2c0 0-2.2 0-2.2 0l-28.8-0.8-1.2-28.6c-2.8-38.2 3.4-49 9.2-56 12-14.4 35-20.4 41.6-21.8 15.8-3.4 33.2-8.6 47.4-13.6 2.6-1.4 7.6-5 12.4-13h-97.8c-5.2 7.6-11.6 14.6-19.6 21.8z" />
-<glyph unicode="&#xe628;" d="M726.6 232.2c-25.8 9.2-62.8 12.4-86.4 17.6-13.6 3-33.4 10.6-40 18.4-6.6 8-2.6 81.8-2.6 81.8s12.2 19.2 18.8 36 13.8 62.8 13.8 62.8 13.6 0 18.4 23.8c5.2 26 13.2 36.8 12.2 56.2-1 18-10.4 19-11.4 19v0c0 0 9.8 27.2 11.2 84.8 1.6 68.2-50.6 135.4-148.6 135.4s-150-67-148.6-135.2c1.2-57.4 11.2-84.8 11.2-84.8v0c-1 0-10.4-1-11.4-19-1-19.4 7.2-29.8 12.2-55.8 4.8-23.8 18.4-24 18.4-24s7.2-46.2 13.8-63c6.6-17 18.8-36 18.8-36s4-73.8-2.6-81.8c-6.6-8-26.4-15.4-40-18.4-23.8-5.2-60.6-8.6-86.4-17.8-25.8-9.2-105.4-40.2-105.4-104.2h640c0 64-79.6 95-105.4 104.2z" />
-<glyph unicode="&#xe629;" d="M404.8 556.6v0 0zM726.6 232.2c-25.8 9.2-62.8 12.4-86.4 17.6-13.6 3-33.4 10.6-40 18.4-6.6 8-2.6 81.8-2.6 81.8s12.2 19.2 18.8 36 13.8 62.8 13.8 62.8 13.6 0 18.4 23.8c5.2 26 13.2 36.8 12.2 56.2-1 18-10.4 19-11.4 19v0c0 0 9.8 27.2 11.2 84.8 1.6 68.2-50.6 135.4-148.6 135.4s-150-67-148.6-135.2c1.2-57.4 11.2-84.8 11.2-84.8v0c-1 0-10.4-1-11.4-19-1-19.4 7.2-29.8 12.2-55.8 4.8-23.8 18.4-24 18.4-24s7.2-46.2 13.8-63c6.6-17 18.8-36 18.8-36s4-73.8-2.6-81.8c-6.6-8-26.4-15.4-40-18.4-23.8-5.2-60.6-8.6-86.4-17.8-25.8-9.2-105.4-40.2-105.4-104.2h640c0 64-79.6 95-105.4 104.2zM512 160h-274.6c4 6 9.4 10.2 16.4 15.2 14 10.2 32.2 19.6 54.2 27.2 13.6 4.8 33.4 8 50.8 10.6 11.4 1.8 22.2 3.4 31.8 5.6 6.8 1.6 41.6 10 57.6 29.2 9 10.8 11.6 25.4 11.2 64.6-0.2 20-1.2 38.6-1.2 39.4l-0.4 8.4-4.6 7c-3 4.6-11.6 19-16 30.6-3.6 9.4-9.2 38.4-12 56.2 0 0 0.8-2-1 7.4-1.8 9.4-16.8 8.6-18.8 16-1.8 7.2-3.6 13.8-8.6 36.4-5 22.6 5.6 22.4 7.8 32.4 1.2 6.2 0 11.4 0 11.6v0c-0.6 2-8.2 26.8-9.4 75.4-0.6 26.4 9.2 51.2 27.6 69.8 21.2 21.6 52 33 89 33 38 0 68-11.4 89.2-33 18.4-18.6 28.2-43.4 27.6-69.8-1-48.4-8.6-73.2-9.4-75.4v0c0-0.2-1.2-3.4-0.8-10.4 0.4-10.8 13.6-11 8.6-33.6-5-22.6-6.8-29.2-8.6-36.4-1.8-7.2-17-6.6-18.8-16-1.8-9.4-1-7.4-1-7.4-2.8-17.8-8.4-46.8-12-56.2-4.6-11.6-13.2-26-16-30.6l-4.6-7-0.4-8.4c0-0.8-1-19.4-1.2-39.4-0.4-39.2 2.2-53.8 11.2-64.6 16-19 50.8-27.6 57.6-29.2 9.6-2.2 20.4-3.8 31.8-5.6 17.4-2.6 37.2-5.8 50.8-10.6 22-7.8 40.4-17.2 54.2-27.4 7-5 12.4-9.2 16.4-15.2l-274.4 0.2z" />
-<glyph unicode="&#xe62a;" d="M512 896c-148 0-268.4-117.4-268.4-265.4 0-32.8 7-68.6 19.6-100.8h-0.2l1.2-2.4c1-2.2 2-4.4 3-6.6l244.8-520.8 244.8 520.6c1 2.2 2.2 4.4 3.2 6.8l0.8 2.2c13 32.2 19.6 66.2 19.6 100.6 0 148.4-120.4 265.8-268.4 265.8zM512 546.2c-51.8 0-93.8 42-93.8 93.8s42 93.8 93.8 93.8c51.8 0 93.8-42 93.8-93.8 0-51.8-42-93.8-93.8-93.8z" />
-<glyph unicode="&#xe62b;" d="M512 896c-148 0-268.4-117.4-268.4-265.4 0-32.8 7-68.6 19.6-100.8h-0.2l1.2-2.4c1-2.2 2-4.4 3-6.6l244.8-520.8 244.8 520.6c1 2.2 2.2 4.4 3.2 6.8l0.8 2.2c13 32.2 19.6 66.2 19.6 100.6 0 148.4-120.4 265.8-268.4 265.8zM730.2 541.2l-0.4-1c-0.6-1.2-1.2-2.6-1.8-3.8l-2-4.2-214-454.8-216 458.8c-0.6 1.2-1.2 2.4-1.6 3.6-11.8 29-18.2 61.2-18.2 90.8 0 130 105.8 233 236 233s236-102.8 236-233c-0.2-30.4-6.2-60.4-18-89.4zM512 768c-70.6 0-128-57.4-128-128s57.4-128 128-128 128 57.4 128 128-57.4 128-128 128zM512 546.2c-51.8 0-93.8 42-93.8 93.8s42 93.8 93.8 93.8c51.8 0 93.8-42 93.8-93.8 0-51.8-42-93.8-93.8-93.8z" />
-<glyph unicode="&#xe62c;" d="M832 654h-50v50h-28v-50h-50v-28h50v-50h28v50h50zM726.6 232.2c-25.8 9.2-62.8 12.4-86.4 17.6-13.6 3-33.4 10.6-40 18.4-6.6 8-2.6 81.8-2.6 81.8s12.2 19.2 18.8 36c6.6 16.8 13.8 62.8 13.8 62.8s13.6 0 18.4 23.8c5.2 26 13.2 36.8 12.2 56.2-1 18-10.4 19-11.4 19 0 0 0 0 0 0s9.8 27.2 11.2 84.8c1.6 68.2-50.6 135.4-148.6 135.4-98 0-150-67-148.6-135.2 1.2-57.4 11.2-84.8 11.2-84.8s0 0 0 0c-1 0-10.4-1-11.4-19-1-19.4 7.2-29.8 12.2-55.8 4.8-23.8 18.4-24 18.4-24s7.2-46.2 13.8-63c6.6-17 18.8-36 18.8-36s4-73.8-2.6-81.8c-6.6-8-26.4-15.4-40-18.4-23.8-5.2-60.6-8.6-86.4-17.8-25.8-9.2-105.4-40.2-105.4-104.2h640c0 64-79.6 95-105.4 104.2z" />
-<glyph unicode="&#xe62d;" d="M793.2 256l38.8 41.4-320 342.6-320-342.6 38.6-41.4 281.4 301z" />
-<glyph unicode="&#xe62e;" d="M793.2 640l38.8-41.4-320-342.6-320 342.6 38.6 41.4 281.4-301z" />
-<glyph unicode="&#xe62f;" d="M896 192v484.4l-262.2-199.6 136.2-154.8-4-4-157.8 139.2-96.2-73.2-96.2 73.2-157.8-139.2-4 4 136 154.8-262 199.2v-484zM879.4 704h-735.4l368-279.8z" />
-<glyph unicode="&#xe630;" d="M128 704v-512h768v512h-768zM512 424.2l-325.6 247.8h651.2l-325.6-247.8zM160 224v427.8l230.2-175.2-136.2-154.6 4-4 157.8 139.2 96.2-73.2 96.2 73.2 157.8-139.2 4 4-136.2 154.8 230.2 175v-427.8h-704z" />
-<glyph unicode="&#xe631;" d="M192 460.8l212-93.4 428 400.6zM832 768l-396.2-431.4 103.8-208.6z" />
-<glyph unicode="&#xe632;" d="M192 460.8l233.2-102.6 114.4-230.2 292.4 640-640-307.2zM456.2 367l311.4 332.4-229.2-497.8-82.2 165.4zM763.6 703.4l-330-314.2-165.6 72.8 495.6 241.4z" />
-<glyph unicode="&#xe633;" d="M832 654h-50v50h-28v-50h-50v-28h50v-50h28v50h50zM404.8 556.6c0 0 0 0 0 0v0zM726.6 232.2c-25.8 9.2-62.8 12.4-86.4 17.6-13.6 3-33.4 10.6-40 18.4-6.6 8-2.6 81.8-2.6 81.8s12.2 19.2 18.8 36c6.6 16.8 13.8 62.8 13.8 62.8s13.6 0 18.4 23.8c5.2 26 13.2 36.8 12.2 56.2-1 18-10.4 19-11.4 19 0 0 0 0 0 0s9.8 27.2 11.2 84.8c1.6 68.2-50.6 135.4-148.6 135.4-98 0-150-67-148.6-135.2 1.2-57.4 11.2-84.8 11.2-84.8s0 0 0 0c-1 0-10.4-1-11.4-19-1-19.4 7.2-29.8 12.2-55.8 4.8-23.8 18.4-24 18.4-24s7.2-46.2 13.8-63c6.6-17 18.8-36 18.8-36s4-73.8-2.6-81.8c-6.6-8-26.4-15.4-40-18.4-23.8-5.2-60.6-8.6-86.4-17.8-25.8-9.2-105.4-40.2-105.4-104.2h640c0 64-79.6 95-105.4 104.2zM512 160h-274.6c4 6 9.4 10.2 16.4 15.2 14 10.2 32.2 19.6 54.2 27.2 13.6 4.8 33.4 8 50.8 10.6 11.4 1.8 22.2 3.4 31.8 5.6 6.8 1.6 41.6 10 57.6 29.2 9 10.8 11.6 25.4 11.2 64.6-0.2 20-1.2 38.6-1.2 39.4l-0.4 8.4-4.6 7c-3 4.6-11.6 19-16 30.6-3.6 9.4-9.2 38.4-12 56.2 0 0 0.8-2-1 7.4-1.8 9.4-16.8 8.6-18.8 16-1.8 7.2-3.6 13.8-8.6 36.4-5 22.6 5.6 22.4 7.8 32.4 1.2 6.2 0 11.4 0 11.6 0 0 0 0 0 0-0.6 2-8.2 26.8-9.4 75.4-0.6 26.4 9.2 51.2 27.6 69.8 21.2 21.6 52 33 89 33 38 0 68-11.4 89.2-33 18.4-18.6 28.2-43.4 27.6-69.8-1-48.4-8.6-73.2-9.4-75.4 0 0 0 0 0 0 0-0.2-1.2-3.4-0.8-10.4 0.4-10.8 13.6-11 8.6-33.6-5-22.6-6.8-29.2-8.6-36.4-1.8-7.2-17-6.6-18.8-16s-1-7.4-1-7.4c-2.8-17.8-8.4-46.8-12-56.2-4.6-11.6-13.2-26-16-30.6l-4.6-7-0.4-8.4c0-0.8-1-19.4-1.2-39.4-0.4-39.2 2.2-53.8 11.2-64.6 16-19 50.8-27.6 57.6-29.2 9.6-2.2 20.4-3.8 31.8-5.6 17.4-2.6 37.2-5.8 50.8-10.6 22-7.8 40.4-17.2 54.2-27.4 7-5 12.4-9.2 16.4-15.2h-274.4z" />
-<glyph unicode="&#xe634;" d="M895.8 223.6c0 33.6 7.2 166.2-97.4 271.4-70.4 70.8-160.6 106.8-286.6 112.4v160.6l-383.8-256 384-256v159.6c80-2.2 124.8-18.2 173.4-40 61.8-27.6 110.6-88 151.6-153.2l38.4-62.4h20.6c0 20.2-0.2 45.8-0.2 63.6z" />
-<glyph unicode="&#xe635;" d="M895.8 223.6c0 33.6 7.2 166.2-97.4 271.4-70.4 70.8-160.6 106.8-286.6 112.4v160.6l-383.8-256 384-256v159.6c80-2.2 124.8-18.2 173.4-40 61.8-27.6 110.6-88 151.6-153.2l38.4-62.4h20.6c0 20.2-0.2 45.8-0.2 63.6zM864.4 237.2c-95.2 161.6-202.4 210.8-384.4 210.8v-129.6l-296.2 193.4 296.2 193.6v-129.4c402 0 384.4-338.8 384.4-338.8z" />
-<glyph unicode="&#xe636;" d="M128 160h20.6l38.4 62.4c41 65.4 89.8 125.6 151.6 153.2 48.8 21.8 93.4 37.8 173.4 40v-159.6l384 256-384 256v-160.6c-126-5.6-216.2-41.4-286.6-112.4-104.6-105.4-97.4-238-97.4-271.4 0.2-17.8 0-43.4 0-63.6z" />
-<glyph unicode="&#xe637;" d="M128 160h20.6l38.4 62.4c41 65.4 89.8 125.6 151.6 153.2 48.8 21.8 93.4 37.8 173.4 40v-159.6l384 256-384 256v-160.6c-126-5.6-216.2-41.4-286.6-112.4-104.6-105.4-97.4-238-97.4-271.4 0.2-17.8 0-43.4 0-63.6zM544 576v129.4l296.2-193.6-296.2-193.4v129.6c-182 0-289.2-49.2-384.4-210.8 0 0-17.6 338.8 384.4 338.8z" />
-<glyph unicode="&#xe638;" d="M320 729.2l41.4 38.8 342.6-320-342.6-320-41.4 38.6 301 281.4z" />
-<glyph unicode="&#xe639;" d="M704 729.2l-41.4 38.8-342.6-320 342.6-320 41.4 38.6-301 281.4z" />
-<glyph unicode="&#xe63a;" d="M728.2 448c0-120-97-216.4-216.2-216.4s-216.2 97-216.2 216.4c0 119.2 97 216.2 216.2 216.2v-111.6l192 111.4-192 128v-88c-141.4 0-256-114.8-256-256.2 0-141.6 114.6-256.2 256-256.2 141.4 0 256 114.2 256 256.2h-39.8zM512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4 0-210.2-171.2-381.4-381.4-381.4z" />
-<glyph unicode="&#xe63b;" d="M896.4 414.6v64l-66.6 17.4c-1.4 8.8-3.2 17.6-5.2 26.4l55.2 41.8-24.4 59.2-68.8-9.6c-4.6 7.4-9.8 14-15 21.2l35.4 59.4-45.2 45.2-60.4-34.8c-7 5.2-14 10.2-21.4 14.6l10.6 70-59 24.6-43.2-56.6c-8.2 2-16.4 3.8-24.6 5.2l-17.4 69.4h-64l-18.4-69.8c-8-1.2-16.2-3-24.2-4.8l-43 58-59.2-24.6 9.6-71.4c-7.6-4.6-16-9-23.4-14.4l-62.6 37.4-45.2-45.2 37.6-63c-4.8-6.8-9-14-13.4-21l-71 10-24.4-59.2 57.8-43.4c-2-8-3.6-16.2-4.8-24.4l-69.6-17.8v-64l69.4-17.8c1.2-8.4 3-16.6 4.8-25l-56.8-42.6 24.6-59 70 10c4.6-7.6 9-15.4 14.2-22.6l-35.8-61.2 45.2-45.2 60.4 36.4c7.2-5.2 14.8-10 22.4-14.6l-9-68.6 59.2-24.4 41.2 55.6c8.8-2.2 17.8-3.6 26.8-5l17.6-66.2h64l16.6 66.2c9.2 1.4 18.2 3 27.2 5.2l41.4-54.2 59.2 24.4-10 67.4c7.2 4.4 13.6 9.8 20.4 14.8l58-33.8 45.2 45.2-33.6 57.8c5.6 7.6 11 14.8 15.8 22.8l67.6-9.6 24.6 59-54.4 41c2.2 9 4 17.8 5.4 27l66.6 17.2zM769.4 433.6c-1.2-25.2-6.2-50-14.6-73.8-2.6-7.2-6-15.4-10.4-24.6-10.2-21.4-22.2-39.8-37.8-57.4 0 0-5.2-5.8-12.8-13.6-7.6-7.6-12.8-12.4-12.8-12.4-17.8-15.4-38.8-28.8-59.6-38.4-7.8-3.6-15-6.2-21.4-8.4-23.8-8.4-48.6-13.4-73.6-14.6-8.4-0.4-17-0.4-25.6 0-25.2 1.4-50.2 6.4-74 14.8-7.8 2.8-15.6 6-23.2 9.6-23 11-44 25.2-62.8 42.4-2.8 2.6-5.4 5.2-7.8 7.6-3 3-6.2 6.4-9.2 9.6-17.2 19-31.4 40.4-42 63.6-2.8 6.2-5.6 12.6-8 19.2 0 0-2.6 6.8-6.2 20-3.6 13.4-5.2 21-5.2 21-2.2 12.2-3.6 24.4-4.2 36.6-0.4 7.6-0.4 15.2 0 22.6 1.2 25.8 6.2 51.2 15 75.4 2.6 7 5.4 14 8.4 20.6 10.8 23.4 25.2 45 42.6 64.2 2.8 3.2 5.8 6.2 8.6 9s5.8 5.8 9 8.6c18.4 16.8 39.2 30.8 61.8 41.4 7.6 3.6 15.2 6.8 23.2 9.6 24.2 8.8 49.6 13.8 75.4 15 7.4 0.4 15 0.4 22.6 0 12.4-0.6 25-2 37.4-4.4 0 0 9.2-2 16.6-3.8 7.4-1.8 21-6.6 21-6.6 6.6-2.4 14.2-5 21.8-8.6 23.2-10.8 44.6-24.8 63.6-42 3.4-3 6.6-6 9.6-9.2 2.4-2.4 4.8-5 7.6-7.8 17.2-18.8 31.6-40 42.4-62.8 3.6-7.4 6.8-15.2 9.6-23.2 8.6-23.8 13.6-48.6 14.8-74 0.6-8.2 0.6-16.8 0.2-25.2zM556 666c-10.8 2-21.8 3.4-32.6 3.8-6.6 0.2-13.2 0.2-19.8 0-22.4-1-44.8-5.4-66-13-6.8-2.4-13.6-5.2-20.2-8.4-19.2-9.2-37.4-21.2-54-36.2-2.6-2.4-5.4-5-7.8-7.6-2.6-2.6-5-5.2-7.6-7.8-15.6-17.2-28-36.2-37.2-56.2-2.8-6-5.2-12-7.4-18-7.6-21.4-12-43.6-13-66-0.4-6.6-0.4-13.2 0-19.8 0.4-10.8 1.6-21.4 3.6-32l206.8 55.2 55.2 206zM302 373c0.4-1 0.6-1.4 0.8-2.4 2.2-6.4 4.8-12.8 7.8-19 9.2-19.8 21.4-38.6 36.8-55.6 2.6-2.8 5.2-5.6 8-8.4 2.2-2.2 4.6-4.4 6.8-6.6 16.8-15.4 35.4-27.8 55-37.2 6.6-3.2 13.4-6 20.2-8.4 21-7.6 42.8-12 64.6-13 7.4-0.4 15-0.4 22.4 0 21.8 1 43.6 5.2 64.4 12.6 6.4 2.2 12.2 4.4 18.4 7.2 18.8 8.6 37 20.6 52.2 33.6l-151.8 151.8-205.6-54.6zM724.4 522.4c-2.4 6.8-5.2 13.6-8.4 20.2-9.4 19.6-21.8 38.2-37.2 55-2.2 2.4-4.4 4.6-6.6 7-2.8 2.8-5.6 5.4-8.4 8-17 15.4-35.8 27.6-55.6 36.8-6.2 2.8-12.8 5.2-19.2 7.6-0.8 0.2-1.8 0.6-2.6 0.8l-56-207.4 151.8-151.8c14.6 16.6 24.8 32.8 33.2 50.4 3.4 7 7 14.8 9.4 21.8 7.4 20.8 11.6 42.6 12.8 64.6 0.4 7.4 0.4 15 0 22.4-1.2 21.8-5.6 43.6-13.2 64.6z" />
-<glyph unicode="&#xe63c;" d="M754.6 533.2c-2.8 7.8-6 15.6-9.6 23.2-11 23-25.2 44-42.4 62.8-2.6 2.8-5.2 5.4-7.6 7.8-3 3-6.4 6.2-9.6 9.2-19 17.2-40.4 31.4-63.6 42-7.6 3.6-15.4 6.4-21.8 8.6 0 0-13.8 4.8-21 6.6-7.4 1.8-16.6 3.8-16.6 3.8-12.4 2.4-24.8 3.8-37.4 4.4-7.6 0.4-15.2 0.4-22.6 0-25.8-1.2-51.2-6.2-75.4-15-7.8-2.8-15.6-6-23.2-9.6-22.4-10.8-43.2-24.6-61.8-41.4-3.2-2.8-6.2-5.8-9-8.6s-5.8-5.8-8.6-9c-17.4-19.2-31.8-40.8-42.6-64.2-3-6.6-5.8-13.6-8.4-20.6-8.8-24.2-13.8-49.6-15-75.4-0.4-7.4-0.4-15 0-22.6 0.6-12.2 2-24.4 4.2-36.6 0 0 1.6-7.8 5.2-21 3.6-13.4 6.2-20 6.2-20 2.4-6.6 5-13 8-19.2 10.8-23.2 24.8-44.6 42-63.6 3-3.4 6-6.6 9.2-9.6 2.4-2.4 5-4.8 7.8-7.6 18.8-17.2 40-31.6 62.8-42.4 7.4-3.6 15.2-6.8 23.2-9.6 23.8-8.6 48.6-13.6 74-14.8 8.6-0.4 17.2-0.4 25.6 0 25.2 1.2 50 6 73.6 14.6 6.2 2.2 13.6 4.8 21.4 8.4 20.8 9.6 41.8 23 59.6 38.4 0 0 5.2 4.8 12.8 12.4 7.6 7.6 12.8 13.6 12.8 13.6 15.4 17.6 27.6 36 37.8 57.4 4.4 9.2 8 17.4 10.4 24.6 8.4 23.8 13.4 48.6 14.6 73.8 0.4 8.4 0.4 17.2 0 25.6-1.6 25-6.4 49.8-15 73.6zM290.2 436.6c-0.2 6.6-0.2 13.2 0 19.8 1 22.4 5.4 44.8 13 66 2.2 6 4.6 12 7.4 18 9.2 20 21.8 39 37.2 56.2 2.4 2.6 5 5.4 7.6 7.8 2.6 2.6 5.2 5 7.8 7.6 16.4 15 34.8 27 54 36.2 6.6 3.2 13.4 6 20.2 8.4 21.4 7.6 43.6 12 66 13 6.6 0.2 13.2 0.4 19.8 0 11-0.4 21.8-1.8 32.6-3.8l-55.2-206-207-55.4c-1.8 10.6-3 21.4-3.4 32.2zM607.4 242.2c-6.2-2.8-12-5-18.4-7.2-20.8-7.4-42.6-11.6-64.4-12.6-7.4-0.4-15-0.2-22.4 0-22 1.2-43.8 5.4-64.6 13-6.8 2.4-13.6 5.2-20.2 8.4-19.6 9.4-38.2 21.8-55 37.2-2.4 2.2-4.6 4.4-6.8 6.6-2.8 2.8-5.4 5.6-8 8.4-15.4 17-27.6 35.8-36.8 55.6-2.8 6.2-5.4 12.6-7.8 19-0.4 1-0.6 1.4-0.8 2.4l205.6 54.6 151.8-151.8c-15.2-13.2-33.4-25-52.2-33.6zM737.6 435.2c-1-21.8-5.2-43.6-12.8-64.6-2.6-7.2-6.2-15-9.4-21.8-8.4-17.6-18.6-33.8-33.2-50.4l-151.8 151.8 56 207.4c0.8-0.2 1.8-0.6 2.6-0.8 6.4-2.2 13-4.6 19.2-7.6 19.8-9.2 38.6-21.4 55.6-36.8 2.8-2.6 5.6-5.2 8.4-8 2.2-2.2 4.4-4.6 6.6-7 15.4-16.8 27.8-35.4 37.2-55 3.2-6.6 6-13.4 8.4-20.2 7.6-21 11.8-42.8 13-64.8 0.4-7.2 0.4-14.8 0.2-22.2zM896.4 414.6v64l-66.6 17.4c-1.4 8.8-3.2 17.6-5.2 26.4l55.2 41.8-24.4 59.2-68.8-9.6c-4.6 7.4-9.8 14-15 21.2l35.4 59.4-45.2 45.2-60.4-34.8c-7 5.2-14 10.2-21.4 14.6l10.6 70-59 24.6-43.2-56.6c-8.2 2-16.4 3.8-24.6 5.2l-17.4 69.4h-64l-18.4-69.8c-8-1.2-16.2-3-24.2-4.8l-43 58-59.2-24.6 9.6-71.4c-7.6-4.6-16-9-23.4-14.4l-62.6 37.4-45.2-45.2 37.6-63c-4.8-6.8-9-14-13.4-21l-71 10-24.4-59.2 57.8-43.4c-2-8-3.6-16.2-4.8-24.4l-69.6-17.8v-64l69.4-17.8c1.2-8.4 3-16.6 4.8-25l-56.8-42.6 24.6-59 70 10c4.6-7.6 9-15.4 14.2-22.6l-35.8-61.2 45.2-45.2 60.4 36.4c7.2-5.2 14.8-10 22.4-14.6l-9-68.6 59.2-24.4 41.2 55.6c8.8-2.2 17.8-3.6 26.8-5l17.6-66.2h64l16.6 66.2c9.2 1.4 18.2 3 27.2 5.2l41.4-54.2 59.2 24.4-10 67.4c7.2 4.4 13.6 9.8 20.4 14.8l58-33.8 45.2 45.2-33.6 57.8c5.6 7.6 11 14.8 15.8 22.8l67.6-9.6 24.6 59-54.4 41c2.2 9 4 17.8 5.4 27l66.6 17.2zM805.2 344.8l34.6-26.2-5.6-13.4-43 6-20.8 3-11-18c-4.6-7.4-9.6-14.6-14.2-20.6l-12.6-17 10.2-17.8 21.2-36.4-10.4-10.4-54.6 31.8-16.8-12.4c-1.2-0.8-2.2-1.6-3.2-2.4-5.4-4-10.4-7.6-15.2-10.6l-18-11 3.2-21 6.4-42.6-13.4-5.6-26.4 34.6-12.8 16.6-20.4-5c-7.8-2-16.2-3.6-24.4-4.8l-21-3.2-5-20.4-10.6-42h-14.4l-11.4 42.4-5.4 20.2-20.6 3.2c-8.2 1.2-16.4 2.8-24 4.8l-20.6 5-12.6-17-26.4-35.8-13.4 5.6 6 44.4 2.8 20.6-17.8 10.8c-7.6 4.6-14 9-20 13.2l-17.2 12.6-18.6-11.4-39-23.6-10.2 10.2 23.4 40 10.6 18.2-12.2 17c-4 5.6-8 11.8-13 20l-11 18.2-21-3-45.4-6.4-5.4 13.2 53.8 40.4-4.8 20.4c-1.8 7.4-3.2 15-4.4 22.4l-3.2 20.8-20.6 5.2-45.4 11.8v14.4l66 16.8 3.4 20.8c1.2 7.6 2.6 15 4.4 22l4.8 20.4-54.6 41 5.4 13.2 67.4-9.6 11 18c3.8 6.2 7.8 12.8 12.2 18.6l12.4 17-11.2 18.4-24.8 41.6 10 10 59.6-35.6 17.2 12.4c5.2 3.8 11.4 7.6 17.8 11.4l3 1.8 17.8 10.8-2.8 20.6-6.2 47 13.4 5.6 40.6-54.8 20.6 4.8c7.2 1.6 14.4 3.2 21.8 4.2l20.6 3.2 5.4 20.4 12.2 46h14.4l11.4-45.4 5.2-20.6 21-3.4c7.4-1.2 14.8-2.6 22.2-4.4l20.2-4.8 12.6 16.6 27.6 37 13.2-5.6-6.8-45.2-3.2-21 18.2-11c6.2-3.8 12.6-8 19.4-13l16.8-12.2 17.6 10 39 22.4 10.2-10.2-22.6-38-10.8-18 12.6-17c5.4-7.4 9.6-13.6 13.2-19.2l11-17.8 20.8 3 44.2 6.2 5.6-13.4-52.4-39.4 5-20.4c1.8-7.6 3.4-15.6 4.8-23.8l3.2-20.8 20.2-5.2 42.4-11v-14.4l-42.4-11-20.4-5.2-3.2-20.8c-1.2-8.2-2.8-16.4-4.8-24.2l-5-20.4 17.4-13.4z" />
-<glyph unicode="&#xe63d;" d="M128 660v-596h596v596h-596zM300 832v-142h454v-454h142v596z" />
-<glyph unicode="&#xe63e;" d="M128 660v-596h596v596h-596zM692 96h-532v532h532v-532zM896 832h-596v-142h32v110h532v-532h-110v-32h142z" />
-<glyph unicode="&#xe63f;" d="M605.4 832l-319.4-448h191.6l-59-320 319.4 448h-191.6l59 320z" />
-<glyph unicode="&#xe640;" d="M512 384c-59.6 0-109.8 40.8-124 96h-228v-288h704v288h-228c-14.2-55.2-64.4-96-124-96zM288 512h128c0-53 43-96 96-96s96 43 96 96h256l-127 192h-1v-160h-32v160h-384v-160h-32v160h-1l-127-192h128z" />
-<glyph unicode="&#xe641;" d="M547.8 696l-33-178.2-6.8-37.8h168l-199.6-280 33 178.2 6.6 37.8h-167.8l199.6 280M605.4 832l-319.4-448h191.6l-59-320 319.4 448h-191.6l59 320z" />
-<glyph unicode="&#xe642;" d="M681.6 794c-67.6 0-129.6-31.6-169.6-83.6-40 52-102 83.6-169.6 83.6-118.2 0-214.4-96.6-214.4-215.4 0-55.8 21.2-108.8 59.8-149.2l324.2-327.4 318.4 321.6c42 40.6 65.6 95.8 65.6 155 0 118.8-96.2 215.4-214.4 215.4v0z" />
-<glyph unicode="&#xe643;" d="M512 768c-212.2 0-384-138.2-384-308.6 0-61.4 22.4-118.6 60.8-166.6 1.8-1.8 5.8-7.6 7.2-9.8 0 0-2 3.2-2.2 3.8 0 0 0 0 0 0v0c0 0 0 0 0 0 4.6-6.6 7.2-14.2 7.2-22.4 0-2.8-35.8-116-35.8-116v0c-2.6-8.8 4.2-17.8 15.2-20 1.6-0.4 3.2-0.4 4.8-0.4 2.6 0 5 0.4 7.4 1l3.2 1.2 101.2 44c1.8 0.8 18 7 20 7.8 0 0 1.2 0.4 1.2 0.4 0 0-0.2 0-1.2-0.4 6.8 2.4 14.4 3.6 22.4 3.6 7.2 0 14.2-1 20.6-3 0.2 0 0.4 0 0.4-0.2 1-0.4 2-0.6 3-1 46.2-15.8 96.8-20.6 150.2-20.6 212 0 382 128.2 382 298.6 0.4 170.4-171.6 308.6-383.6 308.6v0z" />
-<glyph unicode="&#xe644;" d="M512 736c194 0 352-124 352-276.6 0-71.8-35.2-138.4-99-187.8-65.6-50.8-154.8-78.6-251-78.6-57.8 0-102 6-139.4 18.6-1.2 0.4-2.6 1-4 1.4-0.6 0.2-1.2 0.4-1.6 0.4-9.4 2.8-19.4 4.2-29.4 4.2-11.2 0-22.2-1.8-32.6-5.2v0l-0.6-0.2c-1.2-0.4-17.8-6.6-22-8.6v0l-79.2-34.4c27.6 87.8 27.6 89.6 27.6 95.2 0 14.2-4.4 28.2-12.6 40.4-1 1.4-2 2.8-3.2 4.2-1.4 1.8-2.6 3.4-3.6 4.6-34.8 43.8-53.2 94.2-53.2 146-0.2 152.4 157.8 276.4 351.8 276.4M512 768c-212.2 0-384-138.2-384-308.6 0-61.4 22.4-118.6 60.8-166.6 1.8-1.8 5.8-7.6 7.2-9.8 0 0-2 3.2-2.2 3.8 0 0 0 0 0 0v0c0 0 0 0 0 0 4.6-6.6 7.2-14.2 7.2-22.4 0-2.8-35.8-116-35.8-116v0c-2.6-8.8 4.2-17.8 15.2-20 1.6-0.4 3.2-0.4 4.8-0.4 2.6 0 5 0.4 7.4 1l3.2 1.2 101.2 44c1.8 0.8 18 7 20 7.8 0 0 1.2 0.4 1.2 0.4 0 0-0.2 0-1.2-0.4 6.8 2.4 14.4 3.6 22.4 3.6 7.2 0 14.2-1 20.6-3 0.2 0 0.4 0 0.4-0.2 1-0.4 2-0.6 3-1 46.2-15.8 96.8-20.6 150.2-20.6 212 0 382 128.2 382 298.6 0.4 170.4-171.6 308.6-383.6 308.6v0z" />
-<glyph unicode="&#xe645;" d="M865 736h-65v96h-576v-96h-63c-35.2 0-65-27.6-65-62.6v-316.8c0-35 29.8-64.6 65-64.6h63v252h576v-252h65c35.2 0 63 29.6 63 64.6v316.8c0 35-27.8 62.6-63 62.6zM256 512h512v-448h-512v448z" />
-<glyph unicode="&#xe646;" d="M831.8 289c-29.2 30-112.2 86.2-166.6 86.2-12.6 0-23.6-2.8-32.6-8.6-26.6-17-47.8-30.2-58-30.2-5.6 0-11.6 5-24.8 16.4l-2.2 2c-36.6 31.8-44.4 40-58.6 54.8l-3.6 3.8c-2.6 2.6-4.8 5-7 7.2-12.4 12.8-21.4 22-53.2 58l-1.4 1.6c-15.2 17.2-25.2 28.4-25.8 36.6-0.6 8 6.4 21 24.2 45.2 21.6 29.2 22.4 65.2 2.6 107-15.8 33-41.6 64.6-64.4 92.4l-2 2.4c-19.6 24-42.4 36-67.8 36-28.2 0-51.6-15.2-64-23.2-1-0.6-2-1.4-3-2-27.8-17.6-48-41.8-55.6-66.4-11.4-37-19-85 35.6-184.8 47.2-86.4 90-144.4 158-214.2 64-65.6 92.4-86.8 156-132.8 70.8-51.2 138.8-80.6 186.4-80.6 44.2 0 79 0 128.6 59.8 52 62.8 30.4 101.2-0.8 133.4z" />
-<glyph unicode="&#xe647;" d="M831.8 289c-29.2 30-112.2 86.2-166.6 86.2-12.6 0-23.6-2.8-32.6-8.6-26.6-17-47.8-30.2-58-30.2-5.6 0-11.6 5-24.8 16.4l-2.2 2c-36.6 31.8-44.4 40-58.6 54.8l-3.6 3.8c-2.6 2.6-4.8 5-7 7.2-12.4 12.8-21.4 22-53.2 58l-1.4 1.6c-15.2 17.2-25.2 28.4-25.8 36.6-0.6 8 6.4 21 24.2 45.2 21.6 29.2 22.4 65.2 2.6 107-15.8 33-41.6 64.6-64.4 92.4l-2 2.4c-19.6 24-42.4 36-67.8 36-28.2 0-51.6-15.2-64-23.2-1-0.6-2-1.4-3-2-27.8-17.6-48-41.8-55.6-66.4-11.4-37-19-85 35.6-184.8 47.2-86.4 90-144.4 158-214.2 64-65.6 92.4-86.8 156-132.8 70.8-51.2 138.8-80.6 186.4-80.6 44.2 0 79 0 128.6 59.8 52 62.8 30.4 101.2-0.8 133.4zM808.8 177.2c-40-48.4-63-48.4-104.6-48.4-40.6 0-103.6 28-168.4 74.6-62 44.8-89.6 65.4-151.8 129.2-65.8 67.4-107.2 123.6-152.8 207-48.2 88.2-42.8 126.8-33 158.6 5.2 17 20.8 35.2 42 48.4 1 0.6 2 1.4 3.2 2 10.6 6.8 28.2 18.2 47.4 18.2 16 0 30.2-8 43.8-24.6l2-2.4c51-62.4 90.8-117.6 60.8-158.4-21.2-28.6-32.4-48-30.6-68 1.6-19.4 14.6-34 34.2-56l1.4-1.6c32.2-36.4 41.4-46 54.2-59 2.2-2.2 4.4-4.6 7-7.2l3.6-3.8c14.8-15.4 23-23.8 60.6-56.8l2.2-2c16-14 27.8-24.2 45-24.2 17.8 0 37.4 11.2 74.6 35 3.8 2.4 9.2 3.8 16 3.8 43.4 0 118.2-49.6 144.4-76.6 24-24.4 36-42.8-1.2-87.8z" />
-<glyph unicode="&#xe648;" d="M992 192v576h-960v-576h350v-32h-128v-32h514v32h-128v32h352zM64 736h896v-512h-896v512zM96 704h832v-448h-832v448z" />
-<glyph unicode="&#xe649;" d="M992 192v576h-960v-576h350v-32h-128v-32h514v32h-128v32h352zM64 736h896v-512h-896v512z" />
-<glyph unicode="&#xe64a;" d="M835 640h-123.4c-64.2 72-84.4 96-109 96h-177c-24.6 0-44.4-24-109-96h-26.6v32h-68v-32h-27c-35.2 0-67-26.4-67-61.4v-352c0-35 31.8-66.6 67-66.6h640c35.2 0 61 31.6 61 66.6v352c0 35-25.8 61.4-61 61.4zM512 239c-94.2 0-171 76.8-171 171s76.8 171 171 171 171-76.8 171-171-76.8-171-171-171zM738 542h-34v34h34v-34zM512 549c-76.8 0-139-62.2-139-139s62.2-139 139-139 139 62.2 139 139-62.2 139-139 139zM512 346c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64z" />
-<glyph unicode="&#xe64b;" d="M835 640h-123.4c-64.2 72-84.4 96-109 96h-177c-24.6 0-44.4-24-109-96h-26.6v32h-68v-32h-27c-35.2 0-67-26.4-67-61.4v-352c0-35 31.8-66.6 67-66.6h640c35.2 0 61 31.6 61 66.6v352c0 35-25.8 61.4-61 61.4zM864 226.6c0-18.6-12.4-34.6-29-34.6h-640c-17.4 0-35 17.4-35 34.6v352c0 16.4 16.2 29.4 35 29.4h135.6l9.6 6.4c8 9 15.4 20 22.2 27.6 22.6 25.4 39 43.4 50.6 53.8 9.4 8.4 12.4 8.2 12.4 8.2h177c0 0 3.2 0.2 13.4-9 12.2-11 29.4-33 53.2-59.6 5.8-6.6 12-13.6 18.6-21l9.6-6.4h137.8c17.6 0 29-12 29-29.4v-352zM512 581c-94.2 0-171-76.8-171-171s76.8-171 171-171 171 76.8 171 171-76.8 171-171 171zM512 271c-76.8 0-139 62.2-139 139s62.2 139 139 139 139-62.2 139-139-62.2-139-139-139zM704 576h34v-34h-34v34zM576 410c0-35.346-28.654-64-64-64s-64 28.654-64 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64z" />
-<glyph unicode="&#xe64c;" d="M128 832h64v-69.8h-64v69.8zM768 832h-512v-354.6h512v354.6 0zM768 419.2h-512v-355.2h512v355.2 0zM128 692.4h64v-69.8h-64v69.8zM128 552.8h64v-69.8h-64v69.8zM128 413h64v-69.8h-64v69.8zM128 273.4h64v-69.8h-64v69.8zM128 133.8h64v-69.8h-64v69.8zM832 832h64v-69.8h-64v69.8zM832 692.4h64v-69.8h-64v69.8zM832 552.8h64v-69.8h-64v69.8zM832 413h64v-69.8h-64v69.8zM832 273.4h64v-69.8h-64v69.8zM832 133.8h64v-69.8h-64v69.8z" />
-<glyph unicode="&#xe64d;" d="M681.6 763.2c101.4 0 183.8-82.6 183.8-184.6 0-52.4-21.8-99.6-56.6-133.2l-296.8-299.6-302 305c-31.6 33.2-51.2 78.2-51.2 127.8 0 102 82.2 184.6 183.8 184.6 76.4 0 141.8-46.8 169.6-113.6 27.4 66.6 93 113.6 169.4 113.6M681.6 794c-67.6 0-129.6-31.6-169.6-83.6-40 52-102 83.6-169.6 83.6-118.2 0-214.4-96.6-214.4-215.4 0-55.8 21.2-108.8 59.8-149.2l324.2-327.4 318.4 321.6c42 40.6 65.6 95.8 65.6 155 0 118.8-96.2 215.4-214.4 215.4v0z" />
-<glyph unicode="&#xe64e;" d="M763.4 508.2c0 195.2-105 261.6-203.2 276.4 0 1 0.2 2 0.2 3.2 0 24.6-21.8 44.2-48.4 44.2-26.6 0-47.6-19.6-47.6-44.2 0-1.2 0-2.2 0.2-3.2-98.4-15-204-81.6-204-276.8 0-227.6-56.6-252-132.6-316h768c-75.6 64.2-132.6 88.8-132.6 316.4zM512.4 64c53.6 0 97.6 39.8 103.4 86h-206.8c5.6-46.2 49.8-86 103.4-86z" />
-<glyph unicode="&#xe64f;" d="M763.4 508.2c0 195.2-105 261.6-203.2 276.4 0 1 0.2 2 0.2 3.2 0 24.6-21.8 44.2-48.4 44.2-26.6 0-47.6-19.6-47.6-44.2 0-1.2 0-2.2 0.2-3.2-98.4-15-204-81.6-204-276.8 0-227.6-56.6-252-132.6-316h768c-75.6 64.2-132.6 88.8-132.6 316.4zM214.4 224c17.2 18 32.8 36.8 45.4 63.6 24 50.6 34.8 118.4 34.8 220.4 0 92.8 25 160.8 74.2 202.4 45.8 38.6 103.4 46.6 143.6 46.6 40.2 0 97.8-8 143.2-46.6 49-41.4 74-109 74-201.8 0-167.6 29.8-234.6 80.6-284.6h-595.8zM512.4 64c53.6 0 97.6 39.8 103.4 86h-206.8c5.6-46.2 49.8-86 103.4-86z" />
-<glyph unicode="&#xe650;" d="M704.2 755.4c0 0.2 0 0.4 0 0.4-0.2 0.6-0.2 1-0.4 1.6 0 0 0 0.2 0 0.2-1.2 3-3.6 6-7 6.8l-4 0.8-180.8 38.8v-545.2c-16 0-44.8-0.8-89-2.6-83.6-3.2-102.8-43.2-102.8-81.8 0-49.2 26.4-86.2 123-82 103.6 4.6 102.8 97 102.8 163.4v385l147.2-27c6-1.2 10.8 4.6 10.8 10.6v128.8c0 0.8 0.2 1.6 0.2 2.2z" />
-<glyph unicode="&#xe651;" d="M832 320.2v483.8l-448-69.2v-474.4c-18 0-41.8-0.8-87-2.6-85.2-3.2-105-43.6-105-82.6 0-49.8 27-87 125.2-82.8 105.6 4.6 100.6 98 100.6 165v323l382 64v-321.2c-18 0-39.8-0.8-85.2-2.6-85.2-3.2-105-43.6-105-82.6 0-49.8 26-87 124.4-82.8 106 4.6 98 98 98 165z" />
-<glyph unicode="&#xe652;" d="M192 768v-640h158v283.6l482-283.6v640l-482-283.6v283.6h-158z" />
-<glyph unicode="&#xe653;" d="M192 768v-640h158v283.6l482-283.6v640l-482-283.6v283.6h-158zM351.2 448l15.2 8.8 433.6 255.2v-528l-448.8 264zM224 736h94v-251.6-56-17-251.4h-94v576z" />
-<glyph unicode="&#xe654;" d="M674 768v-283.6l-482 283.6v-640l482 283.6v-283.6h158v640h-158z" />
-<glyph unicode="&#xe655;" d="M674 768v-283.6l-482 283.6v-640l482 283.6v-283.6h158v640h-158zM657.8 439.2l-433.8-255.2v528 0l449-264-15.2-8.8zM800 160h-94v251.6 17 56 251.4h94v-576z" />
-<glyph unicode="&#xe656;" d="M512 704l-448-256 448-256v246.4l448-246.4v512l-448-246.4v246.4 0z" />
-<glyph unicode="&#xe657;" d="M928 650v-403.8l-367 201.8 367 202M480 648v-155.4-54.2-191.2l-352 200.8 352 200.4M512 704l-448-256 448-256v246.4l448-246.4v512l-448-246.4v246.4 0z" />
-<glyph unicode="&#xe658;" d="M382 736v-576h-94v576h94M414 768h-158v-640h158v640 0zM736 736v-576h-94v576h94M768 768h-158v-640h158v640 0z" />
-<glyph unicode="&#xe659;" d="M256 768h158v-640h-158v640zM610 768h158v-640h-158v640z" />
-<glyph unicode="&#xe65a;" d="M128 832h64v-69.8h-64v69.8zM734.6 797v-284.8h-445.2v284.8h445.2M768 832h-512v-354.6h512v354.6 0zM734.6 384.2v-285.4h-445.2v285.4h445.2M768 419.2h-512v-355.2h512v355.2 0zM128 692.4h64v-69.8h-64v69.8zM128 552.8h64v-69.8h-64v69.8zM128 413h64v-69.8h-64v69.8zM128 273.4h64v-69.8h-64v69.8zM128 133.8h64v-69.8h-64v69.8zM832 832h64v-69.8h-64v69.8zM832 692.4h64v-69.8h-64v69.8zM832 552.8h64v-69.8h-64v69.8zM832 413h64v-69.8h-64v69.8zM832 273.4h64v-69.8h-64v69.8zM832 133.8h64v-69.8h-64v69.8z" />
-<glyph unicode="&#xe65b;" d="M256 768v-640l512 320-512 320z" />
-<glyph unicode="&#xe65c;" d="M748.2 704l-27.2-20.6c48.2-65.8 77-147.2 77-235.4s-28.8-169.6-77.2-235.4l27.2-20.6c52.6 71.4 83.8 160 83.8 256s-31 184.6-83.6 256zM640 256.4c40 53.6 64 119.8 64 191.6s-24 138-64 191.6l-27.2-20.2c35.8-48 57.2-107.2 57.2-171.4s-21.4-123.4-57.2-171.4l27.2-20.2zM546.2 320.2c27.4 35.8 43.8 79.8 43.8 127.8 0 48-16.4 92-43.8 127.8l-27-19.6c23.2-30.2 37-67.6 37-108.2s-13.8-77.8-37-108.2l27-19.6zM307.8 528h-115.8v-160h115.8l140.2-112v384z" />
-<glyph unicode="&#xe65d;" d="M499.8 528h-115.8v-160h115.8l140.2-112v384z" />
-<glyph unicode="&#xe65e;" d="M272.965 879.782l27.613 16.17 515.204-879.813-27.613-16.17-515.204 879.813zM512.4 253.2c24.6 0 47.6 5.8 68.4 16.4l-226.8 385.6v-235.2c0-92 70.8-166.8 158.4-166.8zM670 420v309c0 92-70.4 167-158 167-50.8 0-95.6-25.2-124.6-64.4l273.8-466.6c5.8 17.2 8.8 35.8 8.8 55zM768 416.6v159.4h-34v-159.4c0-43-12.4-83.2-34.2-117l19.8-34c30.6 42.4 48.4 94.6 48.4 151zM534 161.6c34 2.4 66 11.6 94.6 26l-18.8 32.2c-29-14-61.4-21.8-95.4-21.8-120.6 0-220.2 98-220.2 218.2v159.8h-38v-159.4c0-134.4 106-245.2 240-254.8v-125.8h-146v-36h322v36h-138v125.6z" />
-<glyph unicode="&#xe65f;" d="M512 896c-87.4 0-158-75-158-167v-309c0-92 70.6-167 158-167s158 75 158 167v309c0 92-70.6 167-158 167zM638 420c0-74.4-56.6-135-126-135s-126 60.6-126 135v309c0 74.4 56.6 135 126 135s126-60.6 126-135v-309zM734 576v-159.4c0-120.4-99.6-218.4-220-218.4s-220 98-220 218.4v159.4h-38v-159.4c0-134.4 106-245.2 240-255v-125.6h-146v-36h322v36h-138v125.6c132 9.8 234 120.6 234 255v159.4h-34z" />
-<glyph unicode="&#xe660;" d="M512 253c87.4 0 158 75 158 167v309c0 92-70.6 167-158 167s-158-75-158-167v-309c0-92 70.6-167 158-167zM734 576v-159.4c0-120.4-99.6-218.4-220-218.4s-220 98-220 218.4v159.4h-38v-159.4c0-134.4 106-245.2 240-255v-125.6h-146v-36h322v36h-138v125.6c132 9.8 234 120.6 234 255v159.4h-34z" />
-<glyph unicode="&#xe661;" d="M496 256h32v-192h-32v192zM798.6 592.8c0 2.4 0.4 4.8 0.4 7.2 0 128.6-105.6 232.8-233.6 232.8-92.2 0-171.6-54.2-208.8-132.6-16.2 8.2-34.2 12.8-53.6 12.8-59.2 0-108.2-47.2-117.8-104-70.4-24.2-121.2-93.4-121.2-172.6 0-99.4 80.2-180.4 179.2-180.4h252.8v292.4l-109.4-109-23.2 23.2 149 148.6 149-148.6-23.6-23.2-109.8 109v-292.4h268c90 0 164 74.6 164 165.6s-71 171-161.4 171.2z" />
-<glyph unicode="&#xe662;" d="M386.6 439.2l-23.2 23.2 149 148.6 149-148.6-23.4-23.2-109.2 109.2v-483.6h-33v483.6zM798.6 592.8c0 2.4 0.4 4.8 0.4 7.2 0 128.6-105.6 232.8-233.6 232.8-92.2 0-171.6-54.2-208.8-132.6-16.2 8.2-34.2 12.8-53.6 12.8-59.2 0-108.2-47.2-117.8-104-70.4-24.2-121.2-93.4-121.2-172.6 0-99.4 80.2-180.4 179.2-180.4h182.8v32h-181.2c-81.8 0-148.4 67-148.4 149.2 0 63.6 40.4 122.4 100.4 143.2l16.8 5.8 3 17.6c7.2 43.2 44.2 78.6 87.8 78.6 13.8 0 27.4-3.2 39.8-9.6l27-13.6 13 27.4c33.2 69.8 104.2 114.8 180.8 114.8 110.6 0 201.8-86.6 201.8-197.8 0-26.6-0.4-40.6-0.4-40.6l30.4-0.2c73.2-1 131.2-66.8 131.2-140.6 0-73.6-59.6-133.8-133-134.2h-201v-32h202c90 0 164 74.6 164 165.6s-71 171-161.4 171.2z" />
-<glyph unicode="&#xe663;" d="M798.6 494.4c0 2.4 0.4 4.8 0.4 7.2 0 128.6-105.6 234.4-233.6 234.4-92.2 0-171.6-55.8-208.8-134-16.2 8.2-34.2 12.8-53.6 12.8-59.2 0-108.2-47.4-117.8-104-70.4-24.4-121.2-88.4-121.2-167.6 0-99.6 80.2-183.2 179.2-183.2h552.8c90 0 164 77.8 164 168.6 0 91.2-70.8 165.6-161.4 165.8zM795 192.8l-6.4-0.8h-543.8c-81.8 0-148.4 69.8-148.4 152.2 0 63.8 40.4 116.8 100.4 137.6l16.8 6 3 17.6c7.2 43.2 44.2 78.6 87.8 78.6 13.8 0 27.4-3.2 39.8-9.6l27-13.6 13 27.4c33.2 69.8 104.2 116.4 180.8 116.4 110.6 0 201.8-88.2 201.8-199.4 0-26.6-0.4-40.6-0.4-40.6l30.4-0.2c73.4-1 131.2-61 131.2-134.8s-59.6-136.4-133-136.8z" />
-<glyph unicode="&#xe664;" d="M320 703.2l64.6 64.8 319.4-320-319.4-320-64.6 64.8 254.6 255.2z" />
-<glyph unicode="&#xe665;" d="M704 703.2l-64.6 64.8-319.4-320 319.4-320 64.6 64.8-254.6 255.2z" />
-<glyph unicode="&#xe666;" d="M512 352c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32zM336 512v144c0 97 79 176 176 176s176-79 176-176v-16h32v16c0 114.8-93.2 208-208 208-115 0-208-93.2-208-208v-144h-112v-480h640v480h-496zM528 258v-82c0-8.8-7.2-16-16-16s-16 7.2-16 16v82c-27.6 7.2-48 32.2-48 62 0 35.4 28.6 64 64 64s64-28.6 64-64c0-29.8-20.4-54.8-48-62z" />
-<glyph unicode="&#xe667;" d="M512 704v-246.4l-448 246.4v-512l448 246.4v-246.4l448 256-448 256z" />
-<glyph unicode="&#xe668;" d="M336 512v144c0 97 79 176 176 176s176-79 176-176v-16h32v16c0 114.8-93.2 208-208 208-115 0-208-93.2-208-208v-144h-112v-480h640v480h-496zM800 64h-576v416h576v-416zM512 384c-35.4 0-64-28.6-64-64 0-29.8 20.4-54.8 48-62v-82c0-8.8 7.2-16 16-16s16 7.2 16 16v82c27.6 7.2 48 32.2 48 62 0 35.4-28.6 64-64 64zM512 288c-17.6 0-32 14.4-32 32s14.4 32 32 32 32-14.4 32-32-14.4-32-32-32z" />
-<glyph unicode="&#xe669;" d="M512 352c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32zM720 512v144c0 114.8-93.2 208-208 208-115 0-208-93.2-208-208v-144h-112v-480h640v480h-112zM528 258v-82c0-8.8-7.2-16-16-16s-16 7.2-16 16v82c-27.6 7.2-48 32.2-48 62 0 35.4 28.6 64 64 64s64-28.6 64-64c0-29.8-20.4-54.8-48-62zM688 512h-352v144c0 97 79 176 176 176s176-79 176-176v-144z" />
-<glyph unicode="&#xe66a;" d="M720 512v144c0 114.8-93.2 208-208 208-115 0-208-93.2-208-208v-144h-112v-480h640v480h-112zM336 656c0 97 79 176 176 176s176-79 176-176v-144h-352v144zM800 64h-576v416h576v-416zM576 320c0 35.4-28.6 64-64 64s-64-28.6-64-64c0-29.8 20.4-54.8 48-62v-82c0-8.8 7.2-16 16-16s16 7.2 16 16v82c27.6 7.2 48 32.2 48 62zM512 288c-17.6 0-32 14.4-32 32s14.4 32 32 32 32-14.4 32-32-14.4-32-32-32z" />
-<glyph unicode="&#xe66b;" d="M768 430h-512v34h512v-34z" />
-<glyph unicode="&#xe66c;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM768 430h-512v34h512v-34z" />
-<glyph unicode="&#xe66d;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4 0-210.2-171.2-381.4-381.4-381.4zM256 464h512v-34h-512v34z" />
-<glyph unicode="&#xe66e;" d="M781 672c0 0-309.4 0-334 0-9.4 0-21.4 19.8-37 38-14.2 16.6-29.4 26-41 26-15 0-120.6 0-120.6 0-31 0-56.4-17.8-56.4-48.6v-469.2c0-31 25.4-58.2 56.4-58.2h532.6c31 0 51 27.2 51 58.2v404.2c0 31-20 49.6-51 49.6zM248.4 704h87.6c0 0 14.8 0 22.6 0s17.2-3.2 28.6-16.6c24.2-28.6 31-47.4 59.8-47.4h334c13.2 0 19-4.4 19-17.6v-46.4h-576v111.4c0 18 20.6 16.6 24.4 16.6zM781 192h-532.6c-13 0-24.4 12.4-24.4 26.2v325.8h576v-325.8c0-12-5.2-26.2-19-26.2z" />
-<glyph unicode="&#xe66f;" d="M128 576h768v-512h-768v512zM896 768h-192v-96h-32v96h-320v-96h-32v96h-192v-160h768zM320 832h32v-64h-32v64zM672 832h32v-64h-32v64z" />
-<glyph unicode="&#xe670;" d="M704 768v64h-32v-64h-320v64h-32v-64h-192v-704h768v704h-192zM864 96h-704v480h704v-480zM864 608h-704v128h160v-64h32v64h320v-64h32v64h160v-128z" />
-<glyph unicode="&#xe671;" d="M610 471.2c27.8 0 54-9.4 75.6-27 21-17.2 35.8-41 41.6-67.4l6-27 27.2 3.4c4 0.6 7.8 0.8 11.6 0.8 51.8 0 93.8-44.6 93.8-97 0-52.4-42-97-93.8-97h-303c-18.4 0-35.6 9.4-48.8 22.8s-20.4 32.2-20.4 51c0 36 27.8 65.8 63.8 71.8 3.2 0.6 16.8 2.6 27.4 3.6 0 0-1 10.4-1.2 18.8-0.2 8.4-0.2 18.2-0.2 22.2 0.2 66.8 54 121 120.4 121M610 502c-83 0-150.4-68-150.4-151.8 0-5 0.2-10.2 0.8-15-50.8-4.6-90.4-50.8-90.4-103 0-55.4 44.4-104 99.4-104h302.6c68.6 0 124 59.2 124 128.4s-55.6 127-124 127c-5.2 0-10.4 0.4-15.4-0.2-15.2 67.2-75 118.6-146.6 118.6v0zM416 768h32v-110h-32v110zM128 468h112v-34h-112v34zM220.6 648.2l22.4 22.6 63.8-64.2-22.4-22.6zM576.2 584.2l-22.4 22.4 63.6 64.2 22.4-22.6zM243 249l-22.4 22.6 63.8 64.2 22.4-22.6zM389.4 356c-41.2 16.4-70.4 56.8-70.4 104 0 61.6 49.8 111.8 111.2 111.8 31.8 0 60.4-13.4 80.6-35 9.6 7 19.4 12.6 27.8 16.6-26.2 30.6-65 50.2-108.4 50.2-78.8 0-142.8-64.4-142.8-143.6 0-55.6 31.6-104 77.8-127.8 7.4 10.4 16 18.2 24.2 23.8z" />
-<glyph unicode="&#xe672;" d="M488 640c-86.6 0-156.6-70.4-156.6-157 0-5.2 0.2-10.4 0.8-15.6-52.8-4.6-94.2-51-94.2-105.2 0-57.2 46.4-106.2 103.4-106.2h315.4c71.4 0 129.2 59.8 129.2 131.4s-57.8 130.6-129.2 130.6c-5.4 0-10.8 0-16-0.6-15.8 70-78.2 122.6-152.8 122.6v0z" />
-<glyph unicode="&#xe673;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM512 191.8c-141.4 0-256 114.6-256 256.2s114.6 256.2 256 256.2v87.8l192-128-192-111.4v111.6c-119.2 0-216.2-97-216.2-216.2s97-216.2 216.2-216.2 216.2 96.2 216.2 216.2h39.8c0-142-114.6-256.2-256-256.2z" />
-<glyph unicode="&#xe674;" d="M496 90l-109.4 107.6-23.4-22.8 149-146.8 149 146.8-23.6 22.8-109.6-107.6v214h-32zM798.4 631.2c0 2.4 0.4 4.6 0.4 7 0 127-105.8 229.8-233.6 229.8-92.2 0-171.6-53.6-208.8-130.8-16.2 8-34.2 12.6-53.6 12.6-59.2 0-108.2-46.6-117.8-102.6-70.4-24-121.2-86.8-121.2-164.8 0-98.2 80.2-178.4 179.2-178.4h253v270h32v-270h268c90 0 163.8 74.4 163.8 164.2s-70.8 162.8-161.4 163z" />
-<glyph unicode="&#xe675;" d="M512 191.8c-141.4 0-256 114.6-256 256.2s114.6 256.2 256 256.2v87.8l192-128-192-111.4v111.6c-119.2 0-216.2-97-216.2-216.2s97-216.2 216.2-216.2 216.2 96.2 216.2 216.2h39.8c0-142-114.6-256.2-256-256.2z" />
-<glyph unicode="&#xe676;" d="M894.2 447.6c-90.6 104.4-215.8 224.4-382.2 224.4-67.2 0-128.8-19-193.8-59.6-54.8-34.4-111-82.8-188.2-162.4l-2-2 13.4-13.8c110.2-112.8 205.4-210.2 370.6-210.2 73 0 143.8 23.8 216.4 72.8 61.8 41.8 114.4 94.8 156.6 137.6l11 11-1.8 2.2zM512 288c-88.2 0-160 71.8-160 160s71.8 160 160 160c88.2 0 160-71.8 160-160 0-88.2-71.8-160-160-160zM500.8 506.4c0 13.8 4 26.8 11 37.6-53 0-95.8-43.2-95.8-96.4 0-53.2 43-96.2 95.8-96.2s96 43 96 96.2v0c-10.8-7-23.8-11-37.6-11-38.2 0.2-69.4 31.4-69.4 69.8z" />
-<glyph unicode="&#xe677;" d="M737 704h-450l-127-192v-320h704v320l-127 192zM826.8 512h-90.8v136l90.8-136zM320 672h384v-160h-96c0-53-43-96-96-96s-96 43-96 96h-96v160zM288 648v-136h-90.8l90.8 136zM832 224h-640v256h196c14.2-55.2 64.4-96 124-96s109.8 40.8 124 96h196v-256z" />
-<glyph unicode="&#xe678;" d="M416 416.6v-64.6h64.4l360.2 360-64.8 64.6zM888.4 799.4l-25 25c-5.4 4.8-12.4 7.6-20 7.6s-14.6-3-19.8-7.6l-24.2-24.4 0.2-0.2 22.4-22.6 42-42 24.4 24.4c4.8 5.2 7.6 12.2 7.6 19.8 0.2 7.6-2.8 14.6-7.6 20zM511 320h-127v127.2l256 256h-0.6l0.8 0.8h-480.2v-576h608v444.4l0.2 5z" />
-<glyph unicode="&#xe679;" d="M796 103.4M672 864h-576v-450h224v226h352zM350 610v-452h324l128-126h30v126h96v452h-578z" />
-<glyph unicode="&#xe67b;" d="M607.4 704h-442c-37.6 0-71.4-28.2-71.4-65.4v-375.8c0-37.2 33.8-70.8 71.4-70.8h442c37.6 0 66.6 33.6 66.6 70.8v375.8c0 37.2-29 65.4-66.6 65.4zM734 534v-171.2l196-106.8v384l-196-106z" />
-<glyph unicode="&#xe67c;" d="M607.4 704h-442c-37.6 0-71.4-28.2-71.4-65.4v-375.8c0-37.2 33.8-70.8 71.4-70.8h442c37.6 0 66.6 33.6 66.6 70.8v375.8c0 37.2-29 65.4-66.6 65.4zM640 262.8c0-18.6-13.8-36.8-32.6-36.8h-442c-18.8 0-37.4 18.2-37.4 36.8v375.8c0 18.6 18 31 36.8 31l442-0.2c18.8 0 33.2-12.2 33.2-30.8v-375.8zM734 534v-171.2l196-106.8v384l-196-106zM896 580v-264.6l-128 67v131.2l128.2 67.2-0.2-0.8z" />
-<glyph unicode="&#xe67d;" d="M96 650l367-202-367-201.8v403.8M544 648.4l352-200.4-352-200.8v191.2 54.2 155.4M512 704v-246.4l-448 246.4v-512l448 246.4v-246.4l448 256-448 256z" />
-<glyph unicode="&#xe67e;" d="M288 710.2l419.6-262.2-419.6-262.2v524.4M256 768v-640l512 320-512 320z" />
-<glyph unicode="&#xe67f;" d="M386.4 197.6l-23.2-22.8 149-146.8 149 146.8-23.2 22.8-109.4-107.6v484.2h-32.8v-484.2zM798.4 631.2c0 2.4 0.4 4.6 0.4 7 0 127-105.8 229.8-233.6 229.8-92.2 0-171.6-53.6-208.8-130.8-16.2 8-34.2 12.6-53.6 12.6-59.2 0-108.2-46.6-117.8-102.6-70.4-24-121.2-86.8-121.2-164.8 0-98.2 80.2-178.4 179.2-178.4h183v32h-181.4c-81.8 0-148.4 66.4-148.4 147.4 0 62.8 40.4 115 100.4 135.4l16.8 5.6 3 17.4c7.2 42.6 44.2 77.6 87.8 77.6 13.8 0 27.4-3.2 39.8-9.4l27-13.4 13 27.2c33.2 68.8 104.2 113.2 180.8 113.2 110.6 0 201.8-85.6 201.8-195.2 0-26.2-0.4-40.2-0.4-40.2l30.4-0.2c73.4-1 131.2-60 131.2-132.8 0-72.6-59.6-132.2-133-132.6l-6.4-0.2h-194.4v-32h202c90 0 163.8 74.4 163.8 164.2 0 90-70.8 163-161.4 163.2z" />
-<glyph unicode="&#xe680;" d="M798.6 494.4c0 2.4 0.4 4.8 0.4 7.2 0 128.6-105.6 234.4-233.6 234.4-92.2 0-171.6-55.8-208.8-134-16.2 8.2-34.2 12.8-53.6 12.8-59.2 0-108.2-47.4-117.8-104-70.4-24.4-121.2-88.4-121.2-167.6 0-99.6 80.2-183.2 179.2-183.2h552.8c90 0 164 77.8 164 168.6 0 91.2-70.8 165.6-161.4 165.8z" />
-<glyph unicode="&#xe681;" d="M768 430h-240v-238h-34v238h-238v34h238v240h34v-240h240v-34z" />
-<glyph unicode="&#xe682;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM768 430h-240v-238h-34v238h-238v34h238v240h34v-240h240v-34z" />
-<glyph unicode="&#xe683;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4s171.2 381.4 381.4 381.4 381.4-171.2 381.4-381.4-171.2-381.4-381.4-381.4zM528.2 704h-33.6v-239.8h-238.6v-33.6h238.6v-238.6h33.6v238.6h239.8v33.6h-239.8z" />
-<glyph unicode="&#xe684;" d="M447.8 300.6c-4.8-4.8-11.6-8.8-17.6-8.8s-12.8 4.2-17.8 9l-112 112 35.6 35.6 94.4-94.4 249.6 251.4 35-36.2-267.2-268.6z" />
-<glyph unicode="&#xe685;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM447.8 300.6c-4.8-4.8-11.6-8.8-17.6-8.8s-12.8 4.2-17.8 9l-112 112 35.6 35.6 94.4-94.4 249.6 251.4 35-36.2-267.2-268.6z" />
-<glyph unicode="&#xe686;" d="M680.2 605.4l-249.6-251.4-94.4 94.4-35.6-35.6 112-112c5-5 11.8-9 17.8-9s12.6 4 17.6 8.8l267.4 268.8-35.2 36zM512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4 0-210.2-171.2-381.4-381.4-381.4z" />
-<glyph unicode="&#xe687;" d="M520.6 228c-18.8 0-34 15-34 33.8 0 18.6 15.2 33.6 34 33.6 18.8 0 34-15 34-33.6 0-18.8-15.2-33.8-34-33.8zM588.2 458.6c-45.6-45-44.4-54.8-46.6-106.6h-38c2.2 57 15 87.4 60.2 129 22 20.6 38.8 45.4 38.8 76.2 0 47.2-38.8 79.8-85.2 79.8-64.8 0-97-32.8-95.8-92.8h-37.6c0.6 84 48.8 124.2 135.2 124.2 66 0 120.8-40.8 120.8-109.2 0-43.8-21.4-72.4-51.8-100.6z" />
-<glyph unicode="&#xe688;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM520.6 228c-18.8 0-34 15-34 33.8 0 18.6 15.2 33.6 34 33.6 18.8 0 34-15 34-33.6 0-18.8-15.2-33.8-34-33.8zM588.2 458.6c-45.6-45-44.4-54.8-46.6-106.6h-38c2.2 57 15 87.4 60.2 129 22 20.6 38.8 45.4 38.8 76.2 0 47.2-38.8 79.8-85.2 79.8-64.8 0-97-32.8-95.8-92.8h-37.6c0.6 84 48.8 124.2 135.2 124.2 66 0 120.8-40.8 120.8-109.2 0-43.8-21.4-72.4-51.8-100.6z" />
-<glyph unicode="&#xe689;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4 0-210.2-171.2-381.4-381.4-381.4zM519.2 668c-86.4 0-134.6-40.6-135.2-124.4h37.6c-1.2 60.8 31 93 95.8 93 46.4 0 85.2-32.4 85.2-79.6 0-30.6-16.6-55.4-38.8-76.2-45.2-41.6-58-72-60.2-129h38c2.2 51.6 1 61.4 46.6 106.6 30.4 28.4 51.8 56.6 51.8 100.4 0 68.4-54.8 109.2-120.8 109.2zM520.6 295.4c-18.8 0-34-15-34-33.6s15.2-33.8 34-33.8c18.8 0 34 15 34 33.8 0 18.6-15.2 33.6-34 33.6z" />
-<glyph unicode="&#xe68a;" d="M543 616c0-22.091-17.909-40-40-40s-40 17.909-40 40c0 22.091 17.909 40 40 40 22.091 0 40-17.909 40-40zM544 272v256h-96v-16h32v-240h-32v-16h128v16z" />
-<glyph unicode="&#xe68b;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM503 656c22.2 0 40-18 40-40s-18-40-40-40c-22 0-40 18-40 40s17.8 40 40 40zM576 256h-128v16h32v240h-32v16h96v-256h32v-16z" />
-<glyph unicode="&#xe68c;" d="M543 616c0-22.091-17.909-40-40-40s-40 17.909-40 40c0 22.091 17.909 40 40 40 22.091 0 40-17.909 40-40zM544 272v256h-96v-16h32v-240h-32v-16h128v16zM512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4 0-210.2-171.2-381.4-381.4-381.4z" />
-<glyph unicode="&#xe68d;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4 0-210.2-171.2-381.4-381.4-381.4zM512 768c-176.8 0-320-143.2-320-320s143.2-320 320-320c176.8 0 320 143.2 320 320 0 176.8-143.2 320-320 320z" />
-<glyph unicode="&#xe68e;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4 0-210.2-171.2-381.4-381.4-381.4z" />
-<glyph unicode="&#xe68f;" d="M800 733.4h-160v40c0 32.4-26.2 58.6-58.6 58.6h-139c-32.2 0-58.4-26.2-58.4-58.6v-40h-160v-29.4h42.2l47.2-581.4c0-32.4 26.2-58.6 58.6-58.6h282c32.4 0 58.6 26.2 58.6 58.6l46.6 581.4h40.8v29.4zM413.2 773.4c0 16.2 13.2 29.4 29.2 29.4h139c16.2 0 29.2-13.2 29.2-29.4v-40h-197.4v40zM683.2 124.2v-0.8-0.8c0-16.2-13.2-29.4-29.2-29.4h-282c-16.2 0-29.2 13.2-29.2 29.4v0.8 0.8l-47.4 579.8h434.4l-46.6-579.8zM498 640h28v-482h-28v482zM640 640h-29.2l-21.4-482h29.2zM413 640h-29l21.4-482h29.2z" />
-<glyph unicode="&#xe690;" d="M512 512c-35.4 0-64-28.6-64-64s28.6-64 64-64c35.4 0 64 28.6 64 64s-28.6 64-64 64v0zM256.8 512c-35.4 0-64-28.6-64-64s28.6-64 64-64c35.4 0 64 28.6 64 64s-28.8 64-64 64v0zM768 512c-35.4 0-64-28.6-64-64s28.6-64 64-64 64 28.6 64 64-28.6 64-64 64v0z" />
-<glyph unicode="&#xe691;" d="M512 484c19.8 0 36-16.2 36-36s-16.2-36-36-36-36 16.2-36 36 16.2 36 36 36M512 512c-35.4 0-64-28.6-64-64s28.6-64 64-64c35.4 0 64 28.6 64 64s-28.6 64-64 64v0zM256.8 484c19.8 0 36-16.2 36-36s-16.2-36-36-36c-19.8 0-36 16.2-36 36s16.2 36 36 36M256.8 512c-35.4 0-64-28.6-64-64s28.6-64 64-64c35.4 0 64 28.6 64 64s-28.8 64-64 64v0zM768 484c19.8 0 36-16.2 36-36s-16.2-36-36-36-36 16.2-36 36 16.2 36 36 36M768 512c-35.4 0-64-28.6-64-64s28.6-64 64-64 64 28.6 64 64-28.6 64-64 64v0z" />
-<glyph unicode="&#xe692;" d="M528 672v-324h-32v324h-304v-608h640v608zM528 833.2l109.6-109.4 23.2 23.2-148.8 149-149-149 23.4-23.2 109.6 109.4v-161.2h32z" />
-<glyph unicode="&#xe693;" d="M576 672v-32h224v-544h-576v544h224v32h-256v-608h640v608zM386.2 723.8l-23.2 23.2 149 149 149-149-23.2-23.2-109.4 109.4v-486h-32.8v486z" />
-<glyph unicode="&#xe694;" d="M528 672v-326l109.6 109.4 23.2-23.2-148.8-149-149 149 23.4 23.2 109.6-109.4v326h-304v-608h640v608zM496 832h32v-160h-32v160z" />
-<glyph unicode="&#xe695;" d="M576 672v-32h224v-544h-576v544h224v32h-256v-608h640v608zM386.2 455.4l-23.2-23.2 149-149 149 149-23.2 23.2-109.4-109.4v486h-32.8v-486z" />
-<glyph unicode="&#xe696;" d="M689 364c30 47.2 47.6 103.2 47.6 163.4 0 168.2-136.2 304.6-304.2 304.6-168.2 0-304.4-136.4-304.4-304.6 0-168.2 136.2-304.6 304.2-304.6 61 0 117.8 18 165.4 48.8l13.8 9.6 217.2-217.2 67.4 68.6-217 217.2 10 14.2zM602.8 697.6c45.4-45.4 70.4-105.8 70.4-170s-25-124.6-70.4-170c-45.4-45.4-105.8-70.4-170-70.4-64.2 0-124.6 25-170 70.4-45.4 45.4-70.4 105.8-70.4 170 0 64.2 25 124.6 70.4 170 45.4 45.4 105.8 70.4 170 70.4 64.2 0 124.6-25 170-70.4z" />
-<glyph unicode="&#xe697;" d="M896.6 110.6l-226.6 226.8c41.6 52 66.6 118.2 66.6 190.2 0 168.2-136.2 304.4-304 304.4-168 0-304-136.4-304-304.4s136.2-304.4 304-304.4c72.4 0 138.8 25.4 191 67.6l226.4-226.8 46.6 46.6zM240.2 334.8c-51.4 51.4-79.6 119.8-79.6 192.6s28.4 141.2 79.6 192.6 119.8 80 192.4 80c72.6 0 141-28.4 192.4-79.8s79.6-119.8 79.6-192.6-28.4-141.2-79.6-192.6c-51.4-51.4-119.8-79.8-192.4-79.8-72.6-0.2-141 28.2-192.4 79.6z" />
-<glyph unicode="&#xe698;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM512 192v256h-255.4l447.4 192-192-448z" />
-<glyph unicode="&#xe699;" d="M512 831c102.2 0 198.4-39.8 270.8-112.2s112.2-168.4 112.2-270.8-39.8-198.4-112.2-270.8-168.4-112.2-270.8-112.2-198.4 39.8-270.8 112.2c-72.2 72.4-112.2 168.6-112.2 270.8s39.8 198.4 112.2 270.8c72.4 72.2 168.6 112.2 270.8 112.2M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416v0zM704 640l-447.4-192h255.4v-256z" />
-<glyph unicode="&#xe69a;" d="M288 128v32 576h-64v-672h480v64h-384zM650.6 832h-330.6v-96-576h480v522l-149.4 150zM736 608h-160v160h32v-128h128v-32z" />
-<glyph unicode="&#xe69b;" d="M608 768h-32v-160h160v32h-128zM650.6 832h-330.6v-96h-96v-672h480v96h96v522l-149.4 150zM672 96h-416v608h64v-544h352v-64zM768 192h-416v608h285.4l130.6-131.2v-476.8z" />
-<glyph unicode="&#xe69c;" d="M192 704v-640h768v640h-768zM832 832h-768v-640h96v544h672z" />
-<glyph unicode="&#xe69d;" d="M192 704v-640h768v640h-768zM928 96h-704v576h704v-576zM64 832v-640h96v32h-64v576h704v-64h32v96z" />
-<glyph unicode="&#xe69e;" d="M960 704h-896v-640h896v640 0zM144 768h736v-32h-736v32zM208 832h608v-32h-608v32z" />
-<glyph unicode="&#xe69f;" d="M928 672v-576h-832v576h832M960 704h-896v-640h896v640 0zM144 768h736v-32h-736v32zM208 832h608v-32h-608v32z" />
-<glyph unicode="&#xe6a0;" d="M512 864c-0.2 0-0.2 0-0.4 0 0 0 0 0-0.2 0-0.2 0-0.4 0-0.4 0-229.4-0.6-415-186.6-415-416 0-229.4 185.6-415.4 415-416 0.2 0 0.4 0 0.4 0 0 0 0.2 0 0.2 0 0.2 0 0.2 0 0.4 0 229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM512 65.2c-0.2 0-0.2 0-0.4 0 0 0 0 0-0.2 0-0.2 0-0.4 0-0.4 0-210.8 0.6-381.8 171.8-381.8 382.8 0 211 170.8 382.2 381.8 382.6 0.2 0 0.2 0 0.4 0 0 0 0.2 0 0.2 0 0.2 0 0.2 0 0.4 0 211.4 0 382.8-171.4 382.8-382.8 0-211.2-171.4-382.6-382.8-382.6zM644.6 616.4c-37.4-9-76-14.4-115.8-15.6v-136.2h135.2c-1.2 56.2-8.2 107.2-19.4 151.8zM528.6 795v-163.8c37 1.2 73 6 107.6 14.4-26.2 82.8-67 137.2-107.6 149.4zM386.8 645.8c35-8.4 71.2-13.4 108.4-14.6v164.2c-40.6-11.8-82-66.2-108.4-149.6zM761.2 693.2c-45.2 46-103 79.6-167.8 95 29.6-30.6 54.4-77.4 72.2-134.6 33.4 10.2 65.4 23.4 95.6 39.6zM694.6 464.6h166.6c-3.6 77.6-32.6 148.8-79 205.2-34.2-18.8-70.4-34.2-108.2-45.6 12.2-48 19.4-102.2 20.6-159.6zM359 464.6h136.4v136.2c-40.2 1.2-79.2 6.6-116.8 15.8-11.4-44.6-18.4-95.8-19.6-152zM664 431.4h-135.4v-136c39.8-1.2 78.6-6.4 116-15.6 11.2 44.4 18.2 95.6 19.4 151.6zM378.6 279.6c37.6 9.2 76.6 14.6 116.8 15.8v136h-136.4c1.2-56.2 8.2-107.4 19.6-151.8zM495.4 100.8v164.2c-37.2-1.2-73.6-6.2-108.6-14.6 26.4-83.4 67.8-138 108.6-149.6zM593.4 107.8c64.8 15.6 122.6 49 168 95.2-30.2 16.2-62.2 29.4-95.6 39.6-17.8-57.4-42.8-104-72.4-134.8zM429.4 787.8c-64.2-15.6-121.6-49-166.6-94.8 30-16 61.6-29.2 94.6-39.2 17.8 57 42.6 103.4 72 134zM674 271.8c38-11.4 74.2-26.8 108.4-45.6 46.4 56.4 75.4 127.6 79 205.2h-166.6c-1.4-57.4-8.6-111.4-20.8-159.6zM528.6 265v-164c40.6 12.2 81.4 66.6 107.6 149.6-34.6 8.4-70.6 13.2-107.6 14.4zM349.2 624.4c-37.6 11.4-73.6 26.6-107.4 45.4-46.4-56.4-75.4-127.6-79-205.2h165.8c1 57.6 8.4 111.8 20.6 159.8zM328.4 431.4h-165.8c3.6-77.6 32.6-148.8 79-205.2 33.8 18.6 69.8 34 107.4 45.4-12 48-19.4 102.2-20.6 159.8zM262.6 203c45-45.8 102.4-79.2 166.8-94.8-29.4 30.6-54.2 77.2-72 134.2-33-10.2-64.8-23.4-94.8-39.4z" />
-<glyph unicode="&#xe6a1;" d="M512 864c-0.2 0-0.2 0-0.4 0 0 0 0 0-0.2 0-0.2 0-0.4 0-0.4 0-229.4-0.6-415-186.6-415-416 0-229.4 185.6-415.4 415-416 0.2 0 0.4 0 0.4 0 0 0 0.2 0 0.2 0 0.2 0 0.2 0 0.4 0 229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM528.6 615c44.2 1.2 87 7 128.4 17 12.4-49 20.2-105.6 21.4-167.6h-149.8v150.6zM528.6 648.4v179.6c44.8-12.4 90.4-72.2 119.2-164-38.4-9.2-78.2-14.4-119.2-15.6zM495.4 828.4v-180.2c-41.4 1.2-81.6 6.6-120.2 16 29.2 92.4 75 152.6 120.2 164.2zM495.4 615v-150.4h-150.8c1.2 62 9 118.6 21.4 167.6 41.6-10 85-16 129.4-17.2zM311 464.6h-181.2c3.6 85.6 35.6 164 86.6 226 37-20.4 76.4-37.2 117.6-49.6-13.6-53-21.6-112.8-23-176.4zM311 431.4c1.2-63.4 9.2-123.4 22.8-176.4-41.2-12.6-80.4-29.2-117.6-49.6-51 62-82.8 140.4-86.6 226h181.4zM344.6 431.4h150.8v-150.2c-44.4-1.2-87.8-7.2-129.4-17.4-12.4 49-20.2 105.6-21.4 167.6zM495.4 247.8v-180.4c-45.2 11.8-91 71.8-120.2 164.2 38.6 9.6 78.8 15 120.2 16.2zM528.6 68v180c41-1.2 80.8-6.6 119.4-15.8-29-92-74.4-151.8-119.4-164.2zM528.6 281.2v150.2h149.8c-1.2-61.8-9-118.4-21.4-167.4-41.4 10-84.2 16-128.4 17.2zM711.8 431.4h182.4c-3.6-85.6-35.6-163.8-86.6-226-37.4 20.6-77 37.4-118.6 50 13.6 53 21.6 112.6 22.8 176zM711.8 464.6c-1.2 63.4-9.2 123.2-22.6 176.2 41.6 12.6 81.2 29.4 118.4 49.8 51-62 83-140.4 86.6-226.2h-182.4zM784.8 716.2c-33.2-17.6-68-32.2-104.6-43.2-19.4 62.6-46.8 113.6-79 147.2 70.8-17 134-53.8 183.6-104zM421.6 819.8c-32.2-33.4-59.4-84.4-78.6-146.6-36.2 11-70.8 25.4-103.6 43 49 50 111.8 86.6 182.2 103.6zM239.2 180c32.8 17.6 67.6 32 103.6 43 19.4-62.4 46.6-113.2 78.8-146.8-70.4 17-133.2 53.6-182.4 103.8zM601.2 75.8c32.4 33.6 59.6 84.6 79.2 147.4 36.6-11 71.4-25.6 104.6-43.2-49.6-50.4-113-87.2-183.8-104.2z" />
-<glyph unicode="&#xe6a2;" d="M772.4 672c-121.2 0-219.6-99.8-219.6-223.6 0-80.8 42-152.4 105-190.4h-291.6c63 38 105 109.6 105 190.4 0 123.8-98.4 223.8-219.6 223.8-121.2 0-219.6-100.4-219.6-224 0-123.8 98.4-224.2 219.6-224.2h520.8c121.2 0 219.6 100.2 219.6 224s-98.4 224-219.6 224zM256 320c-70.6 0-128 57.4-128 128s57.4 128 128 128 128-57.4 128-128c0-70.6-57.4-128-128-128zM768 320c-70.6 0-128 57.4-128 128s57.4 128 128 128 128-57.4 128-128c0-70.6-57.4-128-128-128zM768 544c-53 0-96-43-96-96s43-96 96-96 96 43 96 96c0 53-43 96-96 96zM256 544c-53 0-96-43-96-96s43-96 96-96 96 43 96 96c0 53-43 96-96 96z" />
-<glyph unicode="&#xe6a3;" d="M772.4 672c-121.2 0-219.6-100.2-219.6-224 0-80.8 42-151.4 105-190.8h-291.6c63 39.4 105 110 105 190.8 0 123.8-98.4 224-219.6 224-121.2 0-219.6-100.2-219.6-224 0-123.8 98.4-224 219.6-224h520.8c121.2 0 219.6 100.2 219.6 224s-98.4 224-219.6 224zM64.6 448c0 105.2 84 190.8 187 190.8 103.2 0 187-85.6 187-190.8s-84-190.8-187-190.8c-103.2 0-187 85.6-187 190.8zM772.4 257.2c-103.2 0-187 85.6-187 190.8s84 190.8 187 190.8 187-85.6 187-190.8-83.8-190.8-187-190.8zM768 544c53 0 96-43 96-96s-43-96-96-96-96 43-96 96c0 53 43 96 96 96M768 576c-70.6 0-128-57.4-128-128s57.4-128 128-128 128 57.4 128 128c0 70.6-57.4 128-128 128v0zM256 544c53 0 96-43 96-96s-43-96-96-96-96 43-96 96c0 53 43 96 96 96M256 576c-70.6 0-128-57.4-128-128s57.4-128 128-128 128 57.4 128 128c0 70.6-57.4 128-128 128v0z" />
-<glyph unicode="&#xe6a4;" d="M789.2 277.6c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM512 277.6c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM234.8 277.6c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM789.2 554.8c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM512 554.8c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM234.8 554.8c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM789.2 618.4c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8c-59 0-106.8-47.8-106.8-106.8 0-59 47.8-106.8 106.8-106.8zM512 832c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8 0 59-47.8 106.8-106.8 106.8zM234.8 832c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8 0 59-47.8 106.8-106.8 106.8z" />
-<glyph unicode="&#xe6a5;" d="M789.2 277.6c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM789.2 96c-41.2 0-74.8 33.6-74.8 74.8 0 41.2 33.6 74.8 74.8 74.8s74.8-33.6 74.8-74.8c0-41.2-33.6-74.8-74.8-74.8zM512 277.6c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM512 96c-41.2 0-74.8 33.6-74.8 74.8 0 41.2 33.6 74.8 74.8 74.8s74.8-33.6 74.8-74.8c0-41.2-33.6-74.8-74.8-74.8zM234.8 277.6c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM234.8 96c-41.2 0-74.8 33.6-74.8 74.8 0 41.2 33.6 74.8 74.8 74.8s74.8-33.6 74.8-74.8c0-41.2-33.4-74.8-74.8-74.8zM789.2 554.8c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM789.2 373.2c-41.2 0-74.8 33.6-74.8 74.8s33.6 74.8 74.8 74.8 74.8-33.6 74.8-74.8c0-41.2-33.6-74.8-74.8-74.8zM512 554.8c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM512 373.2c-41.2 0-74.8 33.6-74.8 74.8s33.6 74.8 74.8 74.8 74.8-33.6 74.8-74.8c0-41.2-33.6-74.8-74.8-74.8zM234.8 554.8c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8zM234.8 373.2c-41.2 0-74.8 33.6-74.8 74.8s33.6 74.8 74.8 74.8 74.8-33.6 74.8-74.8c0-41.2-33.4-74.8-74.8-74.8zM789.2 618.4c59 0 106.8 47.8 106.8 106.8s-47.8 106.8-106.8 106.8c-59 0-106.8-47.8-106.8-106.8 0-59 47.8-106.8 106.8-106.8zM789.2 800c41.2 0 74.8-33.6 74.8-74.8s-33.6-74.8-74.8-74.8-74.8 33.6-74.8 74.8c0 41.2 33.4 74.8 74.8 74.8zM512 832c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8 0 59-47.8 106.8-106.8 106.8zM512 650.4c-41.2 0-74.8 33.6-74.8 74.8s33.6 74.8 74.8 74.8 74.8-33.6 74.8-74.8c0-41.2-33.6-74.8-74.8-74.8zM234.8 832c-59 0-106.8-47.8-106.8-106.8s47.8-106.8 106.8-106.8c59 0 106.8 47.8 106.8 106.8 0 59-47.8 106.8-106.8 106.8zM234.8 650.4c-41.2 0-74.8 33.6-74.8 74.8 0 41.2 33.6 74.8 74.8 74.8s74.8-33.6 74.8-74.8c0-41.2-33.4-74.8-74.8-74.8z" />
-<glyph unicode="&#xe6a6;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM512 66.6c-117.2 0-222.2 53.2-292.2 136.6 35.6 15.4 124.4 47.4 180.6 63.8 4.4 1.4 5.2 1.6 5.2 21.4 0 21.2-2.4 36.2-7.6 47.2-7 15-15.4 40.4-18.4 63.2-8.4 9.8-19.8 29-27.2 65.8-6.4 32.4-3.4 44.2 0.8 55.2 0.4 1.2 1 2.4 1.2 3.6 1.6 7.4-0.6 47-6.2 77.6-3.8 21 1 65.6 30 102.6 18.2 23.4 53.2 52 116 56h35c63.8-4 98.8-32.6 117-56 29-37 33.8-81.6 29.8-102.6-5.6-30.6-7.8-70-6.2-77.6 0.2-1.2 0.8-2.4 1.2-3.4 4.2-11 7.4-22.8 0.8-55.2-7.4-36.8-18.8-56-27.2-65.8-3-22.8-11.4-48-18.4-63.2-6.6-13.8-13.2-30.2-13.2-46.6 0-19.8 0.8-20 5.4-21.4 53.4-15.8 145.4-47.6 186-64.2-70-83.6-175-137-292.4-137z" />
-<glyph unicode="&#xe6a7;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416 0 229.8-186.2 416-416 416zM512 829.4c210.2 0 381.4-171 381.4-381.4 0-93-33.4-178.2-88.8-244.4-40 16.4-131.8 48.2-185.8 64.2-4.8 1.4-5.4 1.8-5.4 21.4 0 16.2 6.6 32.6 13.2 46.6 7.2 15 15.4 40.4 18.4 63.2 8.4 9.8 20 29 27.2 65.8 6.4 32.4 3.4 44.2-0.8 55.2-0.4 1.2-1 2.4-1.2 3.4-1.6 7.6 0.6 47 6.2 77.6 3.8 21-1 65.6-29.8 102.6-18.2 23.4-53.2 52-117 56h-35c-62.8-4-97.6-32.6-116-56-29-37-33.8-81.6-30-102.6 5.6-30.6 7.8-70 6.2-77.6-0.4-1.4-0.8-2.4-1.2-3.6-4.2-11-7.4-22.8-0.8-55.2 7.4-36.8 18.8-56 27.2-65.8 3-22.8 11.4-48 18.4-63.2 5.2-11 7.6-26 7.6-47.2 0-19.8-0.8-20-5.2-21.4-56.2-16.6-145.2-48.6-180.8-64-55.8 66.4-89.4 151.8-89.4 245 0 210.2 171.2 381.4 381.4 381.4z" />
-<glyph unicode="&#xe6a8;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM546 414h-226v34h192v256h34v-290z" />
-<glyph unicode="&#xe6a9;" d="M512 864c-229.8 0-416-186.2-416-416s186.2-416 416-416c229.8 0 416 186.2 416 416s-186.2 416-416 416zM512 66.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4 0-210.2-171.2-381.4-381.4-381.4zM512 448h-192v-34.6h226.6v290.6h-34.6z" />
-<glyph unicode="&#xe6aa;" d="M960 546h-342.8l-105.2 318.2-105.2-318.2h-342.8l280.4-195.8-109.2-318.2 276.8 197.2 276.8-197.2-109.4 318.2 280.6 195.8z" />
-<glyph unicode="&#xe6ab;" d="M960 546h-342.8l-105.2 318.2-105.2-318.2h-342.8l280.4-195.8-109.2-318.2 276.8 197.2 276.8-197.2-109.4 318.2 280.6 195.8zM725.2 117.6l-213.2 152-213.2-152 85.2 245-216 149.4h262l82 246.6 82-246.6h262l-216-149.2 85.2-245.2z" />
-<glyph unicode="&#xe6ac;" d="M736 160h-544v512h416.2l32 32h-480.2v-576h608v448.2l-32-32zM475.2 391.8l-19.4 19.4 342.6 342.6-22.6 22.8-359.8-360v-64.6h64.4l360.2 360-22.8 22.6zM888.4 799.4l-25 25c-5.4 4.8-12.4 7.6-20 7.6s-14.6-3-19.8-7.6l-24.2-24.4 0.2-0.2 22.4-22.6 42-42 24.4 24.4c4.8 5.2 7.6 12.2 7.6 19.8 0.2 7.6-2.8 14.6-7.6 20z" />
-<glyph unicode="&#xe6ad;" d="M547 421.6c20.2 13.4 46.2 30.4 89 61 37.2 26.4 99.8 72.8 99.8 194.8 0 98.6-57.4 186.6-57.4 186.6h-332.6c0 0-57.6-88.8-57.6-187.6 0-122 62.4-168.2 99.4-194.6 42.8-30.4 70-49.2 87.4-60.6 10-6.6 19-27 19-36v-321.2h-144v-32h320v32h-144v321.4c0 10 11.2 29.6 21 36.2zM609.2 510.2c-6.2-4.4-12.2-8.6-17.8-12.6-6.4 8.4-12.8 16.6-19.4 25 6 4.2 12.2 8.6 19 13.4 18.4 13 41.4 27.6 60 60.6 9.4-5 18.6-10.2 27.8-15.6-21.6-37.8-48.4-55.8-69.6-70.8zM692.4 609.4l-33.4 12.6c3.4 7.6 4 18 4 18h37.8c0.4-6.4-3.2-21.8-8.4-30.6zM320.2 672c0 1.4 0 3 0 4.4 0 65.8 29.2 129.6 44.2 155.6h295.6c14.8 0 44-89 44-154.6 0-1.8 0-3.6 0-5.4h-383.8z" />
-<glyph unicode="&#xe6ae;" d="M128 416c0-10.8 0.4-21.4 1.2-32 2.6-34.2 9.4-67.4 19.8-98.8 15.8-47.6 39.8-91.4 70.6-129.6 76.2-94.8 193.2-155.6 324.4-155.6 229.8 0 416 186.2 416 416 0 131.2-60.8 248.2-155.6 324.4-38.2 30.8-82 54.8-129.6 70.6-31.4 10.4-64.6 17.2-98.8 19.8-10.6 0.8-21.2 1.2-32 1.2v-416h-416zM64 480c0-10.8 0.4-21.4 1.2-32h446.8v32 414.8c-10.6 0.8-21.2 1.2-32 1.2-229.8 0-416-186.2-416-416z" />
-<glyph unicode="&#xe6af;" d="M128 416c0-10.8 0.4-21.4 1.2-32 2.6-34.2 9.4-67.4 19.8-98.8 15.8-47.6 39.8-91.4 70.6-129.6 76.2-94.8 193.2-155.6 324.4-155.6 229.8 0 416 186.2 416 416 0 131.2-60.8 248.2-155.6 324.4-38.2 30.8-82 54.8-129.6 70.6-31.4 10.4-64.6 17.2-98.8 19.8-10.6 0.8-21.2 1.2-32 1.2v-416h-416zM161.4 384h414.6v32 382.6c40.6-3.4 80-13 117.4-28.8 31.8-13.4 61.2-31 88.2-52.2 11.8-9.4 23.2-19.4 33.8-30.2 23.2-23.2 43-48.8 59.4-76.8 8.6-14.6 16.2-29.6 22.8-45.4 20-47.4 30.2-97.6 30.2-149.4s-10.2-102.2-30.2-149.4c-19.4-45.8-47-86.8-82.4-122-35.2-35.2-76.4-63-122-82.4-47.4-20-97.6-30.2-149.4-30.2s-102.2 10.2-149.4 30.2c-15.6 6.6-30.8 14.2-45.4 22.8-27.8 16.4-53.6 36.2-76.8 59.4-10.8 10.8-20.8 22-30.2 33.8-21.2 27-38.8 56.4-52.2 88.2-15.6 37.8-25.2 77.2-28.4 117.8zM64 480c0-10.8 0.4-21.4 1.2-32h446.8v32 414.8c-10.6 0.8-21.2 1.2-32 1.2-229.8 0-416-186.2-416-416zM96 480c0 51.8 10.2 102.2 30.2 149.4 19.4 45.8 47 86.8 82.4 122 35.2 35.2 76.4 63 122 82.4 47.2 20 97.6 30.2 149.4 30.2v-384h-384z" />
-<glyph unicode="&#xe6b0;" d="M512 832c211.8 0 383.4-171.4 383.8-383l110 105 18-18.2-140.6-135.8-133.2 135.8 18 18.2 102.2-104.8c-0.6 197-161 357.2-358.2 357.2-197.6 0-358.4-160.8-358.4-358.4 0-197.6 160.8-358.4 358.4-358.4 157.2 0 291 102 339 243.2l24.8-7c-51.2-152.2-194.6-261.8-363.8-261.8-212 0-384 172-384 384s172 384 384 384z" />
-<glyph unicode="&#xe6b1;" d="M547 421.6c20.2 13.4 46.2 30.4 89 61 37.2 26.4 99.8 72.8 99.8 194.8 0 98.6-57.4 186.6-57.4 186.6h-332.6c0 0-57.6-88.8-57.6-187.6 0-122 62.4-168.2 99.4-194.6 42.8-30.4 70-49.2 87.4-60.6 10-6.6 19-27 19-36v-321.2h-144v-32h320v32h-144v321.4c0 10 11.2 29.6 21 36.2zM364.2 832h295.8c14.8 0 44-89 44-154.6 0-1.8 0-3.6 0-5.4h-383.8c0 1.4 0 3 0 4.4 0 65.8 29.2 129.6 44 155.6zM512.2 448c-11.4 0-22 3-31.4 8.2-15.8 10.6-39.8 27-74.6 51.8-15.2 10.8-38 27.2-55.6 53.4-14.8 22.2-24.2 48-28.2 78.4h379.2c-10.8-79.8-55.6-111.6-83.8-131.6-30-21.4-51.4-36.6-68.6-48.4-10.4-7.4-23.2-11.8-37-11.8z" />
-<glyph unicode="&#xe6b2;" d="M544 416v32 96h-64v-96-32h-128v-64h128v-32-96h64v96 32h128v64h-96zM672 704v64c-1 36.4-27.2 64-64.4 64h-198.2c-37.2 0-57.4-27.4-57.4-64v-64h-256v-640h832v640h-256zM384 763.8c0 20.4 5.8 36.2 27.4 36.2h194.2c20.8 0 34.4-15.4 34.4-36.2v-59.8h-256v59.8zM704 320h-128v-128h-128v128h-128v128h128v128h128v-128h128v-128z" />
-<glyph unicode="&#xe6b3;" d="M544 544v-96-32h128v-64h-128v-32-96h-64v96 32h-128v64h128v32 96h64M576 576h-128v-128h-128v-128h128v-128h128v128h128v128h-128v128 0zM672 704v64c-1 36.4-27.2 64-64.4 64h-198.2c-37.2 0-57.4-27.4-57.4-64v-64h-256v-640h832v640h-256zM384 763.8c0 20.4 5.8 36.2 27.4 36.2h194.2c20.8 0 34.4-15.4 34.4-36.2v-59.8h-256v59.8zM896 96h-768v576h768v-576z" />
-<glyph unicode="&#xe6b4;" d="M832 704v32h-64v-32h-96v59.8 4.2c-1 36.4-27.2 64-64.4 64h-198.2c-37.2 0-57.4-27.4-57.4-64v-4.2-59.8h-96v32h-64v-32h-96v-640h832v640h-96zM384 705v58.8c0 20.4 5.8 36.2 27.4 36.2h194.2c20.8 0 34.4-15.4 34.4-36.2v-58.8-1h-256v1zM896 96h-768v448h768v-448zM896 576h-768v96h64v-32h64v32h512v-32h64v32h64v-96z" />
-<glyph unicode="&#xe6b5;" d="M192 736h64v-32h-64v32zM96 544h832v-480h-832v480zM768 736h64v-32h-64v32zM832 704v-64h-64v64h-96v59.8 4.2c-1 36.4-27.2 64-64.4 64h-198.2c-37.2 0-57.4-27.4-57.4-64v-4.2-59.8h-96v-64h-64v64h-96v-128h832v128h-96zM640 705v-1h-256v1 58.8c0 20.4 5.8 36.2 27.4 36.2h194.2c20.8 0 34.4-15.4 34.4-36.2v-58.8z" />
-<glyph unicode="&#xe6b6;" d="M384 640c0-35.346-28.654-64-64-64s-64 28.654-64 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64zM877.6 381.2l-408 427.6c-15.2 15.2-35.2 23-55 23.2h-223c-35.2 0-63.6-28.4-63.6-63.6v-216.2c0-21.6 8.6-41 22.6-55.4l428-414.4c12.2-12.2 28.6-18.4 45-18.4 16.2 0 32.6 6 45 18.4l209 208.8c12.4 12.4 18.4 28.6 18.4 45s-6.2 32.8-18.4 45zM320 544c-53 0-96 43-96 96s43 96 96 96 96-43 96-96-43-96-96-96z" />
-<glyph unicode="&#xe6b7;" d="M414.2 800c12.2-0.2 23.8-5 32.4-13.6l408.2-427.6c5.8-5.8 9-13.8 9-22.4s-3.2-16.4-9-22.2l-208.8-209.2c-5.8-5.8-13.8-9-22.2-9-8.6 0-16.6 3.2-22.4 9l-0.4 0.4-427.8 414.2c-8.6 9-13.2 20.6-13.2 32.8v216c0 17.4 14.2 31.6 31.6 31.6h222.6M414.4 832h-222.8c-35.2 0-63.6-28.4-63.6-63.6v-216.2c0-21.6 8.6-41 22.6-55.4l428-414.4c12.2-12.2 28.6-18.4 45-18.4 16.2 0 32.6 6 45 18.4l209 208.8c12.4 12.4 18.4 28.6 18.4 45s-6.2 32.8-18.4 45l-408 427.6c-15.4 15.2-35.2 23-55.2 23.2v0zM320 704c35.4 0 64-28.6 64-64s-28.6-64-64-64-64 28.6-64 64 28.6 64 64 64M320 736c-53 0-96-43-96-96s43-96 96-96 96 43 96 96-43 96-96 96v0z" />
-<glyph unicode="&#xe6b8;" d="M512.2 832c-247.6 0-448.2-197.4-448.2-442 0-128.6 55.8-244 144.2-326h607.6c88.4 82 144.2 197.4 144.2 326 0 244.6-200.2 442-447.8 442zM556.4 375.8c-0.8-0.8-1.6-1.6-2.4-2.4-9.8-12.2-24.8-20-41.8-20-29.8 0-53.8 23.8-53.8 53.2 0 15.6 7 29.4 17.8 39.2 1.4 1.6 2.6 3.2 4.8 4.8l218.4 135.2 20-21.6-163-188.4zM807.2 101l-4.8-5-29.8 30-38.4 38.4 21 20.8 47.2-46.4c29.6 31.8 45.4 60.6 62.8 99 19.4 42.4 30.4 86.2 33 134.2h-58.2v30h58.8c-1.2 46-11.2 94-30.2 138-17.2 40-41 75.6-70.6 107.6l-51.8-51.4-10.2 10.2-10 9.6-1 1 51.8 51.4c-33.4 31-72 55.4-114.2 73-43.2 18-88.4 26.4-136.4 27.8v-69.2h-28v69.4c-48-1.4-93-9.8-136.2-27.8-42.4-17.6-81.2-42.2-114.8-73.4l51.6-51.2-1-1-20-19.6-51.8 51.2c-29.6-32-53.4-68-70.6-107.8-19-44-29.2-92-30.2-138h58.8v-30h-58.4c2.6-48 13.6-91.8 33-134.2 17.6-38.4 33.2-67.4 62.8-99.2l47 46.4 21.2-20.8-38.4-38-29.6-29.8-1.2 1.2c-81.6 74.6-125 193.6-125 293.2 0 0.2 0 0.4 0 0.6 0 0.2 0 0.6 0 0.6 0 168.4 107.6 315.2 251.8 376.2 50.4 21.4 106.6 32 165 32 0 0 0 0 0 0s0 0 0 0 0 0 0 0c58-0.2 115.8-10.4 165.8-32 145.6-62.8 250.6-208.2 250.6-376.6 0-0.2 0-0.4 0-0.6 0-0.2 0-0.4 0-0.6 0-116.2-50.6-218.8-121.4-289.2z" />
-<glyph unicode="&#xe6b9;" d="M960 390c0 244.2-199.4 441.4-446.4 442-0.4 0-1 0-1.4 0 0 0 0 0 0 0 0 0 0 0 0 0-247.6 0-448.2-197.4-448.2-442 0-0.2 0-0.4 0-0.4 0-0.2 0-0.4 0-0.6 0-128 55.2-243 143-323.8l1-1 73.2 73.2-22.6 22.6-50.6-50.6c-31.6 34.4-57.2 72-76 113.6-20.8 46-32.8 94.8-35.4 145h63.4v32h-63.8c1.2 52 12.2 102.6 32.6 150.2 18.4 43.2 44 82.6 75.8 117.2l55.4-55.4 11 11 10.6 10.4 1 1-55.6 55.6c36 33.6 77.4 60.4 123 79.4 46.4 19.4 95.4 28.6 146 30.2v-73.6h32v73.8c50.6-1.6 99.8-10.6 146.2-30.2 45.4-19 86.6-45.6 122.6-79.2l-55.8-55.8 1-1 10.6-10.4 11-11 55.8 55.8c32-34.6 57.6-74 76-117.4 20.4-47.8 31.2-98.2 32.4-150.4h-63.8v-32h63.4c-2.8-50.2-14.6-99.2-35.4-145-19-41.6-44.6-79.2-76.2-113.6l-50.8 50.4-22.6-22.6 73.4-73.2 5.2 5c85.4 80.6 139.2 194 139.2 320 0 0.2 0 0.4 0 0.6-0.2-0.2-0.2 0-0.2 0.2zM480.8 450.6c-2.2-1.6-3.4-3.2-4.8-4.8-10.8-9.8-17.8-23.6-17.8-39.2 0-29.4 24.2-53.2 53.8-53.2 17 0 32 7.8 41.8 20 0.8 0.8 1.8 1.6 2.4 2.4l162.8 188.4-20 21.6-218.2-135.2z" />
-<glyph unicode="&#xe6ba;" d="M800 614.2c0 155.6-132.2 281.8-288 281.8-155.8 0-288-126.2-288-282 0-62 26.4-118 60.4-166h-0.6c21.8-30 42.8-55.4 63-90 44-75.6 37.2-148.6 37.4-163.2v-2.8h64v256l-64 128h33.2l62.8-128v-256h64v256l62.8 128h33l-64-128v-256h64v2.8c0 17.8-7.2 87.6 36.8 163.2 20.2 34.6 41.2 60 63 90h-0.2c34 48 60.4 104 60.4 166.2zM448 32h128v-32h-128v32zM416 96h192v-32h-192v32zM416 160h192v-32h-192v32z" />
-<glyph unicode="&#xe6bb;" d="M800 614.2c0 155.6-132.2 281.8-288 281.8-155.8 0-288-126.2-288-282 0-62 26.4-118 60.4-166h-0.6c21.8-30 42.8-55.4 63-90 44-75.6 37.2-148.6 37.4-163.2v-2.8h256v2.8c0 17.8-7.2 87.6 36.8 163.2 20.2 34.6 41.2 60 63 90h-0.2c33.8 48 60.2 104 60.2 166.2zM702 451.2c-1.2-1.6-2.2-3-3.4-4.6-16.2-21.8-33-44.4-49.4-72.2-34.6-59.4-40.8-115.8-41.6-150.2h-31.6v223.8l64 128h-33.2l-62.8-128v-224h-64v224l-62.8 128h-33.2l64-128v-224h-31.8c-1 34.4-7.8 91.4-41.8 150-9 15.4-18.2 30-27.4 42h0.4l-37.2 51.2c-31.6 43.2-54.2 94.2-54.2 147.2 0 66.8 32 129.6 79.2 176.8s110 73.4 176.8 73.4c66.8 0 129.6-26.2 176.8-73.4 47.2-47.2 79.2-110 79.2-176.8 0-53-22.6-103.8-54.2-147l-11.8-16.2zM448 32h128v-32h-128v32zM416 96h192v-32h-192v32zM416 160h192v-32h-192v32z" />
-<glyph unicode="&#xe6bc;" d="M736 832h-448c-35.4 0-64-28.6-64-64v-640c0-35.4 28.6-64 64-64h448c35.4 0 64 28.6 64 64v640c0 35.4-28.6 64-64 64zM720 400v-256h-96v256h96zM720 560v-96h-96v96h96zM560 240v-96h-96v96h96zM560 400v-96h-96v96h96zM560 560v-96h-96v96h96zM400 240v-96h-96v96h96zM400 400v-96h-96v96h96zM400 560v-96h-96v96h96zM304 656v96h416v-96h-416z" />
-<glyph unicode="&#xe6bd;" d="M288 640h448v128h-448v-128zM320 736h384v-64h-384v64zM736 832h-448c-35.4 0-64-28.6-64-64v-640c0-35.4 28.6-64 64-64h448c35.4 0 64 28.6 64 64v640c0 35.4-28.6 64-64 64zM768 128c0-17.6-14.4-32-32-32h-448c-17.6 0-32 14.4-32 32v640c0 17.6 14.4 32 32 32h448c17.6 0 32-14.4 32-32v-640zM320 480v64 32h-32v-128h128v32h-32zM320 320v64 32h-32v-128h128v32h-32zM320 160v64 32h-32v-128h128v32h-32zM480 480v64 32h-32v-128h128v32h-32zM640 480v64 32h-32v-128h128v32h-32zM480 320v64 32h-32v-128h128v32h-32zM480 160v64 32h-32v-128h128v32h-32zM640 160v64 192h-32v-288h128v32h-32z" />
-<glyph unicode="&#xe6be;" d="M816 464h-569.4l132.6 148.8c5.8 6.8 6.4 16.2 0.2 22.4s-17 6.6-22.8 0.2l-160-176c-0.4-0.4-0.8-0.8-1-1.2-0.2-0.2-0.2-0.4-0.4-0.6-0.2-0.2-0.4-0.4-0.6-0.8-0.2-0.2-0.2-0.4-0.4-0.6-0.2-0.2-0.2-0.4-0.4-0.6-0.2-0.2-0.2-0.4-0.4-0.8-0.2-0.2-0.2-0.4-0.4-0.6 0-0.2-0.2-0.4-0.2-0.8 0-0.2-0.2-0.6-0.2-0.8 0-0.2-0.2-0.4-0.2-0.8 0-0.2-0.2-0.6-0.2-0.8 0-0.2 0-0.6-0.2-0.8 0-0.2 0-0.4 0-0.6-0.2-1-0.2-2.2 0-3.2 0-0.2 0-0.4 0-0.6 0-0.2 0-0.6 0.2-0.8 0-0.2 0.2-0.6 0.2-0.8 0-0.2 0.2-0.4 0.2-0.8 0-0.2 0.2-0.6 0.2-0.8 0-0.2 0.2-0.4 0.2-0.8 0-0.2 0.2-0.4 0.4-0.6 0.2-0.2 0.2-0.4 0.4-0.8 0.2-0.2 0.2-0.4 0.4-0.6 0.2-0.2 0.2-0.4 0.4-0.6 0.2-0.2 0.4-0.4 0.6-0.8 0.2-0.2 0.2-0.4 0.4-0.6 0.4-0.4 0.6-0.8 1-1.2l160-176c3.2-3.4 7.2-4.6 11.4-4.6s8.2 1.6 11.4 4.6c6.2 6.2 6 16 0 22.6l-132.8 148.8h569.4c8.8 0 16 7.2 16 16 0 8.8-7.2 16-16 16z" />
-<glyph unicode="&#xe6bf;" d="M496 752v-569.4l-148.8 132.6c-6.8 5.8-16.2 6.4-22.4 0.2-6.2-6.2-6.6-17-0.2-22.8l176-160c0.4-0.4 0.8-0.8 1.2-1 0.2-0.2 0.4-0.2 0.6-0.4 0.2-0.2 0.4-0.4 0.8-0.6 0.2-0.2 0.4-0.2 0.6-0.4 0.2-0.2 0.4-0.2 0.6-0.4 0.2-0.2 0.4-0.2 0.8-0.4 0.2-0.2 0.4-0.2 0.6-0.4 0.2 0 0.4-0.2 0.8-0.2 0.2 0 0.6-0.2 0.8-0.2 0.2 0 0.4-0.2 0.8-0.2 0.2 0 0.6-0.2 0.8-0.2 0.2 0 0.6 0 0.8-0.2 0.2 0 0.4 0 0.6 0 1-0.2 2.2-0.2 3.2 0 0.2 0 0.4 0 0.6 0 0.2 0 0.6 0 0.8 0.2 0.2 0 0.6 0.2 0.8 0.2 0.2 0 0.4 0.2 0.8 0.2 0.2 0 0.6 0.2 0.8 0.2 0.2 0 0.4 0.2 0.8 0.2 0.2 0 0.4 0.2 0.6 0.4 0.2 0.2 0.4 0.2 0.8 0.4 0.2 0.2 0.4 0.2 0.6 0.4 0.2 0.2 0.4 0.2 0.6 0.4 0.2 0.2 0.4 0.4 0.8 0.6 0.2 0.2 0.4 0.2 0.6 0.4 0.4 0.4 0.8 0.6 1.2 1l176 160c3.4 3.2 4.6 7.2 4.6 11.4s-1.6 8.2-4.6 11.4c-6.2 6.2-16 6-22.6 0l-148.8-132.8v569.4c0 8.8-7.2 16-16 16-8.8 0-16-7.2-16-16z" />
-<glyph unicode="&#xe6c0;" d="M208 432h569.4l-132.6-148.8c-5.8-6.8-6.4-16.2-0.2-22.4 6.2-6.2 17-6.6 22.8-0.2l160 176c0.4 0.4 0.8 0.8 1 1.2 0.2 0.2 0.2 0.4 0.4 0.6 0.2 0.2 0.4 0.4 0.6 0.8 0.2 0.2 0.2 0.4 0.4 0.6 0.2 0.2 0.2 0.4 0.4 0.6 0.2 0.2 0.2 0.4 0.4 0.8 0.2 0.2 0.2 0.4 0.4 0.6 0 0.2 0.2 0.4 0.2 0.8 0 0.2 0.2 0.6 0.2 0.8 0 0.2 0.2 0.4 0.2 0.8 0 0.2 0.2 0.6 0.2 0.8 0 0.2 0 0.6 0.2 0.8 0 0.2 0 0.4 0 0.6 0.2 1 0.2 2.2 0 3.2 0 0.2 0 0.4 0 0.6 0 0.2 0 0.6-0.2 0.8 0 0.2-0.2 0.6-0.2 0.8 0 0.2-0.2 0.4-0.2 0.8 0 0.2-0.2 0.6-0.2 0.8 0 0.2-0.2 0.4-0.2 0.8 0 0.2-0.2 0.4-0.4 0.6-0.2 0.2-0.2 0.4-0.4 0.8-0.2 0.2-0.2 0.4-0.4 0.6-0.2 0.2-0.2 0.4-0.4 0.6-0.2 0.2-0.4 0.4-0.6 0.8-0.2 0.2-0.2 0.4-0.4 0.6-0.4 0.4-0.6 0.8-1 1.2l-160 176c-3.2 3.4-7.2 4.6-11.4 4.6s-8.2-1.6-11.4-4.6c-6.2-6.2-6-16 0-22.6l132.6-148.6h-569.2c-8.8 0-16-7.2-16-16 0-9 7.2-16.2 16-16.2z" />
-<glyph unicode="&#xe6c1;" d="M528 144v569.4l148.8-132.6c6.8-5.8 16.2-6.4 22.4-0.2 6.2 6.2 6.6 17 0.2 22.8l-176 160c-0.4 0.4-0.8 0.8-1.2 1-0.2 0.2-0.4 0.2-0.6 0.4-0.2 0.2-0.4 0.4-0.8 0.6-0.2 0.2-0.4 0.2-0.6 0.4-0.2 0.2-0.4 0.2-0.6 0.4-0.2 0.2-0.4 0.2-0.8 0.4-0.2 0.2-0.4 0.2-0.6 0.4-0.2 0-0.4 0.2-0.8 0.2-0.2 0-0.6 0.2-0.8 0.2-0.2 0-0.4 0.2-0.8 0.2-0.2 0-0.6 0.2-0.8 0.2-0.2 0-0.6 0-0.8 0.2-0.2 0-0.4 0-0.6 0-1 0.2-2.2 0.2-3.2 0-0.2 0-0.4 0-0.6 0-0.2 0-0.6 0-0.8-0.2-0.2 0-0.6-0.2-0.8-0.2-0.2 0-0.4-0.2-0.8-0.2-0.2 0-0.6-0.2-0.8-0.2-0.2 0-0.4-0.2-0.8-0.2-0.2 0-0.4-0.2-0.6-0.4-0.2-0.2-0.4-0.2-0.8-0.4-0.2-0.2-0.4-0.2-0.6-0.4-0.2-0.2-0.4-0.2-0.6-0.4-0.2-0.2-0.4-0.4-0.8-0.6-0.2-0.2-0.4-0.2-0.6-0.4-0.4-0.4-0.8-0.6-1.2-1l-176-160c-3.4-3.2-4.6-7.2-4.6-11.4s1.6-8.2 4.6-11.4c6.2-6.2 16-6 22.6 0l148.8 132.6v-569.2c0-8.8 7.2-16 16-16s16 7.2 16 16z" />
-<glyph unicode="&#xe6c2;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM512 816c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zM160 432c-8.8 0-16 7.2-16 16 0 8.8 7.2 16 16 16s16-7.2 16-16c0-8.8-7.2-16-16-16zM215.2 258.2c-7.6-4.4-17.4-1.8-21.8 5.8-4.4 7.6-1.8 17.4 5.8 21.8 7.6 4.4 17.4 1.8 21.8-5.8 4.4-7.6 1.8-17.4-5.8-21.8zM221 616c-4.4-7.6-14.2-10.2-21.8-5.8-7.6 4.4-10.2 14.2-5.8 21.8s14.2 10.2 21.8 5.8c7.6-4.4 10.2-14.2 5.8-21.8zM328 766.6c7.6 4.4 17.4 1.8 21.8-5.8 4.4-7.6 1.8-17.4-5.8-21.8-7.6-4.4-17.4-1.8-21.8 5.8-4.4 7.6-1.8 17.4 5.8 21.8zM349.8 135.2c-4.4-7.6-14.2-10.2-21.8-5.8-7.6 4.4-10.2 14.2-5.8 21.8 4.4 7.6 14.2 10.2 21.8 5.8s10.2-14.2 5.8-21.8zM512 80c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zM528 420.2c-2.6-1.4-5.2-2.6-8-3.2v-245c0-4.4-3.6-8-8-8s-8 3.6-8 8v245c-8 2-15.2 7.2-19.8 15-6 10.4-5.4 23 0.4 32.6l-75.2 125.8c-4.6 7.6-2 17.4 5.4 22 7.6 4.6 17.4 2 22-5.4l76-126.8c10.8-0.2 21.2-6 26.8-16 9-15.6 3.8-35-11.6-44zM696 129.4c-7.6-4.4-17.4-1.8-21.8 5.8-4.4 7.6-1.8 17.4 5.8 21.8 7.6 4.4 17.4 1.8 21.8-5.8 4.4-7.6 1.8-17.4-5.8-21.8zM701.8 744.8c-4.4-7.6-14.2-10.2-21.8-5.8-7.6 4.4-10.2 14.2-5.8 21.8 4.4 7.6 14.2 10.2 21.8 5.8 7.6-4.4 10.2-14.2 5.8-21.8zM830.6 264c-4.4-7.6-14.2-10.2-21.8-5.8-7.6 4.4-10.2 14.2-5.8 21.8 4.4 7.6 14.2 10.2 21.8 5.8 7.6-4.4 10.4-14.2 5.8-21.8zM824.8 610.2c-7.6-4.4-17.4-1.8-21.8 5.8s-1.8 17.4 5.8 21.8c7.6 4.4 17.4 1.8 21.8-5.8 4.6-7.6 1.8-17.4-5.8-21.8zM864 432c-8.8 0-16 7.2-16 16 0 8.8 7.2 16 16 16s16-7.2 16-16c0-8.8-7.2-16-16-16z" />
-<glyph unicode="&#xe6c3;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM806.2 153.8c-38.2-38.2-82.8-68.2-132.2-89.2-51.2-21.6-105.8-32.6-162-32.6-56.2 0-110.6 11-162 32.6-49.6 21-94 51-132.2 89.2-38.2 38.2-68.2 82.8-89.2 132.2-21.6 51.4-32.6 105.8-32.6 162 0 56.2 11 110.6 32.6 162 21 49.6 51 94 89.2 132.2 38.2 38.2 82.8 68.2 132.2 89.2 51.4 21.6 105.8 32.6 162 32.6 56.2 0 110.6-11 162-32.6 49.6-21 94-51 132.2-89.2 38.2-38.2 68.2-82.8 89.2-132.2 21.6-51.2 32.6-105.8 32.6-162 0-56.2-11-110.6-32.6-162-21-49.4-51-94-89.2-132.2zM528 800c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM528 96c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM880 448c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM176 448c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM352 752.8c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM704 143.2c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM832.8 624c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM223.2 272c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM223.2 624c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM832.8 272c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM704 752.8c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM352 143.2c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM512.8 480l-76 126.8c-4.6 7.6-14.4 10-22 5.4s-10-14.4-5.4-22l75.2-125.8c-5.8-9.6-6.4-22.2-0.4-32.6 4.4-7.8 11.6-12.8 19.8-15v-244.8c0-4.4 3.6-8 8-8s8 3.6 8 8v245c2.8 0.8 5.4 1.8 8 3.2 15.4 8.8 20.6 28.4 11.8 43.8-5.8 10-16.2 15.6-27 16z" />
-<glyph unicode="&#xe6c4;" d="M511.8 526h-129.8v-156h129.8l94.2-102.6v361.2zM729 839.8c-0.8 0.4-1.4 0.8-2.2 1.2-63.8 35-137 55-214.8 55-247.4 0-448-200.6-448-448 0-168.6 93.2-315.2 230.8-391.8 0.8-0.4 1.4-1 2.2-1.4 64-34.8 137.2-54.8 215-54.8 247.4 0 448 200.6 448 448 0 168.6-93.2 315.4-231 391.8zM787.8 249.2l-115.8 116.6v-153.4l39.2-39.8c-56-40.6-124.6-65.4-199-65.4-43.2 0-84.6 8.4-122.6 23-13 5-25.8 10.6-38 17.2-107.2 57.4-180.2 170.4-180.2 300.6 0 74.4 24.8 142.8 65.4 198.8l70.6-70.8h153.4l-147.2 147.6c56 40.4 124.2 65.2 198.8 65.2 43.2 0 84.4-8.4 122.6-23 12.2-4.8 24.4-10 35.8-16 108.4-57 182.6-170.6 182.6-301.6-0.4-74.8-25-143-65.6-199z" />
-<glyph unicode="&#xe6c5;" d="M175.6 454.6c-27.6-9-47.6-35-47.6-65.6 0-38 30.8-69 69-69h205.2c-4-50-20-107.2-2.2-174.6 15-56.8 78.8-99.4 104.8-73.6 10 9.8 7 30.4 7 67.6 0 85.6 35.6 172.2 79.6 217.4 18.8 19.4 50.4 26 80.4 27.2v-32h224v480h-223.8v-64c-41.2-1-105.2 10.4-151.6 13.2-104 6.2-204-4.8-252.6-16.2-48.6-11.4-70-26-70-61.2 0-12.8 3.8-24.6 10.2-34.6-23.6-9.4-40.2-32.4-40.2-59.4 0-14.4 4.8-27.6 12.8-38.4-23.8-9.2-40.8-32.4-40.8-59.6 0.2-25 14.8-46.8 35.8-57.2zM800 767.4c17.6 0 32-14.2 32-32 0-17.6-14.4-32-32-32s-32 14.2-32 32c0 17.6 14.4 32 32 32z" />
-<glyph unicode="&#xe6c6;" d="M848.4 441.4c27.6 9 47.6 35 47.6 65.6 0 38-30.8 69-69 69h-205.2c4 50 20 107.2 2.2 174.6-15 56.8-78.8 99.4-104.8 73.6-10-9.8-7-30.4-7-67.6 0-85.6-35.6-172.2-79.6-217.4-18.8-19.4-50.4-26-80.4-27.2v32h-224.2v-480h224v64c41.2 1 105.2-10.4 151.6-13.2 104-6.2 204 4.8 252.6 16.2 48.6 11.4 70 26 70 61.2 0 12.8-3.8 24.6-10.2 34.6 23.6 9.4 40.2 32.4 40.2 59.4 0 14.4-4.8 27.6-12.8 38.4 23.8 9.2 40.8 32.4 40.8 59.6-0.2 25-14.8 46.8-35.8 57.2zM224 128.6c-17.6 0-32 14.2-32 32 0 17.6 14.4 32 32 32s32-14.2 32-32c0-17.6-14.4-32-32-32z" />
-<glyph unicode="&#xe6c7;" d="M897.8 832h-65.8v-81.4c0-45-46.4-78.6-94.4-78.6s-97.6 33.6-97.6 78.6v81.4h-256v-81.4c0-45-48-78.6-96-78.6s-96 33.6-96 78.6v81.4h-65.8c-34.4 0-62.2-26.6-62.2-58.8v-715c0-32.2 27.8-58.2 62.2-58.2h771.6c34.4 0 62.2 26 62.2 58.4v714.8c0 32.2-27.8 58.8-62.2 58.8zM864 120.2c0-13.2-11.6-24-25.6-24l-653-0.2c-14 0.6-25.4 11.2-25.4 24.4v463c0 13.8 11.8 24.6 26.6 24.6h651c14.6 0 26.4-10.6 26.4-24.2v-463.6zM352 768c0-35.4-28.6-64-64-64v0c-35.4 0-64 28.6-64 64v64c0 35.4 28.6 64 64 64v0c35.4 0 64-28.6 64-64v-64zM800 768c0-35.4-28.6-64-64-64v0c-35.4 0-64 28.6-64 64v64c0 35.4 28.6 64 64 64v0c35.4 0 64-28.6 64-64v-64z" />
-<glyph unicode="&#xe6c8;" d="M915.2 679.6l-165 8-9.6 107.6c-2 22.6-22.2 38.4-45.8 36.6l-592-48.6c-23.6-2-40.6-21-38.8-43.4l42.4-471.6c2-22.6 22.4-38.4 45.8-36.6l30 2.4-4.8-91.6c-1.2-25.2 18.4-45.6 44.8-47l660.4-31.4c26.4-1.2 48.2 17.2 49.6 42.4l27.8 526.6c1.2 25-18.6 45.4-44.8 46.6zM205.2 669l-14.2-269.6-34.8-49.4-32 356c0 0.4 0 0.6 0 1s0 0.6 0 1c1 10 8.6 18 19 18.8l522 42.8c10.4 0.8 19.4-6 21-15.8 0-0.4 0.6-0.4 0.6-0.8 0-0.2 0.6-0.4 0.6-0.8l5.4-61.6-438 21c-26.4 0.8-48.4-17.6-49.6-42.6zM873.4 195.2l-93.4 110.6-55 65.4c-4.8 5.8-12.6 10.6-21.2 11s-15-3-22.2-8.2l-32.8-23.8c-7-4.2-12.4-7-19.8-6.6-7.2 0.4-13.6 3.2-18.2 7.6-1.6 1.6-4.6 4.4-7 6.8l-85.6 97.8c-6.2 7.8-16.4 12.8-27.6 13.4-11.4 0.6-22.4-4.2-29.6-11.2l-215.8-232.4 0.6 13.6 13.6 257.8 6.6 125.8c0 0.4 0 0.8 0 1 0 0.4 0 0.8 0 1 2.8 10.8 12.4 18.6 23.8 18l582.4-28c11.6-0.6 20.6-9.4 20.8-20.4 0-0.4 0.6-0.6 0.6-1 0-0.4 0.6-0.6 0.6-1l-20.8-397.2zM746.4 435.4c38.8 0 70.4 31.6 70.4 70.4s-31.4 70.4-70.4 70.4c-38.8 0-70.4-31.4-70.4-70.4s31.4-70.4 70.4-70.4z" />
-<glyph unicode="&#xe6c9;" d="M896.8 544h-688l682.4 136c17 3.2 28 19.4 24.8 36.2l-17.8 90.8c-3.2 16.8-19.6 27.6-36.6 24.4l-740.2-147.2c-17-3.2-28-19.4-24.8-36l17.8-90.8c1.2-5.6 4.2-10.4 7.8-14.4-14.8-2.4-26.2-14.4-26.2-29.8v-418.4c0-17 14-30.8 31.2-30.8h769.6c17.2 0 31.2 13.8 31.2 30.8v418.4c0 17-14 30.8-31.2 30.8zM610 155.2l-101.4 72.6-101.4-72.6 39 116.8-101.6 72h125.4l38.4 116.8 38.6-116.8h125.4l-101.6-72 39.2-116.8z" />
-<glyph unicode="&#xe6ca;" d="M755.6 759.8c-89.8 26.6-118-23.8-243.6-23.8s-153.8 50.6-243.6 23.8c-89.8-26.6-134.6-120.8-177-297.6-42.4-177-34.6-304.8 15.4-328.6 50-23.8 106.4 30.8 160.2 98.2 43.6 52.8 65.4 56.2 245 56.2 179.4 0 198-1.4 245-56.2 53.8-67.4 110.2-122 160.2-98.2 50 23.8 57.8 151.6 15.4 328.6-42.4 176.8-87.4 270.8-177 297.6zM256.4 432.6c-43.4 0-78.6 35.4-78.6 79.2 0 43.6 35.2 79.2 78.6 79.2 43.4 0 78.6-35.6 78.6-79.2s-35.2-79.2-78.6-79.2zM619.4 472.8c-21.2 0-38.6 17.4-38.6 38.8s17.4 38.8 38.6 38.8c21.4 0 38.8-17.4 38.8-38.8-0.2-21.4-17.4-38.8-38.8-38.8zM703.8 388c-21.2 0-38.6 17.4-38.6 38.8 0 21.6 17.4 38.8 38.6 38.8 21.4 0 38.8-17.4 38.8-38.8 0-21.6-17.4-38.8-38.8-38.8zM703.8 557.8c-21.2 0-38.6 17.4-38.6 38.8s17.4 38.8 38.6 38.8c21.4 0 38.8-17.4 38.8-38.8 0-21.4-17.4-38.8-38.8-38.8zM788.4 472.8c-21.4 0-38.6 17.4-38.6 38.8s17.4 38.8 38.6 38.8c21.2 0 38.6-17.4 38.6-38.8 0-21.4-17.2-38.8-38.6-38.8z" />
-<glyph unicode="&#xe6cb;" d="M64 449.2c0-130.4 99-225.2 221.4-225.2h453.2c122.4 0 221.4 94.8 221.4 225.2s-99 222.8-221.4 222.8h-453.2c-122.4 0-221.4-92.6-221.4-222.8zM809.6 493.4c21.4 0 38.8-17 38.8-38s-17.4-38-38.8-38-38.8 17-38.8 38 17.4 38 38.8 38zM724.6 576.4c21.6 0 39-17 39-38s-17.4-38-39-38c-21.4 0-38.8 17-38.8 38s17.4 38 38.8 38zM724.6 410.2c21.6 0 39-16.8 39-38 0-21-17.4-37.8-39-37.8-21.4 0-38.8 17-38.8 37.8 0.2 21.2 17.4 38 38.8 38zM639.6 493.4c21.6 0 39-17 39-38s-17.4-38-39-38c-21.4 0-38.8 17-38.8 38s17.4 38 38.8 38zM176 469.4c0 5.4 3.6 10.6 8.6 10.6h71.4v76.4 1.2c0 5.6 4.2 10.4 9.6 10.4h43.8c5.4 0 10.8-4.8 10.8-10.4v-1-76.6h75.6c5.4 0 10.4-5 10.4-10.6v-43.4c0-5.8-5-10-10.4-10h-75.8v-77.2-1c0-5.6-5.4-9.8-10.8-9.8h-43.8c-5.2 0-9.6 3.8-9.6 9v2.2 76.8h-70.6c-5.4 0-9.2 4.2-9.2 10v43.4z" />
-<glyph unicode="&#xe6cc;" d="M512 746.8c41.2-0.2 74.6 33.2 74.6 74.6 0 41.2-33.4 74.6-74.6 74.6-41.2 0-74.6-33.4-74.6-74.6 0-41.2 33.4-74.6 74.6-74.6zM586.8 730h-149.6c-56.4 0-93.2-49.6-93.2-96.8v-227.2c0-44 62-44 62 0v210h12v-571.2c0-60.8 84-58.8 86 0v329.2h16v-329.4c3.4-62.4 86-56.4 86 0.2v571.2h10v-210c0-44 64-44 64 0v227.2c0 47-37 96.8-93.2 96.8z" />
-<glyph unicode="&#xe6cd;" d="M512 344.6l256 231.4h-160v192h-192.8v-192h-159.2zM930.8 365.6l-142.8 110h-84l124-123.6h-101.2c-4.6 0-8.6-2.4-10.8-5.8l-36.8-91h-335l-36.8 91c-2 3.6-6.2 5.8-10.8 5.8h-101l124.4 123.6h-84.4l-142.8-110c-21.2-12.4-31.6-38-28.2-63.2l17.4-133.8c4.6-26.2 19.4-40.6 56.2-40.6h747.6c38.2 0 51.6 15.2 56.2 40.6l17.4 133.8c3.4 25.8-7.4 50.8-28.6 63.2z" />
-<glyph unicode="&#xe6ce;" d="M827.4 693.2c-4.8 18-8 28-8 28-5.2 18.6-18.4 18.6-38 21.8l-106.2 13.4c-13.2 2.2-13.2 2.2-18.4 13.6-17.4 39.2-22.8 62-41.8 62h-206c-19 0-24.2-22.8-41.6-62.2-5.2-11.2-5.2-11.2-18.4-13.6l-106.4-13.4c-19.4-3.2-33.4-5-38.6-23.6 0 0-2.4-8.2-7.4-26-6.4-23.8-9-21.2 13-21.2h604.8c22-0.2 19.6-2.6 13 21.2zM758.8 608h-493.6c-33.2 0-34.8-4.4-32.8-29.4l37.4-485.2c3.2-24.6 5.6-29.6 35-29.6h414.4c29.4 0 31.8 5 35 29.6l37.4 485.2c2 25.2 0.4 29.4-32.8 29.4z" />
-<glyph unicode="&#xe6cf;" d="M682 704v58c0 38.2-29 70-69 70h-202.2c-39.8 0-68.8-31.8-68.8-70v-58h-182v-64h18.4c0 0 10.8-1.2 16.4-6.8s7.8-18 7.8-18l38-483.4c3-58.8 3-67.8 72-67.8h398.8c69 0 69 8.8 72 67.6l38 483.2c0 0 2.2 12.6 7.8 18.2 5.6 5.6 16.4 6.8 16.4 6.8h18.4v64h-182v0.2zM384 762c0 19.2 15.6 30 35.4 30h183.4c19.8 0 37.2-11 37.2-30v-58h-256v58zM367 192l-20.6 384h40.6l21-384h-41zM534.2 192h-44v384h44v-384zM657.4 192h-40.8l21 384h40.6l-20.8-384z" />
-<glyph unicode="&#xe6d0;" d="M860.2 576h-696.4c-35.4 0-37.2-18.4-35.2-41l26-366c1.8-22.4 7-41 42.2-41h632.4c36 0 40.2 18.4 42.2 41l24.2 370.6c1.8 22.4 0 36.4-35.4 36.4zM852.4 673.4c-1 24.8-9 30.6-30.2 30.6 0 0-242.8 0-286.4 0-43.6 0-48.8-0.6-81.8 34.8-27.4 29.6-16.6 29.2-73.2 29.2-45.2 0-150.6 0-150.6 0-34.8 0-47.2 3-50.4-33.2-3-33.4-10-114.4-11-126.8h686.8l-3.2 65.4z" />
-<glyph unicode="&#xe6d1;" d="M953.4 115.6l-413.2 699c-5.8 10-16.6 17.4-28.2 17.4-11.8 0-22.6-7.4-28.2-17.4l-413.2-699c-5.6-10-9.6-26-3.8-35.8s16.4-15.8 28-15.8h834.2c11.6 0 22.2 6 28 15.8 6 9.8 2 26-3.6 35.8zM576 160h-128v96h128v-96zM576 320h-128v288h128v-288z" />
-<glyph unicode="&#xe6d2;" d="M960 454c-3.4 247.4-206.6 445.2-454 442s-445.2-206.6-442-454c3.4-247.4 206.6-445.2 454-442 247.4 3.4 445.4 206.6 442 454zM512 736.2c35.4 0 64-28.6 64-64s-28.6-64-64-64c-35.4 0-64 28.6-64 64s28.6 64 64 64zM600 170h-176v22h44v320h-44v24h132v-344h44v-22z" />
-<glyph unicode="&#xe6d3;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448 448 200.6 448 448-200.6 448-448 448zM768 416h-512v64h512v-64z" />
-<glyph unicode="&#xe6d4;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448 448 200.6 448 448-200.6 448-448 448zM768 416h-224v-224h-64v224h-224v64h224v224h64v-224h224v-64z" />
-<glyph unicode="&#xe6d5;" d="M513 544h-1c0.4 0 0.6 0 1 0zM737 640h-97c0 0 52-34 63.2-96h33.8c35.2 0 63-27.8 63-63v-64c0-35.2-27.8-65-63-65h-224c-35.2 0-65 29.8-65 65v63h-96v-63c0-23 5-45 13.8-65 25.2-56.4 81.8-96 147.2-96h224c88.4 0 159 72.6 159 161v64c0 88.4-70.6 159-159 159zM659.2 544c-24.2 56.6-80.2 96-146.2 96h-224c-88.4 0-161-70.6-161-159v-64c0-88.4 72.6-161 161-161h95c0 0-51.6 34-64.2 96h-30.8c-35.2 0-65 29.8-65 65v64c0 35.2 29.8 63 65 63h224c35.2 0 63-27.8 63-63v-64c0-0.4 0-0.6 0-1h96c0 0.4 0 0.6 0 1v64c0 22.4-4.6 43.8-12.8 63z" />
-<glyph unicode="&#xe6d6;" d="M798 320v0c20 0 33.6 14.2 33.6 31.8 0 6.6-2.2 12.2-5.6 18l-275.4 380.8c-9.2 10.6-23 17.4-38.6 17.4-15.4 0-29.2-6.8-38.4-17.4l-276-381.6c-3.4-5.2-5.2-11-5.2-17.4 0-17.4 13.6-31.6 33.6-31.6v0h572zM807.4 256h-590.6c-13.6 0-24.8-10.8-24.8-24.4v-79.2c0-13.4 11-24.4 24.8-24.4h590.6c13.6 0 24.6 11 24.6 24.4v79.2c0 13.6-11 24.4-24.6 24.4z" />
-<glyph unicode="&#xe6d7;" d="M151.4 768h16.2c13.4 0 24.4-10 24.4-23.4v-227l374.2 245c5 3.4 10.2 4.6 16.2 4.6 16.6 0 30.8-14 30.8-34v-126.2l237 156.4c5 3.4 10 4.6 16.2 4.6 16.6 0 29.8-14.8 29.8-34.8v-572c0-20-13.4-33-30-33-6.2 0-10.8 2.4-16.4 5.8l-236.6 155.2v-128c0-20-14.4-33-31-33-6.2 0-11 2.4-16.4 5.8l-373.8 244.4v-226c0-13.4-10.8-24.4-24.4-24.4h-16.2c-13.4 0-23.4 11-23.4 24.4v592.2c0 13.4 9.8 23.4 23.4 23.4z" />
-<glyph unicode="&#xe6d8;" d="M872.6 768h-16.2c-13.4 0-24.4-10-24.4-23.4v-227l-374.2 245c-5 3.4-10.2 4.6-16.2 4.6-16.6 0-30.8-14-30.8-34v-126.2l-237 156.4c-5 3.4-10.2 4.6-16.2 4.6-16.6 0-29.8-14.8-29.8-34.8v-572c0-20 13.4-33 30-33 6.2 0 10.8 2.4 16.4 5.8l236.6 155.2v-128c0-20 14.4-33 31-33 6.2 0 11 2.4 16.4 5.8l373.8 244.4v-226c0-13.4 10.8-24.4 24.4-24.4h16.2c13.4 0 23.4 11 23.4 24.4v592.2c0 13.4-9.8 23.4-23.4 23.4z" />
-<glyph unicode="&#xe6d9;" d="M656.4 832h-288.8c-26.2 0-47.6-21.4-47.6-47.8v-672.6c0-26.2 21.4-47.6 47.6-47.6h288.6c26.2 0 47.6 21.4 47.6 47.6v672.6c0.2 26.4-21.2 47.8-47.4 47.8zM480 760.2c0 4.2 3.4 7.8 7.8 7.8h48.6c4.2 0 7.8-3.4 7.8-7.8v-0.6c0-4.2-3.4-7.8-7.8-7.8h-48.6c-4.2 0-7.8 3.4-7.8 7.8v0.6zM456 768c4.4 0 8-3.6 8-8s-3.6-8-8-8-8 3.6-8 8c0 4.4 3.6 8 8 8zM512 95.8c-17.8 0-32.2 14.4-32.2 32.2 0 17.8 14.4 32.2 32.2 32.2 17.8 0 32.2-14.4 32.2-32.2 0-17.8-14.6-32.2-32.2-32.2zM672 192h-320v512h320v-512z" />
-<glyph unicode="&#xe6da;" d="M224 814.4v-732.8c0-9.8 7.8-17.6 17.6-17.6h540.8c9.8 0 17.6 7.8 17.6 17.6v732.8c0 9.8-7.8 17.6-17.6 17.6h-540.8c-9.8 0-17.6-7.8-17.6-17.6zM512 84.8c-15 0-27.2 12-27.2 27s12.2 27.2 27.2 27.2c14.8 0 27-12.2 27-27.2 0.2-15-12-27-27-27zM288 722.8c0 7 5.4 13.2 12 13.2h422.4c6.8 0 13.6-6.2 13.6-13.2v-550.4c0-7-6.8-12.6-13.6-12.6h-422.4c-6.8 0-12 5.6-12 12.6v550.4z" />
-<glyph unicode="&#xe6db;" d="M512 338c-35.4 0-64-28.6-64-64 0-35.2 28.6-64 64-64 35.2 0 64 28.6 64 64 0 35.4-28.6 64-64 64zM680.8 832h-337.6c-30.4 0-55.2-24.4-55.2-55.4v-657.4c0-31 24.8-55.4 55.2-55.4h337.6c30.4 0 55.2 24.4 55.2 55.4v657.4c0 31-24.8 55.4-55.2 55.4zM512.2 127.8c-79.6 0-144.2 64.4-144.2 144 0 79.4 64.6 144 144.2 144 79.4 0 143.8-64.6 143.8-144 0-79.6-64.4-144-143.8-144zM671.8 506.4c-1.6-15.2-14-26.4-29.4-26.4h-262c-16.4 0-28.4 12.4-28.4 29.2v229c0 15 10 27.4 24 29.8h271.6c13-2.4 23-13.2 24.4-26.6l-0.2-235z" />
-<glyph unicode="&#xe6dc;" d="M640 0h-256v192h256v-192zM608 320h-192l-32 576h256l-32-576z" />
-<glyph unicode="&#xe6dd;" d="M897 447l-384 384v-224h-384v-320h384v-224z" />
-<glyph unicode="&#xe6de;" d="M513 831l-384-384h224v-384h320v384h224z" />
-<glyph unicode="&#xe6df;" d="M129 447l384-384v224h384v320h-384v224z" />
-<glyph unicode="&#xe6e0;" d="M513 63l384 384h-224v384h-320v-384h-224z" />
-<glyph unicode="&#xe6e1;" d="M851 689.2c9.4 11.8 15 27 15 43.2 0 38.4-31.2 69.6-69.6 69.6-16.4 0-31.4-5.6-43.2-15-68 48.4-151.4 77-241.2 77-229.8 0-416-186.2-416-416 0-229.8 186.2-416 416-416 229.8 0 416 186.2 416 416 0 89.8-28.6 173.2-77 241.2zM783.6 176.4c-35.2-35.2-76.4-63-122.2-82.4-47.4-20-97.6-30.2-149.6-30.2-51.8 0-102.2 10.2-149.6 30.2-45.8 19.4-86.8 47-122.2 82.4-35.2 35.2-63 76.4-82.4 122.2-20 47.4-30.2 97.6-30.2 149.6 0 51.8 10.2 102.2 30.2 149.6 19.4 45.8 47 86.8 82.4 122.2s76.4 63 122.2 82.4c47.4 20 97.6 30.2 149.6 30.2 51.8 0 102.2-10.2 149.6-30.2 25.4-10.8 49.4-24.2 71.8-40-4.2-9-6.6-19-6.6-29.8 0-38.4 31.2-69.6 69.6-69.6 10.6 0 20.6 2.4 29.8 6.6 15.8-22.4 29.2-46.4 40-71.8 20-47.4 30.2-97.6 30.2-149.6 0-51.8-10.2-102.2-30.2-149.6-19.4-45.8-47-87-82.4-122.2zM704.2 448c0-106.149-86.051-192.2-192.2-192.2s-192.2 86.051-192.2 192.2c0 106.149 86.051 192.2 192.2 192.2 106.149 0 192.2-86.051 192.2-192.2z" />
-<glyph unicode="&#xe6e2;" d="M877.6 318.8c-7.2 6.2-294.4 214.4-294.4 214.4-0.4 0.4-0.8 0.8-1 1-11 11.2-10.4 20.8-11.2 37.6 0 0-1.8 138-4.4 184s-26.6 76.2-54.6 76.2c0 0 0 0 0 0s0 0 0 0c-28 0-51.8-30-54.4-76s-4.4-184-4.4-184c-0.8-16.8-0.2-26.4-11.2-37.6-0.4-0.4-0.8-0.8-1-1 0 0-287-208.2-294.4-214.4s-18.4-15.6-18.4-36.4c0-24.4 7.2-27.4 21.2-23.2 0 0 280.4 79 290.8 81.6s15.8-1.2 16.6-15 1.6-92.8 1.8-102-1.2-9.4-5.8-14.8l-64-81.6c-3.4-4-5.4-9-5.4-14.6 0 0 0-12.2 0-24.8s5.6-14.6 16.4-9.8 65.2 34.8 65.2 34.8c1.4 0.6 9.2 3.8 12.8 3.8 8.4 0 16 0.2 17.6-12.4 2.6-22.8 9.8-40.6 17-40.6 0 0 0 0 0 0s0 0 0 0c7.2 0 14.4 17.8 17 40.6 1.4 12.6 9.2 12.4 17.6 12.4 3.6 0 11.4-3.2 12.8-3.8 0 0 54.4-30 65.2-34.8s16.4-2.8 16.4 9.8 0 24.8 0 24.8c0 5.6-2 10.8-5.4 14.6l-64 81.6c-4.6 5.4-5.8 5.8-5.8 14.8s1 88.2 1.8 102 6.2 17.6 16.6 15 290.8-81.6 290.8-81.6c14.2-4.2 21.2-1.2 21.2 23.2-0.6 20.6-11.6 30-19 36.2z" />
-<glyph unicode="&#xe6e3;" d="M891.8 105.8l-235.8 398.4v299.8c0 15.4-13 28-29 28s-29-12.4-29-28v-307.2c0-3.6 1.2-7.2 2.6-10.6-15.2 22.2-41.2 36.8-70.8 36.8-47 0-85-36.6-85-82 0-33.6 21-63 50.8-75h-144l70 117c2.4 4.2 4.2 9 4.2 13.8v60.8c8-6.4 20-10.2 32.2-10.2 30.6 0 55 23.8 55 53.2 0 29.4-24.4 53.2-55 53.2-12.2 0-24.2-3.8-32.2-10.2v160.4c0 15.4-13 28-29 28s-29-12.4-29-28v-299.8l-235.6-398.4c-5-8.6-5.2-19.2 0-27.8 5.2-8.6 14.4-14 24.8-14h710c10.2 0 19.6 5.2 24.8 14 5.2 8.4 5 19.2 0 27.8zM564.4 366c29.8 12 50.8 41.6 50.8 75 0 11.4-2.4 22.4-6.8 32.2l62-107.2h-106zM530.2 702.8c24 0 43.4 18.8 43.4 41.8 0 23.2-19.4 41.8-43.4 41.8-24 0-43.4-18.8-43.4-41.8-0.2-23 19.4-41.8 43.4-41.8z" />
-<glyph unicode="&#xe6e4;" d="M904 768h-784c-31 0-55.8-25-56-56v0-0.6-526.8-0.6 0c0.4-31 25-56 56-56h784c31.2 0 56 25.4 56 56.6v0 526.8 0c0 31.2-24.8 56.6-56 56.6zM154.2 704h715.4c13.8 0 24.2-10.2 26.2-24v-40h-767.8v40.6c2 13.6 12.6 23.4 26.2 23.4zM869.8 192h-715.6c-13.8 0-24.2 9.8-26.2 23.4v232.6h768v-232c-2-13.8-12.6-24-26.2-24zM192 352h384v-32h-384v32zM192 288h192v-32h-192v32zM704 352h128v-96h-128v96z" />
-<glyph unicode="&#xe6e5;" d="M896 640h-128v9c0 137-110 247-247 247h-16c-137 0-249-110-249-247v-9h-128l-64-640h896l-64 640zM320 649c0 101.4 83.6 183 185 183h16c101.4 0 183-81.6 183-183v-9h-384v9zM135.6 64l49.8 512h70.6v-72.6c-19.2-11-32-31.8-32-55.4 0-35.4 28.6-64 64-64s64 28.6 64 64c0 23.6-12.8 44.4-32 55.4v72.6h384v-72.6c-19.2-11-32-31.8-32-55.4 0-35.4 28.6-64 64-64s64 28.6 64 64c0 23.6-12.8 44.4-32 55.4v72.6h70.8l49.8-512h-753z" />
-<glyph unicode="&#xe6e6;" d="M945.8 686.8l-209.4 140.6c-9.2 6.2-20.8 6.2-30.2 0l-194.2-130.4-194.2 130.4c-9.2 6.2-21 6.2-30.2 0l-209.4-140.6c-8.8-5.8-14.2-16.6-14.2-28v-562c0-11.8 5.6-22.6 14.8-28.6 9.2-5.8 20.6-5.6 29.6 0.4l194.2 130.4 194.2-130.4c9.4-6.2 20.8-6.2 30.2 0l194.4 130.4 194.2-130.4c4.6-3 9.8-4.8 15-4.8 5 0 10 1.4 14.4 4.2 9.2 5.8 14.8 16.8 14.8 28.6v562c0.2 11.6-5.2 22.4-14 28.2zM270 253.6l-142-98.8v483.4l142 98.8v-483.4zM334 254.4v244.8c2-1.4 4-2.6 5.8-4l18.6 26c-7.6 5.4-16 10.6-24.4 15v201.8l146-98v-217.4c-11 3.8-21.8 8.8-32.8 15.8l-17-27.2c13.6-8.6 27.2-15 41.4-19.6l8.4 25.6v-260.6l-146 97.8zM544 156.6v226.8c0.4 0 0.8 0 1 0 5.8 0.4 11.6 1 17 1.8l-5 31.6c-4.2-0.6-8.6-1.2-13.2-1.4v224.6l146 98v-238.4l-10.6 9.6c-6-6.6-11.6-13.2-17.2-19.4-3.6-4.2-7.2-8.2-10.6-12.2l24-21.2c3.6 4 7.2 8.2 10.8 12.4 1.2 1.4 2.4 2.8 3.8 4.2v-218.4l-146-98zM896 156.6l-142 96.8v274.4c7.2 3.2 14.8 5.6 22.2 7.2l-6.4 31.4c-5.4-1-10.6-2.6-16-4.2v175l142-97v-483.6zM197.8 448c3.8 11.8 7 22 14.2 32.6l-26.4 18c-9.8-14.4-14.2-27.8-18.4-41l-0.4-1.6 30.4-9.8 0.6 1.8zM257.6 517.8c4.4 2.4-2.8 2.2 2 3.6l-9.8 30.4c-6.6-2.2-13-4.8-19.2-8.2-7.6-4.2-15.4-9.8-22.6-16.6l21.8-23.4c5.2 5 22.4 11.4 27.8 14.2zM592.6 427.8l14-28.8c13.2 6.4 25.6 14.8 38.2 26l-21.2 24c-10.4-9.2-20.4-16.2-31-21.2zM395.6 484.4c-2 2.4-4 4.8-6 7.2l-24.4-20.8c2-2.4 4-4.6 5.8-7 7.2-8.6 14.6-17.4 23.2-25.6l22 23.2c-7.2 7-13.6 14.8-20.6 23zM815.4 500.6l20.6 20.8 20.6-20.8 22.8 22.8-20.8 20.6 20.8 20.6-22.8 22.8-20.6-20.8-20.6 20.8-22.8-22.8 20.8-20.6-20.8-20.6z" />
-<glyph unicode="&#xe6e7;" d="M320 640h384c-3.4 40-19.4 70.4-55.8 80.2-0.8 0.2-1.8 0.6-2.6 0.8-24 6.8-41.6 15-41.6 41.4v41.2c0 51-41 92.6-92 92.6s-92-41.4-92-92.6v-41.2c0-26.2-17.6-34.4-41.6-41.2-0.8-0.2-1.8-0.8-2.8-1-36.4-9.8-51.8-40.2-55.6-80.2zM512 831.2c15.2 0 27.6-12.4 27.6-27.6 0-15.4-12.4-27.6-27.6-27.6-15.2 0-27.6 12.4-27.6 27.6 0 15.2 12.4 27.6 27.6 27.6zM809.2 834h-147.2v-29c0-21.2 17.4-37 38-37h74.4c13.4 0 24.2-11.4 24.8-25l0.2-654.4c-0.6-12.8-10.6-23.2-23-24.2l-528.8-0.2c-12.4 1-22.2 11.4-23 24.2l-0.2 654.6c0.6 13.6 11.8 25 25 25h74.6c20.6 0 38 15.8 38 37v29h-147.2c-30.2 0-54.8-26.2-54.8-57.2v-720.8c0-31 24.6-56 54.8-56h594.4c30.2 0 54.8 25 54.8 56v720.8c0 31-24.6 57.2-54.8 57.2zM288 576h224v-32h-224v32zM288 384h320v-32h-320v32zM288 192h258v-32h-258v32zM288 288h352v-32h-352v32zM288 480h416v-32h-416v32z" />
-<glyph unicode="&#xe6e8;" d="M250.4 255.4h-186.4v109.2h202.4l26.2 166.6h-198.6v109.2h214.4l43.6 255.6h127.8l-43.6-255.4h211.2l43.6 255.4h126.2l-43.6-255.4h186.4v-109.2h-203.8l-24.6-166.6h198.4v-109.2h-213l-45-255.6h-126.2l43.6 255.4h-212.8l-43.6-255.4h-126.2l43.6 255.4zM418.8 531.4l-24.8-166.8h211.2l24.6 166.6h-211z" />
-<glyph unicode="&#xe6e9;" d="M907.6 145.8c-47.8-50.6-104.6-87.6-170.4-110.8-65.8-23.4-135.2-35-208.2-35-69.8 0-133.4 11-190.6 33.2-57.2 22-106.2 52.8-146.6 92.2-40.6 39.4-72 86.6-94.4 141.6-22.4 55-33.4 115-33.4 180 0 64.2 12.2 123.6 36.6 178.2 24.4 54.6 57.6 102 99.8 142.2 42.2 40.2 91.4 71.6 148 94.6 56.2 22.6 116.6 34 180.6 34 55.2 0 108.8-8 160.6-24 52-16 98-40.2 138.2-72.2 40.2-32.2 72.2-72.2 96.2-120.4 24-48.2 36-104.8 36-169.8 0-48.2-6.6-90.8-20-127.6-13.4-37-31.2-67.8-53.6-92.8-22.4-25-47.8-43.6-76.6-56-28.8-12.4-59-18.6-90.6-18.6-32.4 0-58.4 7.6-78 22.8-19.4 15.2-29.2 34.6-29.2 57.8h-6c-12.2-19.2-30.8-37.6-56-54.8-25.2-17.2-56-26-92.6-26-55.2 0-97.8 18-127.8 54.2-30 36.2-45 83-45 141 0 33.8 5.6 67 17 100 11.4 33 27.6 62.2 48.6 88 21 25.6 46.2 46.4 75.4 62 29.2 15.6 61.6 23.4 97.4 23.4 30.8 0 56.8-6.4 78-19.2 21-12.8 34.8-28.6 41.4-47h1.2l9.8 48.2h108.4l-47.8-227.8c-1.6-11.2-3.8-23.6-6.6-37.4-2.8-13.6-4.2-26.4-4.2-38.6 0-13.6 2.6-25 8-34.4 5.2-9.2 15.6-13.8 31-13.8 31.6 0 57.8 16.8 78.6 50.6 20.6 33.8 31 79 31 136 0 48.2-8.2 91-24.4 128.2-16.2 37.4-38.8 68.6-67.6 94-28.8 25.2-63.2 44.4-102.8 57.2-39.8 12.8-83.2 19.2-130.2 19.2-51.2 0-98-9-140.6-27s-79-43-109-74.6c-30-31.8-53.4-69-70-112-16.8-42.8-25.2-89.2-25.2-139 0-53 8.8-100.8 26.2-143.4 17.4-42.6 42-78.8 73.6-109 31.6-30.2 69.4-53.2 113.2-69.2 43.8-16 92.2-24 144.8-24 65.8 0 122.4 10.4 169.8 31.4 47.4 20.8 91 49.8 130.8 86.8l67.2-72.4zM526.6 584c-19.4 0-36.6-5.6-51.2-16.8-14.6-11.2-27-25.4-37.2-42.8-10.2-17.2-17.8-36.4-23.2-57.2-5.2-20.8-8-41-8-60.2 0-9.6 1-19.8 3-30.8 2-10.8 6-20.8 12.2-30.2 6-9.2 14-16.8 23.8-22.8 9.8-6 22.8-9 39-9 22 0 40.6 5.4 56 16.2 15.4 10.8 28 24.4 37.8 41 9.8 16.4 16.8 34.4 21.4 53.6 4.4 19.2 6.6 37 6.6 53 0 12.8-1.2 25.4-3.6 38-2.4 12.4-6.6 23.6-12.8 33.8-6 10-14.4 18.2-25 24.6-10.4 6.4-23.4 9.6-38.8 9.6z" />
-<glyph unicode="&#xe6ea;" d="M736 512c53 0 96 43 96 96s-43 96-96 96c-53 0-96-43-96-96 0-53 43-96 96-96zM904 832h-784c-31.2 0-56-25.4-56-56.6v-654.8c0-31.2 24.8-56.6 56-56.6h784c31.2 0 56 25.4 56 56.6v654.8c0 31.2-24.8 56.6-56 56.6zM697.8 436.6c-6 7-15.2 12.4-25.6 12.4-10.2 0-17.4-4.8-25.6-11.4l-37.4-31.6c-7.8-5.6-14-9.4-23-9.4-8.6 0-16.4 3.2-22 8.2-2 1.8-5.6 5.2-8.6 8.2l-107.6 116.4c-8 9.2-20 15-33.4 15s-25.8-6.6-33.6-15.6l-253-305.2v521c2 13.6 12.6 23.4 26.2 23.4h715.4c13.8 0 25-10.2 25.8-24l0.6-520.8-198.2 213.4z" />
-<glyph unicode="&#xe6eb;" d="M658.4 896h-292.6c-60.8 0-109.8-46.8-109.8-104.8v-55.2h304v-74h-304v-86h304v-74h-304v-86h304v-74h-304v-83.6c0-58 49-104.4 109.8-104.4h60.2v-154h172v154h60.4c60.6 0 109.6 46.4 109.6 104.4v83.6h-118v74h118v86h-118v74h118v86h-118v74h118v55.2c0 58-49 104.8-109.6 104.8z" />
-<glyph unicode="&#xe6ec;" d="M512.8 896c-70.2-0.2-131.6-46.4-153.6-118.6-11.2-37-7-89.6-2.4-109 4.6-19.4 14.6-39.8 26.4-56.6 5.6-8.4 13.4-14.8 22.4-18.4 1.2-0.6 2.6-1 4-1.6 6.6-2.2 13-4.4 20.2-6.2 23.6-6 54.2-9.4 82.2-9.6v0c0 0 1.2 0 1.4 0 0.6 0 0.6 0 2.6 0v0.2c28 0.2 54.6 3.4 78.2 9.6 7.2 1.8 13.8 4 20.4 6.2 1.4 0.4 2.6 1 3.8 1.6 9 3.6 16.8 10 22.4 18.4 11.8 16.8 21.6 37.2 26.4 56.6 4.6 19.4 8.8 72-2.4 109-22 72-81.6 118.2-152 118.4zM590.6 557.8c-0.8 0-1.4 0-2.2-0.2-1.2-0.2-2.6-0.6-3.8-0.8-4-0.8-8.2-1.6-12.2-2.4-18.4-3-37.8-4.6-58-4.8-20.2 0.2-44.6 1.8-62 4.8-4.2 0.8-8.4 1.6-12.4 2.4-1.2 0.2-2.6 0.6-3.8 0.8-0.8 0.2-1.6 0.2-2.2 0.2-12.2 0-22-10.6-22.4-23.8 0.2-1.6 0.4-3.2 0.4-4.8 9.6-134.4 33.6-481.4 36.4-504 0 0 5.6-25.4 64.2-25.2 0 0 0 0 0 0 58.4-0.2 64.2 25.2 64.2 25.2 2.8 22.6 26.8 369.6 36.4 504 0 1.6 0.2 3.2 0.4 4.8-1 13.2-10.8 23.8-23 23.8zM532 396.6c0-12-9-21.8-20-21.8s-20 9.8-20 21.8v65.4c0 12 9 21.8 20 21.8s20-9.8 20-21.8v-65.4z" />
-<glyph unicode="&#xe6ed;" d="M542 882.8c-0.6 0.8-1.4 1.4-1.8 2 0 0-0.2 0.2-0.2 0.2-7.2 6.8-17 11-27.8 11-11 0-20.8-4.2-27.8-11 0 0-0.2-0.2-0.2-0.2-0.6-0.6-1.2-1.2-1.8-2-12.2-12.6-27.6-28.8-44.8-48.2-34.8-39.4-77.2-92-117-153.6-66.8-103.6-125.8-232.2-128.2-366.2 0-2.6-0.2-5.4-0.2-8 0-39.4 7.8-77 21.8-111.6 8.2-20 18.4-38.8 30.4-56.4 57-83.6 155.6-138.8 267.6-138.8 176.8 0 320 137.4 320 306.8 0 255.8-210.4 494.8-290 576zM512 112c-31.6 0-61.4 7.4-87.8 20.2 131.8 28.8 236.8 129.4 271.6 259 10.4-24.2 16.4-51 16.4-79.2-0.2-110.4-89.8-200-200.2-200z" />
-<glyph unicode="&#xe6ee;" d="M512 32c229.8 0 416 186.2 416 416s-186.2 416-416 416c-229.8 0-416-186.2-416-416 0-229.8 186.2-416 416-416z" />
-<glyph unicode="&#xe6ef;" d="M874.8 832h-725.6c-11.8 0-21.2-9.4-21.2-21.2v-725.6c0-11.8 9.4-21.2 21.2-21.2h725.6c11.6 0 21.2 9.4 21.2 21.2v725.6c0 11.8-9.6 21.2-21.2 21.2z" />
-<glyph unicode="&#xe6f0;" d="M448 88.4v719.4c0 13.4-10.8 24.2-24.4 24.2h-143.2c-13.6 0-24.4-10.8-24.4-24.2v-719.4c0-13.4 10.8-24.4 24.4-24.4h143.2c13.6 0 24.4 10.8 24.4 24.4zM743.6 832h-143.2c-13.4 0-24.4-10.8-24.4-24.2v-719.4c0-13.4 10.8-24.4 24.4-24.4h143.2c13.4 0 24.4 10.8 24.4 24.4v719.4c0 13.4-10.8 24.2-24.4 24.2z" />
-<glyph unicode="&#xe6f1;" d="M810.4 494.2l-556.8 331.4c-6.8 4-13.8 6.4-21.8 6.4-21.8 0-39.6-18-39.6-40h-0.2v-688h0.2c0-22 17.8-40 39.6-40 8.2 0 15 2.8 22.4 6.8l556.2 331c13.2 11 21.6 27.6 21.6 46.2s-8.4 35-21.6 46.2z" />
-<glyph unicode="&#xe6f2;" d="M622 144.6v606.6l-189.6-175.2h-208.4v-256h208.4zM734.4 248.8c41 55.6 65.6 124.6 65.6 199.2 0 74.8-24.6 143.6-65.6 199.2l-40.8-30.6c34.8-47.2 55.6-105.4 55.6-168.6 0-63.2-20.8-121.4-55.6-168.6l40.8-30.6z" />
-<glyph unicode="&#xe6f3;" d="M540 144.6v606.6l-189.4-175.2h-208.6v-256h208.6zM652.6 248.8c41 55.6 65.6 124.6 65.6 199.2 0 74.8-24.6 143.6-65.6 199.2l-40.8-30.6c34.8-47.2 55.6-105.4 55.6-168.6 0-63.2-20.8-121.4-55.6-168.6l40.8-30.6zM785.6 156.8c60 81.4 96 182 96 291.2s-36 209.8-96 291.2l-40.8-30.6c53.8-72.8 86-162.8 86-260.6s-32.2-187.6-86-260.6l40.8-30.6z" />
-<glyph unicode="&#xe6f4;" d="M462 144.4v607l-189.8-175.4h-208.2v-256h208.2zM574.2 248.6c41 55.8 65.6 124.6 65.6 199.4s-24.6 143.6-65.6 199.4l-40.8-30.6c34.8-47.2 55.6-105.4 55.6-168.8 0-63.2-20.8-121.6-55.6-168.6l40.8-30.8zM707.4 156.6c60 81.4 96 182.2 96 291.4s-36 209.8-96 291.4l-40.8-30.6c53.8-72.8 86-163 86-260.8s-32.2-187.8-86-260.6l40.8-30.8zM793.4 801.2c72.8-98.6 115.8-221 115.8-353.2s-43-254.4-115.8-353.2l41-30.8c78.8 107.2 125.6 240 125.6 384s-46.8 276.8-125.6 384l-41-30.8z" />
-<glyph unicode="&#xe6f5;" d="M224.2 483.8l-0.2-27.2c0.2-131.2 92-241.2 216.2-272.4 2.6-0.2 5.2-1 7.6-1.8 11.8-4 20.2-13.8 24.2-25.6v-117.4c0-21.8 17.8-39.4 40-39.4h0.2c22.2 0 39.8 17.6 39.8 39.4v117.6c4 11.8 12.2 21.4 24 25.4 2.4 0.8 5 1.6 7.8 1.8 124.2 31.2 216.2 141.2 216.2 272.4v27.2c0 20.8-17.8 37.8-39 37.8s-39-16.8-39-37.8v-27.2c0-57-23-108.2-61.2-145.6-38.4-37.2-90.6-60.4-149-60.4-58.4 0-110.2 23-148.4 60.4-38.2 37.4-61.4 88.8-61.4 145.6v27.2c0 20.8-17.6 37.8-39 37.8-21.2 0-38.8-17-38.8-37.8zM358 744.6v-287.6c0-83.6 69.4-151.4 155-151.4s155 67.8 155 151.4v287.6c0 83.6-69.4 151.4-155 151.4s-155-67.8-155-151.4z" />
-<glyph unicode="&#xe6f6;" d="M230.4 204c-56.4 0-102.4-45.8-102.4-102s46-102 102.4-102h74.4c30.6 0 57.8 13.6 76.6 34.8 0.2 0.2 0.6 0.2 0.8 0.4 1.2 1.2 2 3 3 4.2 2.6 3.2 5 6.4 7 10 19 28.4 28 65.8 28 94.4 0 33.6 0 394.6 0 394.6 0 1.2 0 2.2 0 3.4 0 1 0 2.2 0 3.2 1.6 28.4 22.4 51.4 50.2 57.8 3.4 0.8 10.8 2.4 10.8 2.4l299.8 56.8c1.4 0.2 2.6 0.4 4 0.6 1.6 0.2 3 0.2 4.8 0.2 24.2 0 42.2-19 42.2-42.4 0 0 0-211.6 0-262.8 0-51 5.8-63.8-81-63.8h-40.2c-56.6 0-102.4-45.8-102.4-102s45.8-102 102.4-102h74.4c36.4 0 68.2 18.8 86.4 47.2 0 0.2 0.2 0 0.4 0 18 24.4 23.8 61.2 23.8 110.6 0 49.6 0 605.6 0 605.6 0 23.4-19.8 42.4-44 42.4-1.4 0-2.8-0.2-4-0.2l-6.2-1-435-82.4c-27.6-7.4-52.6-33.8-54.6-62.8 0-0.2 0-0.2 0-0.4 0-0.2 0-0.2 0-0.4 0 0 0-472.4 0-500.2 0-27.8 4-44.4-95.4-44.4h-26.2z" />
-<glyph unicode="&#xe6f7;" d="M828 445c0-13.8-10.6-24.8-23.2-24.8-1 0-1.8 0.6-2.8 0.8-19.8 29.4-51.4 48.8-87.6 48.8-60 0-108.4-52.6-108.4-117.8v-234.4c0-65 48.2-117.6 108.2-117.6h5.4c7.2 0 13.8 1.6 20 4.4v-0.2c6.2 2.8 12.4 5.8 18.4 9 20.6 11.4 39.6 26.4 56.4 44.6 29.2 31.6 47.8 71 57.6 113.4 0.4 1.8 1 3.8 1.4 5.6 20.6 92 26.2 205.2 20.8 306.4-6.4 119.4-44 217-111.4 290.6 0 0.2-0.2 0.2-0.4 0.4-15.4 16.8-31.8 31.8-49.2 45.2-18 14-37 26.2-56.8 36.2-50.6 26.2-106.4 40-164 40v0 0c-58 0-113.4-13.8-164-40-19.8-10.2-38.8-22.4-56.8-36.2-17.4-13.4-34-28.4-49.4-45.2-0.2-0.2-0.2-0.2-0.4-0.4-68-73.2-105.4-170.8-111.8-290.2-5.4-101.4 0.2-214.4 20.8-306.4 0.4-1.8 0.8-3.8 1.4-5.6 9.8-42.4 28.4-81.8 57.6-113.4 16.8-18.2 35.8-33.2 56.4-44.6 6-3.4 12-6.4 18.4-9v0.2c6.2-2.8 13-4.4 20-4.4h5.4c60 0 108.2 52.8 108.2 117.6v234c0 65-48.4 117.8-108.4 117.8-36 0-67.8-19.4-87.4-48.8-1 0-2-0.8-3-0.8-12.6 0-23.2 11-23.2 24.8 0 0 0 0 0 0 0 0.6 0.6 1 0.6 1.4 0.4 10.8 1 21.8 1.6 32.6 1.6 31.8 6.2 61.8 13 89.8 12.4 51.6 33.6 96.4 63.2 134 5 6.6 10.4 12.8 16 19 6.4 6.8 12.8 13.4 19.6 19.4 3.2 3 6.4 5.6 9.6 8.4 22 18.6 46 34 71.4 45.6 38 17.2 79 26.6 121.4 26.6v0c42.4 0 83.4-9.2 121.4-26.6 25.4-11.6 49.4-27 71.4-45.6 3.2-2.8 6.4-5.6 9.4-8.4 6.8-6 13.2-12.6 19.6-19.4 5.6-6.2 11-12.4 16-19 29.6-37.6 50.6-82.4 63-134 6.8-28 11.6-57.8 13.2-89.8 0.6-10.8-0.2-21.8 1.8-32.6-0.4-0.2-0.4-0.6-0.4-1.4 0 0.2 0 0.2 0 0z" />
-<glyph unicode="&#xe6f8;" d="M512 642.2c-107.4 0-194.4-87-194.4-194.4 0-107.4 87-194.2 194.4-194.2 107.4 0 194.4 87 194.4 194.2 0 107.4-87 194.4-194.4 194.4zM512 361c-48 0-87 39-87 87s39 87 87 87c48 0 87-39 87-87 0-48-39-87-87-87zM512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448 448 200.6 448 448c0 247.4-200.6 448-448 448zM512 202.4c-135.6 0-245.6 110-245.6 245.6s110 245.6 245.6 245.6c135.6 0 245.6-110 245.6-245.6 0-135.6-110-245.6-245.6-245.6z" />
-<glyph unicode="&#xe6f9;" d="M734 589.4c0 10.2-8 18.6-18.4 18.6h-103.6v64.4c0 70.4-58.6 127.6-129.8 127.6h-356.2v-96h352.2c9 0 19.8-11.2 19.8-20.2v-75.8h-415.2c-10.4 0-18.8-8.4-18.8-18.6v-340.8-111.4-22.6c0-10.2 8.4-18.6 18.8-18.6h632.8c10.4 0 18.4 8.4 18.4 18.6v129l226-69.4v176.4 176.4l-226-69.4v131.8zM516.4 278h-236.2c-39.6 0-71.8 32-71.8 71.6s32.2 71.6 71.8 71.6c39.6 0 71.8-32.4 71.8-72 0-20-8.4-37.2-21.6-51.2h135.8c-13.2 14-21.6 31.2-21.6 51.2 0 39.6 32.2 71.8 71.8 71.8 39.6 0 71.8-31.8 71.8-71.4s-32.2-71.6-71.8-71.6z" />
-<glyph unicode="&#xe6fa;" d="M716.6 64h19.4v236.2 23.4c0 13-11.4 24.4-24.8 24.4h-398.4c-13.4 0-24.8-11.2-24.8-24.4v-23.4-236.2h19.4c1.8 0 3.6 0 5.4 0h398.6c1.8 0 3.6 0 5.2 0zM847.6 698h-61.6v104.6c0 16.6-14.6 29.4-31.8 29.4h-484.4c-17.2 0-31.8-12.8-31.8-29.4v-104.6h-61.6c-55.8 0-112.4-54.8-112.4-109.2v-241.6c0-54.4 56.6-123.4 112.4-123.4 0 0 26.6 0 36.6 0 9.8 0 11 0 11 28v86c0 37.6 30.4 64 65.8 64h448c35.4 0 62.2-42.6 62.2-80v-70c0-28 0.2-28 10-28 10 0 37.4 0 37.4 0 55.8 0 112.4 53 112.4 107.4v257.6c0.2 54.4-56.4 109.2-112.2 109.2zM800 576c-17.6 0-32 14.4-32 32s14.4 32 32 32 32-14.4 32-32-14.4-32-32-32z" />
-<glyph unicode="&#xe6fb;" d="M960 747.4c0 11.2-8.2 20.6-19.2 20.6h-856.4c-11 0-20.4-9.2-20.4-20.6v-523.4h896v523.4zM896 288h-768v416h768v-416zM0 182.6c140.4-39.8 231.6-54.6 512-54.6s371.6 14.6 512 54.6v9.4h-1024v-9.4z" />
-<glyph unicode="&#xe6fc;" d="M937.4 832h-850.8c-12 0-22.6-10-22.6-22.2v-531.4c0-12.4 10.4-22.2 22.6-22.2h850.8c12 0 22.6 10 22.6 22.2v531.4c0 12.2-10.4 22.2-22.6 22.2zM896 320h-768v448h768v-448zM605 64c56 1 83 7.8 58 25-25 17.4-57 30.6-58 45-0.6 7.4-3.4 90-3.4 90h-179.2c0 0-3-82.6-3.4-90-1-14.2-33-27.6-58-45-25-17.4 2-24 58-25h186z" />
-<glyph unicode="&#xe6fd;" d="M294.8 56.2c0.8-0.4 1.4-1 2.2-1.4 21.8-12 45-21.4 68.8-29.6 3.6-1.2 7.2-2.4 10.8-3.6 42.8-13.6 88-21.8 135.4-21.8 247.4 0 448 200.6 448 448 0 168.6-93.2 315.4-231 391.8-0.8 0.4-1.4 0.8-2 1.2-21.8 12-45 21.4-68.8 29.6-3.6 1.2-7.2 2.4-10.8 3.6-42.8 13.8-88.2 22-135.4 22-247.4 0-448-200.6-448-448 0-168.6 93.2-315.2 230.8-391.8zM236.4 646.8l108.8-108.8 72.6 81-104.8 104.8c56 40.4 124.2 65.2 198.8 65.2 18.6 0 36.6-1.8 54.4-4.8 19.6-3.2 38.6-8.2 57-14.6 3.6-1.2 7.4-2.4 11.2-3.8 12.4-4.8 24.4-10 36-16.2 108.4-57 182.4-170.6 182.4-301.6 0-74.4-24.8-142.6-65.4-198.8l-108.8 108.8-72.6-80.8 104.8-104.8c-56-40.6-124.4-65.4-198.8-65.4-18.6 0-36.8 1.8-54.4 4.8-19.6 3.2-38.6 8.2-57 14.6-3.8 1.2-7.6 2.4-11.2 3.8-13 5-25.8 10.6-38 17.2-107.2 57.4-180.2 170.4-180.2 300.6 0 74.4 24.8 142.6 65.2 198.8zM419.4 180.4l278.4 309.6h-170.6l77.2 225.6-278.2-309.6h170.6z" />
-<glyph unicode="&#xe6fe;" d="M192 384h294l-102.2-384 448.2 512h-294l102 384z" />
-<glyph unicode="&#xe6ff;" d="M512 704c-163.8 0-291.4-97.6-448-256 134.8-135.4 248-256 448-256 199.8 0 346.8 152.8 448 253.2-103.6 117.6-250.4 258.8-448 258.8zM512 265.4c-98.8 0-179.2 82-179.2 182.6 0 100.8 80.4 182.6 179.2 182.6s179.2-82 179.2-182.6c0-100.8-80.4-182.6-179.2-182.6zM512 512c0 15.8 5.8 30.2 15.2 41.4-5 0.8-10 1.2-15.2 1.2-57.6 0-104.6-47.8-104.6-106.6 0-58.8 47-106.6 104.6-106.6s104.6 47.8 104.6 106.6c0 4.6-0.4 9.2-0.8 13.8-11-8.6-24.6-13.8-39.6-13.8-35.6 0-64.2 28.6-64.2 64z" />
-<glyph unicode="&#xe700;" d="M860.8 666h-135l-80.8 81.6c0 0-0.4 0.4-0.6 0.4l-0.4 0.4c-12 12-28.2 19.6-46.6 19.6h-168c-19.6 0-37-8.4-49.2-21.8v-0.2l-79-80h-138c-37.2 0-67.2-29.2-67.2-66.4v-404.2c0-37.2 30-67.4 67.2-67.4h697.6c37 0 67.2 30.2 67.2 67.4v404.2c0 37.2-30.2 66.4-67.2 66.4zM512 229c-101.8 0-184.8 83.2-184.8 185.2 0 102.2 83 185.2 184.8 185.2 102 0 184.8-83 184.8-185.2 0-102-82.8-185.2-184.8-185.2zM848.2 559c-15.4 0-28 12.6-28 28.2s12.6 28.2 28 28.2c15.4 0 28-12.6 28-28.2s-12.6-28.2-28-28.2zM512 554.2c-77.2 0-139.6-62.6-139.6-140 0-77.2 62.4-140 139.6-140 77 0 139.6 62.6 139.6 140 0 77.4-62.6 140-139.6 140z" />
-<glyph unicode="&#xe701;" d="M280 672.8c-31.8-31.8-23.4-34.6-21.2-36.8s179.6-171.2 179.6-171.2 7.8-6.8 7.8-16.8v0c0-10-7.8-16.8-7.8-16.8s-177.4-169-179.6-171.2c-2.2-2.2-10.6-5 21.2-36.8 31.8-31.8 36.8-24.4 38.4-22.8l134.8 128.6c0.2 0.2 0.4 0.4 0.6 0.6 0.2 0.2 0.6 0.4 0.8 0.6 4.6 3.8 19.6 21.2 19.6 6.4 0-14.6 0-303.6 0-312.8v-0.2-3.4c0-11 10.4-20.2 23.2-20.2 7 0 13.4 2.6 17.8 7v0c0 0 236.4 225.6 245.6 234.4s10 21.4 2 29.4l-167.8 160.6c0 0-8.8 8.6-8.8 16.6s8.8 16.6 8.8 16.6l167.8 160.6c8 8 7.2 20.8-2 29.4-9.2 8.8-245.6 234.4-245.6 234.4v0c-4.2 4.2-10.6 7-17.6 7-12.8 0-23.2-9.2-23.2-20.2v-3.4-0.4c0-9.2 0-298.2 0-312.8 0-14.8-15 2.6-19.6 6.4-0.2 0.2-0.6 0.4-0.8 0.6-0.2 0.2-0.4 0.4-0.6 0.6l-134.8 128.6c-2 1.8-6.8 9.2-38.6-22.6zM560 720.2c0 13.2 15-4.6 19.6-8.8l61-58.4c4.2-4 5.8-9.4 5.8-14.4s-2-11.2-5.6-14.6c-3.6-3.4-61.6-59-61.6-59-4.6-3.6-19.2-19.6-19.2-3.4 0 0 0 145.4 0 158.6zM560 334.4c0 16.4 14.4 0.4 19.2-3.4 0 0 58.2-55.6 61.8-59 3.6-3.4 5.6-9.8 5.6-14.6s-1.6-10.4-5.8-14.4l-61-58.4c-4.6-4.2-19.6-22-19.6-8.8-0.2 13.2-0.2 158.6-0.2 158.6z" />
-<glyph unicode="&#xe702;" d="M512.2 768v0c-159.8 0-311.4-59.8-427.8-168.2l-20.4-19 103-102 19.2 17.6c89 81.8 204.6 127 325.6 127s236.8-45.2 325.6-127l19.2-17.6 18.6 18.4 84.4 83.6-20.4 19c-116 108.4-267.8 168.2-427 168.2zM794.8 447.2c-77.6 70.2-177.8 108.8-282.2 108.8h-17.8l-0.2-0.4c-98.4-4-192-42.2-265.2-108.4l-21-19 103.8-102.8 19.2 16.8c50.6 44.4 114.8 69 180.6 69 66.2 0 130.4-24.6 181-69l19.2-16.8 18.2 18 85.6 84.8-21.2 19zM512.4 128l146 144.4-23.2 19c-30.8 22.8-64.8 40-123 40-58 0-89.8-18.8-123-40l-23-19 21.2-21 105.6-104.4 19.4-19z" />
-<glyph unicode="&#xe703;" d="M84.2 192h762.2c11 0 19.8 9 19.8 20v108h73.8c11.2 0 20.2 9 20.2 20v216c0 11-9 20-20.2 20h-74v108c0 11-8.6 20-19.8 20h-762c-11.2 0-20.2-9-20.2-20v-472c0-11 9-20 20.2-20zM514.8 640l-55.8-162h123l-200.8-222 55.8 162h-123l200.8 222z" />
-<glyph unicode="&#xe704;" d="M939.8 576h-73.8v108c0 11-8.6 20-19.8 20h-762c-11.2 0-20.2-9-20.2-20v-472c0-11 9-20 20.2-20h762.2c11 0 19.8 9 19.8 20v108h73.8c11.2 0 20.2 9 20.2 20v216c-0.2 11-9.2 20-20.4 20zM896 384h-94v-64-64h-674v384h674v-64-64h94v-128z" />
-<glyph unicode="&#xe705;" d="M84.2 192h762.2c11 0 19.8 9 19.8 20v108h73.8c11.2 0 20.2 9 20.2 20v216c0 11-9 20-20.2 20h-74v108c0 11-8.6 20-19.8 20h-762c-11.2 0-20.2-9-20.2-20v-472c0-11 9-20 20.2-20zM802 640v-64-64h94v-128h-94v-64-64h-354l-64 384h418z" />
-<glyph unicode="&#xe706;" d="M939.8 576h-73.8v108c0 11-8.6 20-19.8 20h-762c-11.2 0-20.2-9-20.2-20v-472c0-11 9-20 20.2-20h762.2c11 0 19.8 9 19.8 20v108h73.8c11.2 0 20.2 9 20.2 20v216c-0.2 11-9.2 20-20.4 20zM896 384h-94v-64-64h-98l-64 384h162v-64-64h94v-128z" />
-<glyph unicode="&#xe707;" d="M939.8 576h-73.8v108c0 11-8.6 20-19.8 20h-762c-11.2 0-20.2-9-20.2-20v-472c0-11 9-20 20.2-20h762.2c11 0 19.8 9 19.8 20v108h73.8c11.2 0 20.2 9 20.2 20v216c-0.2 11-9.2 20-20.4 20z" />
-<glyph unicode="&#xe708;" d="M380.8 662.8l-58.8-208.6c-12.6-45.6 41.4-63.4 54.6-20.6l52.6 192.4h14.8l-90.4-338h84.4v-254c0-46 64-46 64 0v254h20v-254c0-46 62-46 62 0v254h86.8l-92.4 338h16.8l52.6-192.4c13-43.8 66.6-25 54.6 20.4l-58.8 208.8c-8 23.6-36.4 65.2-84 67.2h-94.6c-49.2-2-77.4-43.2-84.2-67.2zM585.2 821.6c0 41.2-32.8 74.6-73.2 74.6-40.4 0-73.2-33.4-73.2-74.6 0-41.2 32.8-74.6 73.2-74.6 40.4 0 73.2 33.4 73.2 74.6z" />
-<glyph unicode="&#xe709;" d="M850.6 310.4c-82.8 31.4-77.8 18.8-77.8 77 0 37.6 18.6 23.8 30.4 95.4 4.6 28.2 8.4 9.4 18.2 54.6 5.2 23.6-3.6 25.4-2.4 36.6 1 11.2 2 21.4 4 44.4 2.4 28.8-23.2 104-114.8 104-91.6 0-117.2-75.2-114.8-104 1.8-23.2 3-33.2 4-44.4 1-11.2-7.6-13-2.4-36.6 9.8-45.2 13.6-26.2 18.2-54.6 11.8-71.6 30.2-58 30.2-95.4 0-26.8 6.2-38-29.8-55 10.8-3.8 23.4-8.4 38.6-14.2 108.8-41.4 106.2-81.6 109-100.6 2-13 3-116.6 3.4-153.6h195.4c0 0 0 161-3 179.8-2.2 14.8-22 34.4-106.4 66.6zM714 64c0 0 0 28.2-0.4 60.8-0.4 37.2-1.4 80-3.4 92.8-3 19-28.6 44.4-137.2 85.8-15 5.6-27.6 10.2-38.6 14.2-66.6 23.6-61.8 31.4-61.8 96 0 48.6 24 17 39.2 109.2 6 36.4 10.8 12.2 23.4 70.4 6.8 30.4-4.6 32.8-3.2 47.4 1.4 14.6 2.8 27.6 5.2 57.4 3.2 37-29.8 134.2-148.2 134.2-118.4 0-151.2-97-148.2-134.2 2.4-29.8 3.8-42.8 5.4-57.4 1.4-14.6-10-16.8-3.2-47.4 12.8-58.2 17.6-34 23.6-70.4 15.2-92.2 39-60.6 39-109.2 0-75.2 6.6-69.6-100.4-110.2-108.6-41.4-134.2-66.8-137.2-85.8-4-24.2-4-153.6-4-153.6h650z" />
-<glyph unicode="&#xe70a;" d="M858 304v102h102v84h-102v102h-84v-102h-102v-84h102v-102zM832 64c0 0 0 52.8-4.4 80.4-3.6 21.8-33.8 50.6-162.2 97.8-126.4 46.4-118.6 23.8-118.6 109.2 0 55.4 28.2 23.2 46.2 128.4 7 41.4 12.6 13.8 27.8 80.2 8 34.8-5.4 37.4-3.8 54 1.6 16.6 3.2 31.4 6.2 65.4 3.6 42-35.4 152.6-175.2 152.6-139.8 0-178.8-110.6-175-152.8 3-33.8 4.6-48.8 6.2-65.4 1.6-16.6-11.8-19.2-3.8-54 15.2-66.2 20.8-38.6 27.8-80.2 18-105.2 46.2-73 46.2-128.4 0-85.6 7.8-63-118.6-109.2-128.4-47-158.8-76-162.2-97.8-4.6-27.4-4.6-80.2-4.6-80.2h768z" />
-<glyph unicode="&#xe70b;" d="M896 64c0 0 0 52.8-4.4 80.4-3.6 21.8-33.8 50.6-162.2 97.8-126.4 46.4-118.6 23.8-118.6 109.2 0 55.4 28.2 23.2 46.2 128.4 7 41.4 12.6 13.8 27.8 80.2 8 34.8-5.4 37.4-3.8 54 1.6 16.6 3.2 31.4 6.2 65.4 3.6 42-35.4 152.6-175.2 152.6-139.8 0-178.8-110.6-175-152.8 3-33.8 4.6-48.8 6.2-65.4 1.6-16.6-11.8-19.2-3.8-54 15.2-66.2 20.8-38.6 27.8-80.2 18-105.2 46.2-73 46.2-128.4 0-85.6 7.8-63-118.6-109.2-128.4-47-158.8-76-162.2-97.8-4.6-27.4-4.6-80.2-4.6-80.2h768z" />
-<glyph unicode="&#xe70c;" d="M191.4 118h32.2c0-18.2 0-61.4 0-85.6l106.4 79.6c3.8 2.8 10.8 6 26.6 6h163.6c46 0 84.4 31.4 93.4 72.6l-37.4 34.8c-1.2 1.2-2.6 2.2-4 3.2 0 0 0 0.4 0 0.4-5.2 3.6-14.4 8.8-35 8.8h-216.2c-69.4 0-129 52.6-129 118.8v201.4h-3.6c-52.6 0-92.4-40.8-92.4-90.8v-257.8c0-50 42.8-91.4 95.4-91.4zM367.4 284h216.2c20.8 0 30-4.6 35-8.4l149.4-106.2v114.6h34c69.6 0 126 53.8 126 119.8v340.6c0 66-56.4 119.6-126 119.6h-434.6c-69.4 0-125.4-53.6-125.4-119.6v-139.4-201c0-66.2 56-120 125.4-120z" />
-<glyph unicode="&#xe70d;" d="M248.6 160h305.4c28.8 0 28.8-0.2 42.6-10.4s171.4-117.6 171.4-117.6v128h7.4c84.4 0 152.6 63.6 152.6 142.8v417.8c0 79.2-68.4 143.4-152.6 143.4h-526.8c-84.2 0-152.6-64.2-152.6-143.4v-417.8c0-79.2 68.4-142.8 152.6-142.8zM704.2 576c35.4 0 64-28.6 64-64s-28.6-64-64-64c-35.4 0-64 28.6-64 64 0 35.4 28.6 64 64 64zM512.2 576c35.4 0 64-28.6 64-64s-28.6-64-64-64c-35.4 0-64 28.6-64 64 0 35.4 28.6 64 64 64zM320.2 576c35.4 0 64-28.6 64-64s-28.6-64-64-64c-35.4 0-64 28.6-64 64 0 35.4 28.6 64 64 64z" />
-<glyph unicode="&#xe70e;" d="M248.6 160h305.4c28.8 0 28.8-0.2 42.6-10.4s171.4-117.6 171.4-117.6v128h7.4c84.4 0 152.6 63.6 152.6 142.8v417.8c0 79.2-68.4 143.4-152.6 143.4h-526.8c-84.2 0-152.6-64.2-152.6-143.4v-417.8c0-79.2 68.4-142.8 152.6-142.8z" />
-<glyph unicode="&#xe70f;" d="M146.6 178c0 0 0 0 0 0 3.6-6 5.6-12.8 5.6-20.4l-24.2-125.6 112.4 44.2c5.4 2.2 11.2 3.4 17.4 3.4 5.6 0 11-1 16-2.8 0 0 0.2 0 0.4 0 0.8-0.4 1.6-0.6 2.4-1 35.6-14.6 74.8-22.8 115.8-22.8 92.6 0 175.2 41 229.6 105.2-28.2-7.2-57.8-11.4-88.2-11.4-191.8 0-347.4 150-347.4 335 0 23.6 2.6 46.4 7.4 68.6-60-52.2-97.8-127.6-97.8-211.6 0-56.8 17.2-110.4 47-155 1.2-1.6 2.4-3.8 3.6-5.8zM580.6 864c-167.4 0-307.2-114.4-340-266.4-4.8-22.2-7.4-45-7.4-68.6 0-185 155.4-335 347.4-335 30.6 0 60 4.2 88.2 11.4 16.2 4.2 32.2 9 47.6 15.2 1 0.4 1.8 0.8 2.8 1.2 0.2 0 0.4 0 0.4 0.2 5.8 2.2 12.2 3.4 18.6 3.4 7.2 0 14-1.4 20.2-4l137.2-51.6-34 147.6c0 8.8 2.4 17.2 6.6 24.4 0 0 0 0 0 0 1.2 2.2 2.8 4.2 4.2 6.2 34.8 52.2 55 114.4 55 181 0.6 185-154.8 335-346.8 335z" />
-<glyph unicode="&#xe710;" d="M512 61.2c57.8 0 112.8 11.4 162.6 31.8 1.2 0.6 2.2 1 3.4 1.4 0.2 0 0.4 0 0.4 0.2 7 2.6 14.6 4 22.4 4 8.6 0 16.8-1.6 24.2-4.8l168-61.8-44.2 176.8c0 10.6 3 20.6 7.8 29.2 0 0 0 0 0 0 1.6 2.6 3.2 5.2 5 7.4 41.8 62.6 66 137 66 216.8 0.4 222-185.8 401.8-415.6 401.8-229.8 0-416-179.8-416-401.4 0-221.8 186.2-401.4 416-401.4zM704 512c35.4 0 64-28.6 64-64s-28.6-64-64-64c-35.4 0-64 28.6-64 64 0 35.4 28.6 64 64 64zM512 512c35.4 0 64-28.6 64-64s-28.6-64-64-64c-35.4 0-64 28.6-64 64 0 35.4 28.6 64 64 64zM320 512c35.4 0 64-28.6 64-64s-28.6-64-64-64c-35.4 0-64 28.6-64 64 0 35.4 28.6 64 64 64z" />
-<glyph unicode="&#xe711;" d="M512 61.2c57.8 0 112.8 11.4 162.6 31.8 1.2 0.6 2.2 1 3.4 1.4 0.2 0 0.4 0 0.4 0.2 7 2.6 14.6 4 22.4 4 8.6 0 16.8-1.6 24.2-4.8l168-61.8-44.2 176.8c0 10.6 3 20.6 7.8 29.2 0 0 0 0 0 0 1.6 2.6 3.2 5.2 5 7.4 41.8 62.6 66 137 66 216.8 0.4 222-185.8 401.8-415.6 401.8-229.8 0-416-179.8-416-401.4 0-221.8 186.2-401.4 416-401.4z" />
-<glyph unicode="&#xe712;" d="M172.8 0h678.4c24.6 0 44.8 19.8 44.8 44.2v423.8c0 24.4-20 44-44.8 44h-529.2v61.8c0 54.6 19.8 122.2 56.2 160.6v0 0.6c35.2 37.2 83.8 59 133.6 59h0.4c49.8 0 98.4-21.8 133.6-59v-0.4-0.2c22.6-23.8 38.8-58.6 48-94.6h106.8c-11.8 62.6-39.4 123.6-78.4 164.8-52.4 55.6-127.4 91.4-210 91.4-0.2 0-0.2 0-0.2 0 0 0-0.2 0-0.2 0-82.6 0-158-35.8-210.6-91.2-52.8-55.6-85.2-147.8-85.2-230.8v-62h-43.2c-24.8 0-44.8-19.8-44.8-44v-423.8c0-24.4 20-44.2 44.8-44.2z" />
-<glyph unicode="&#xe713;" d="M172.8 0h678.4c24.6 0 44.8 19.8 44.8 44.2v423.8c0 24.4-20 44-44.8 44h-43.2v61.8c0 83-32.4 175.2-85.2 230.8-52.6 55.6-128 91.4-210.6 91.4-0.2 0-0.2 0-0.2 0 0 0-0.2 0-0.2 0-82.6 0-158-35.8-210.6-91.2-52.8-55.6-85.2-147.8-85.2-230.8v-62h-43.2c-24.8 0-44.8-19.8-44.8-44v-423.8c0-24.4 20-44.2 44.8-44.2zM322 573.8c0 54.6 19.8 122.2 56.2 160.6v0 0.6c35.2 37.2 83.8 59 133.6 59h0.4c49.8 0 98.4-21.8 133.6-59v-0.4l-0.2-0.2c36.6-38.4 56.2-106 56.2-160.6v-61.8h-379.8v61.8z" />
-<glyph unicode="&#xe714;" d="M227.4 352c-55 0-99.4 42.8-99.4 96 0 53 44.4 96 99.4 96 55.2 0 99.6-43 99.6-96 0-53.2-44.4-96-99.6-96zM512 352c-55 0-99.6 42.8-99.6 96 0 53 44.6 96 99.6 96 55 0 99.4-43 99.4-96 0-53.2-44.4-96-99.4-96zM796.4 352c-55 0-99.6 42.8-99.6 96 0 53 44.4 96 99.6 96 55 0 99.6-43 99.6-96 0-53.2-44.4-96-99.6-96z" />
-<glyph unicode="&#xe715;" d="M320 653.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101zM576 653.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101zM832 653.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101zM320 397.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101zM576 397.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101zM832 397.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101zM320 141.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101zM576 141.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101zM832 141.4c0-7.4-6-13.4-13.4-13.4h-101c-7.4 0-13.4 6-13.4 13.4v101c0 7.4 6 13.4 13.4 13.4h101c7.4 0 13.4-6 13.4-13.4v-101z" />
-<glyph unicode="&#xe716;" d="M796.2 493.6c0 2.4 0.4 4.8 0.4 7.2 0 130-103.6 235.2-231.4 235.2-92.2 0-171.4-54.8-208.6-134-16.2 8.2-34.4 13-53.6 13-59 0-108.2-43.8-117.6-101-70.8-24.4-121.4-92.2-121.4-172 0-100.4 80.2-182 179-182h205v160h-96.4l160.4 167.4 160.4-167.2h-96.4v-160h220.6c90.4 0 163.4 75 163.4 166.8s-73.4 166.4-163.8 166.6z" />
-<glyph unicode="&#xe717;" d="M796.2 493.6c0 2.4 0.4 4.8 0.4 7.2 0 130-103.6 235.2-231.4 235.2-92.2 0-171.4-54.8-208.6-134-16.2 8.2-34.4 13-53.6 13-59 0-108.2-43.8-117.6-101-70.8-24.4-121.4-92.2-121.4-172 0-100.4 80.2-181.8 179-182h553.4c90.4 0.4 163.4 75 163.4 166.8 0.2 92-73.2 166.6-163.6 166.8z" />
-<glyph unicode="&#xe718;" d="M512 832c-131.8 0-238.6-107.4-238.6-240 0-229.2 238.6-528 238.6-528s238.6 298.8 238.6 528c0 132.6-106.8 240-238.6 240zM512 475.6c-62.4 0-112.8 50.8-112.8 113.4 0 62.6 50.6 113.6 112.8 113.6 62.4 0 112.8-50.8 112.8-113.6 0-62.6-50.4-113.4-112.8-113.4z" />
-<glyph unicode="&#xe719;" d="M885.6 760.8l-60.8 60.8c-14 13.8-36.4 13.8-50.2 0l-63.6-63.6 111-111 63.6 63.4c13.8 14.2 13.8 36.6 0 50.4zM692.2 739l-344-355-28.2-128 128 28.2 353.2 346zM768 448v-300c0-10.2-7.8-20.2-18.4-20.2s-538 0.2-538 0.2c-11.2 0-19.6 10.8-19.6 20s0 536 0 536c0 10 9.4 20 21.2 20h298.8l64 64h-401.2c-26 0-46.8-20.6-46.8-46.6v-610.6c0-25.8 21-46.8 46.8-46.8h610.6c25.8 0 46.6 21 46.6 46.8v401.2l-64-64z" />
-<glyph unicode="&#xe71a;" d="M649.2 650.2c-12.6 0.2-22.8-10.2-22.8-23.2l-0.4-389.6c-0.2-87.6-59.4-126.8-114.4-126.4-55 0.6-114.2 40.8-114 128.2 0 67 0.4 335.4 0.6 469.6 0 30.8 12 54.8 33.6 67.4 21.2 12.4 48.8 12.2 70-0.6 21.6-13 33.4-37.2 33.4-68l-0.6-449c0-14.6-3.4-26.6-9.4-34.2-3.8-4.8-8.8-7.6-13.8-7.6-11.2 0.2-22.8 14.6-22.6 41.6 0 0 0.4 332.6 0.6 345.4 0 13-10.2 23.6-22.8 23.6-12.6 0-22.8-10.4-22.8-23.4l-0.6-345.4c0-58 34.4-88.6 68.4-89 18.8-0.2 36.6 8.8 49.2 24.8 12.6 16 19.4 38 19.4 63.6l0.6 449c0 47.6-20.4 87.2-56.2 108.6-35 21.2-80.6 21.6-115.8 1-35.8-21-56.4-60.2-56.6-107.8-0.2-134-0.4-402.4-0.6-469.6-0.2-114.4 80.2-174.8 159.6-175.6 41-0.4 82.2 15.4 112.6 46.2 28.4 29 47.4 71.4 47.4 126.8l0.2 389.8c0.6 13.2-9.6 23.8-22.2 23.8z" />
-<glyph unicode="&#xe71b;" d="M704 204.2h-499.2v359.4h115c0 0 28.2 39.4 85.4 76.4h-238.8c-21.2 0-38.4-17-38.4-38.2v-435.8c0-21 17.2-38.2 38.4-38.2h576c21.2 0 38.4 17 38.4 38.2v218l-76.8-62.8v-117zM640 512v-127.8l256 191-256 192.8v-119.4c-309.6 0-320-328.6-320-328.6 87.6 143 152 192 320 192z" />
-<glyph unicode="&#xe71c;" d="M134 662.6c22-11.6 327.6-178.2 339-184.2s23-8.8 41-8.8c18 0 29.6 2.8 41 8.8 11.4 6 317 172.6 339 184.2 8.2 4.2 22 11.8 25 20.4 5.2 15.2-0.4 21-22.6 21h-764.8c-22.2 0-27.8-6-22.6-21 3-8.8 16.8-16.2 25-20.4zM911.4 653.6c-16.4-8.4-163.6-113.2-261-176.2l164.4-185c4-4 5.8-8.8 3.6-11.2-2.4-2.2-7.6-1-11.8 2.8l-197.2 166.4c-29.8-19.2-50.8-32.4-54.4-34.4-15.4-7.8-26.2-8.8-41-8.8-14.8 0-25.6 1-41 8.8-3.8 2-24.6 15.2-54.4 34.4l-197.2-166.4c-4-4-9.4-5.2-11.8-2.8-2.4 2.2-0.6 7.2 3.4 11.2l164.2 185c-97.4 63-246.2 167.8-262.6 176.2-17.6 9-18.6-1.6-18.6-9.8 0-8.2 0-410 0-410 0-18.6 27.4-41.8 47-41.8h742c19.6 0 43 23.4 43 41.8 0 0 0 402 0 410 0 8.4 1.2 18.8-16.6 9.8z" />
-<glyph unicode="&#xe71d;" d="M609 576v160l-303.6-287.6 303.6-268.4v183.8c136 0 215.8-17.8 318.2-203.8 0 0-12.2 416-318.2 416zM95 448l288-253v117l-164.4 136 164.4 157.2v114z" />
-<glyph unicode="&#xe71e;" d="M576 363.8v-184.6l320 268.8-320 288v-160c-374.4 0-448-416-448-416 106 186 244.8 203.8 448 203.8z" />
-<glyph unicode="&#xe71f;" d="M896 160c0 0-73.6 416-448 416v160l-320-288 320-268.8v184.6c203.2 0 342-17.8 448-203.8z" />
-<glyph unicode="&#xe720;" d="M762 702.8h-497.8c-24.2 0-39 0-39-40.8v-56.2h576v56.2c0 40.8-14.8 40.8-39.2 40.8zM666 767h-306c-26.2 0-39-0.6-39-37.4h384c-0.2 36.8-12.8 37.4-39 37.4zM864.8 620.8l-31.8 18.8v-64.6h-642v64.6l-30.4-18.8c-28.6-17.8-35.6-30.6-30-81.8l35-369.6c7.4-41.4 31.8-42.4 48-42.4h599.8c16.2 0 40.4 1 47.8 42.4l34.4 368.8c4.6 48.8-4 65.6-30.8 82.6z" />
-<glyph unicode="&#xe721;" d="M797.2 621.6c-1.8 4.4-4 8.6-7 12.2l-167.6 183.4c-3.8 4.2-8.4 7.2-13.4 9.8-5.8 3-12.2 4.2-19 4.2h-319.8c-24.8 0-45.4-21.2-45.4-47.8v-670.4c0-26.8 20.6-49.8 45.4-49.8h486.2c24.8 0 44.4 23 44.4 49.8v488.2c0 7.2-1 14.2-3.8 20.4zM321 602.8c0 3 3.6 4.2 6.8 4.2h141.6c3.2 0 5.6-1.2 5.6-4.2v-21.6c0-2.8-2.2-6.2-5.6-6.2h-141.6c-3.2 0-6.8 3.4-6.8 6.2v21.6zM321 346.8c0 3 3.6 4.2 6.8 4.2h244.4c3.2 0 4.8-1.2 4.8-4.2v-21.6c0-2.8-1.4-6.2-4.8-6.2h-244.4c-3.2 0-6.8 3.4-6.8 6.2v21.6zM641 197.2c0-2.8-1.4-6.2-4.8-6.2h-308.4c-3.2 0-6.8 3.4-6.8 6.2v21.6c0 3 3.6 4.2 6.8 4.2h308.4c3.2 0 4.8-1.2 4.8-4.2v-21.6zM705 453.2c0-2.8-1.4-6.2-4.8-6.2h-372.4c-3.2 0-6.8 3.4-6.8 6.2v21.6c0 3 3.6 4.2 6.8 4.2h372.4c3.2 0 4.8-1.2 4.8-4.2v-21.6zM611.2 605c-11.2 0-22.2 10.4-22.2 22.6v132l142.4-154.6h-120.2z" />
-<glyph unicode="&#xe722;" d="M798.6 622.2c-1.4 5.8-4 10-7 13.6l-167.4 183.4c-3.8 4.2-8.2 6.2-13.2 8.8-5.8 3-12.2 3.2-18.8 3.2h-319.8c-24.8 0-47.4-19.2-47.4-45.8v-670.4c0-26.8 22.6-51.8 47.4-51.8h486.2c24.8 0 42.4 25 42.4 51.8v488.2c0 7.2-0.8 12.4-2.4 19zM611 738l116-127h-116v127zM289 127v640h258v-163.4c0-29.6 26.8-56.6 56.2-56.6h133.8v-420h-448z" />
-<glyph unicode="&#xe723;" d="M896 371.2v153.6h-85.6c-6.8 28.8-17.8 56-32.2 81l59.6 59.4-108.6 108.6-58.2-58.2c-25.2 15.4-52.8 27-82.2 34.6v81.8h-153.6v-81.8c-29.4-7.6-57-19.4-82.2-34.6l-58.2 58.2-108.6-108.6 59.6-59.4c-14.4-25-25.2-52.2-32.2-81h-85.6v-153.6h88.2c7.6-27.4 19-53.2 33.4-77.2l-63.4-63.4 108.6-108.6 64.6 64.6c23.4-13.6 49-23.8 75.8-30.8v-92h153.6v92c27 7 52.4 17.2 75.8 30.8l64.6-64.6 108.6 108.6-63.2 63.4c14.4 23.8 25.8 49.6 33.4 77.2h88zM512 340.4c-59.4 0-107.4 48.2-107.4 107.6s48 107.6 107.4 107.6 107.6-48.2 107.6-107.6-48.2-107.6-107.6-107.6z" />
-<glyph unicode="&#xe724;" d="M822.2 448c0 47.8 29.6 85.6 73.8 111.6-8 26.6-18.6 52.4-31.6 76.4-49.8-13-90 6.4-124 40.4-33.8 33.8-44.2 74.2-31.2 124-24 13-49.6 23.6-76.4 31.6-26-44.4-72.8-73.8-120.8-73.8-47.8 0-94.8 29.4-120.8 73.8-26.8-8-52.4-18.6-76.4-31.6 13-49.8 2.6-90-31.2-124-33.8-33.8-74.2-53.4-123.8-40.4-13.2-24-23.8-49.6-31.8-76.4 44.4-26 74-63.8 74-111.6 0-47.8-29.6-94.8-74-120.8 8-26.8 18.6-52.4 31.6-76.4 49.8 13 90 2.6 123.8-31.2 34-33.8 44.2-74.2 31.2-124 24.2-13 49.6-23.6 76.4-31.6 26 44.4 73 73.8 120.8 73.8 47.8 0 94.8-29.4 120.8-73.8 26.8 8 52.4 18.6 76.4 31.6-13 49.8-2.6 90 31.2 124 33.8 33.8 74.2 53.4 124 40.4 13 24.2 23.6 49.8 31.6 76.4-44.2 26-73.6 63.8-73.6 111.6zM512 251.4c-108.4 0-196.6 88-196.6 196.6s88 196.6 196.6 196.6c108.6 0 196.6-88 196.6-196.6 0-108.6-88-196.6-196.6-196.6z" />
-<glyph unicode="&#xe725;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448s-200.6 448-448 448zM552.4 242.6c-1-35.6-27.4-57.6-61.6-56.6-32.8 1-58.6 24.4-57.6 60.2 1 35.6 28.2 58.2 61 57.2 34.4-1 59.4-25.2 58.2-60.8zM649.8 497.2c-8.4-11.8-27.2-27-50.8-45.4l-26.2-18c-12.8-9.8-20.8-21.4-25-34.6-2.2-7-3.8-25.2-4.2-37.4-0.2-2.4-1.6-7.8-9-7.8-7.4 0-70 0-78.2 0-8.2 0-9.2 4.8-9 7.2 1.2 33.2 6 60.6 19.8 82.6 18.6 29.6 71 60.8 71 60.8 8 6 14.2 12.4 19 19.4 8.8 12 16 25.4 16 39.8 0 16.6-4 32.4-14.6 45.6-12.4 15.4-25.8 22.8-51.6 22.8-25.4 0-40.2-12.8-50.8-29.6-10.6-16.8-8.8-36.6-8.8-54.6h-97.4c0 68 17.8 111.4 55.4 137 25.4 17.4 57.8 25 95.6 25 49.6 0 89-9.2 123.8-35.6 32.2-24.4 49.2-58.8 49.2-105.2 0-28.6-10-52.6-24.2-72z" />
-<glyph unicode="&#xe726;" d="M690.2 805.8c-55 41.8-117 56.2-195.6 56.2-59.6 0-110.6-12.2-151-39.4-59.6-40.6-87.6-108.8-87.6-216.6h153.6c0 28.8-2.8 59.8 14 86.4s40.2 47 80.4 47c40.8 0 61.8-11.8 81.6-36.2 16.8-20.8 23.2-45.6 23.2-72 0-22.8-11.6-43.8-25.4-62.8-7.6-11.2-17.6-21.2-30.2-30.8 0 0-83-49.4-112.2-96.2-21.8-34.8-29.6-78.4-31.4-130.6-0.2-3.8 1.2-11.6 14.4-11.6 13 0 112 0 123.6 0 11.6 0 14 8.8 14.2 12.4 0.8 19 3.2 48.2 6.6 59.2 6.6 20.8 19.4 39 39.4 54.6l41.4 28.6c37.4 29.2 67.2 53 80.4 71.8 22.6 30.8 38.4 68.8 38.4 113.8 0 73.4-27 127.6-77.8 166.2zM484 219.6c-51.8 1.6-94.6-34.4-96.4-90.6-1.6-56.4 39-93.4 91-95 54-1.6 95.8 33.2 97.4 89.4 1.6 56.2-38 94.6-92 96.2z" />
-<glyph unicode="&#xe727;" d="M576 64v512h-192v-32h64v-480h-64v-32h256v32zM511.6 671c53.2 0 96.4 43.2 96.4 96.4s-43.2 96.4-96.4 96.4c-53.2 0-96.4-43.2-96.4-96.4s43.2-96.4 96.4-96.4z" />
-<glyph unicode="&#xe728;" d="M128 512h768v-128h-768v128z" />
-<glyph unicode="&#xe729;" d="M834.8 512h-645.6c-33.8 0-61.2-28.6-61.2-64s27.4-64 61.2-64h645.6c33.8 0 61.2 28.6 61.2 64s-27.4 64-61.2 64z" />
-<glyph unicode="&#xe72a;" d="M896 512h-320v320h-128v-320h-320v-128h320v-320h128v320h320z" />
-<glyph unicode="&#xe72b;" d="M834.8 512h-258.8v258.8c0 33.8-28.6 61.2-64 61.2s-64-27.4-64-61.2v-258.8h-258.8c-33.8 0-61.2-28.6-61.2-64s27.4-64 61.2-64h258.8v-258.8c0-33.8 28.6-61.2 64-61.2s64 27.4 64 61.2v258.8h258.8c33.8 0 61.2 28.6 61.2 64s-27.4 64-61.2 64z" />
-<glyph unicode="&#xe72c;" d="M0 672h1024v-64h-1024v64zM0 480h1024v-64h-1024v64zM0 288h1024v-64h-1024v64z" />
-<glyph unicode="&#xe72d;" d="M192 478h640v-64h-640v64zM192 670h640v-64h-640v64zM192 286h640v-64h-640v64z" />
-<glyph unicode="&#xe72e;" d="M834.8 512h-645.6c-33.8 0-61.2-28.6-61.2-64s27.4-64 61.2-64h645.6c33.8 0 61.2 28.6 61.2 64s-27.4 64-61.2 64zM834.8 768h-645.6c-33.8 0-61.2-28.6-61.2-64s27.4-64 61.2-64h645.6c33.8 0 61.2 28.6 61.2 64s-27.4 64-61.2 64zM834.8 256h-645.6c-33.8 0-61.2-28.6-61.2-64s27.4-64 61.2-64h645.6c33.8 0 61.2 28.6 61.2 64s-27.4 64-61.2 64z" />
-<glyph unicode="&#xe72f;" d="M859.8 768.8c-80.8 84.2-212 84.2-292.8 0l-55-57-55 57.2c-81 84.2-212 84.2-292.8 0-91-94.6-91-248.2 0-342.8l347.8-362.2 347.8 362c91 94.6 91 248.2 0 342.8z" />
-<glyph unicode="&#xe730;" d="M896 544h-294l-90 288-90-288h-294l238.2-178.6-94.2-301.4 240 192 240-192-94.2 301.4z" />
-<glyph unicode="&#xe731;" d="M890 186.6l-169.6 171.8c27.6 48.2 42 101.8 42 155.8 0 175.2-142.4 317.8-317.2 317.8-174.8 0-317.2-142.6-317.2-317.8 0-175.2 142.4-317.8 317.2-317.8 55.8 0 111 15.4 160.2 44.8l168.8-171.2c3.8-3.8 9.2-6.2 14.6-6.2s10.8 2.2 14.6 6.2l86.6 87.6c8 8.2 8 21 0 29zM445.2 708.2c106.8 0 193.6-87 193.6-194s-86.8-194-193.6-194c-106.8 0-193.6 87-193.6 194 0 107 86.8 194 193.6 194z" />
-<glyph unicode="&#xe732;" d="M896 384l-384 448-384-448h96v-320h192v256h192v-256h192v320z" />
-<glyph unicode="&#xe733;" d="M740.2 597.4h57.8v-94.6l162 166.4-162 162.8v-108h-57.8c-165.4 0-258.8-123.8-341.2-233-74-98.2-138-190.8-241.2-190.8h-93.8v-126.6h93.8c165.4 0 258.8 131.6 341.2 240.8 74 98.2 137.8 183 241.2 183zM306.4 525c7 9.2 14.2 18.6 21.4 28.2 17.6 23.2 36 47.8 56 72.2-59.2 55.8-130.6 97-226 97h-93.8v-126.6c0 0 26.6 1.2 93.8 0 65-1.4 105.8-28.2 148.6-70.8zM798 299.2h-57.8c-63 0-111.4 31.6-156.4 78.6-4.4-6-9-12-13.6-18-19.8-26.2-41-54.4-64.4-82.2 60.8-59.8 134.4-105 234.4-105h57.8v-108.6l162 162.8-162 166.4v-94z" />
-<glyph unicode="&#xe734;" d="M618.2 766.4l-4.8 1.4c-7.4 2-15 4-23.6 5.8-3.4 0.8-7 1.4-10.6 2.2-5.6 1-11.2 1.8-17 2.4-5.2 0.8-10.6 1.4-15.8 1.8l-0.2 116-205.8-180 206.6-179.2-0.4 126.8c1.6-0.2 3.2-0.2 4.6-0.6 5.8-0.8 11.6-2 17.2-3.2 8.2-2 16-4.2 23.6-7 4.4-1.6 8.8-3.2 13-5 8.6-3.8 17-8.2 25.2-13.2l2.4-1.4c2-1.2 4-2.4 6-3.6 8.6-5.8 16.8-12.4 25-20l2.2-1.8c1-0.8 1.8-1.6 2.6-2.2 8-8 15.4-16.6 22.2-26.2l1.4-1.6c0.6-0.6 1-1.2 1.6-2 5.8-8.4 11.4-18.2 16.8-29.8 0.4-0.8 0.8-1.6 1.2-2.4 0.4-0.6 0.8-1.4 1-2.2 4-9 7.2-19.2 10.4-32 0.2-1 0.6-2.2 1-3.2 0.2-0.8 0.6-1.6 0.8-2.8 2.8-13 4.2-26.6 4.2-40.4 0.2-43.6-13.8-85.4-40.6-120.6l-11-14.4 86.8-78.4 14 17.2c45.6 56.8 69.6 124.6 69.4 196.6 0 139.8-92.4 261.6-229.4 303zM477.4 232.2c-1.6 0.2-3.2 0.2-4.8 0.6-5.8 0.8-11.6 2-17.2 3.2-7.8 1.8-15.6 4.2-23.6 7-4.4 1.6-8.8 3.2-13 5-8.4 3.8-16.8 8.2-25.2 13.2l-2.8 1.6c-1.8 1.2-3.8 2.2-5.6 3.4-8.6 5.8-16.8 12.4-25 20l-2.2 1.8c-1 0.8-1.8 1.6-2.6 2.2-7.8 7.6-15 16.2-22.2 26-0.4 0.6-1 1.4-1.6 2-0.4 0.6-1 1-1.4 1.8-6 8.6-11.4 18.4-16.8 29.8-0.4 1-1 2-1.4 2.8-0.4 0.6-0.8 1.2-1 1.8-3.8 8.8-7.2 18.8-10.4 32-0.2 1.2-0.6 2.2-1 3.2-0.2 0.8-0.6 1.6-0.8 2.8-2.8 13-4.2 26.4-4.4 40.2-0.2 43.8 14 85.4 40.6 120.6l11 14.4-86.8 78.4-14-17.2c-45.6-56.6-69.6-124.6-69.4-196.6 0.2-139.8 92.6-261.6 229.8-303l4.8-1.4c7.4-2 15-4 23.6-5.8 3.4-0.8 7-1.6 10.6-2.2 5.6-1 11.4-1.8 17-2.4 5.4-0.8 10.6-1.2 15.8-1.8l0.2-116 205.8 180-206.6 179.2 0.6-126.6z" />
-<glyph unicode="&#xe735;" d="M512 894c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM728.6 295c3-3 4.6-7 4.6-11.2s-1.6-8.4-4.6-11.2l-43.2-43.4c-3.2-3.2-7.2-4.6-11.2-4.6s-8.2 1.6-11.2 4.6l-151 151.2-150.8-151.4c-3-3.2-7.2-4.6-11.2-4.6s-8.2 1.6-11.2 4.6l-43.2 43.4c-3 3-4.6 7-4.6 11.2s1.6 8.4 4.6 11.2l151.4 152-151.8 150c-6.2 6.2-6.2 16.4 0 22.6l43.2 43.4c3 3 7 4.6 11.2 4.6s8.2-1.6 11.2-4.6l151.4-149.4 151.4 149.4c3 3 7 4.6 11.2 4.6s8.2-1.6 11.2-4.6l43.2-43.4c6.2-6.2 6.2-16.4 0-22.6l-151.8-150 151.2-151.8z" />
-<glyph unicode="&#xe736;" d="M887.2 185.8l-262.4 263.4 263 260c10.8 10.8 10.8 28.4 0 39.2l-74.8 75.2c-5.2 5.2-12.2 8-19.6 8s-14.4-3-19.6-8l-261.8-259.2-262.2 259c-5.2 5.2-12.2 8-19.6 8s-14.4-3-19.6-8l-74.6-75.2c-10.8-10.8-10.8-28.4 0-39.2l263-260-262.2-263.2c-5.2-5.2-8.2-12.2-8.2-19.6s2.8-14.4 8.2-19.6l74.8-75.2c5.4-5.4 12.4-8.2 19.6-8.2 7 0 14.2 2.6 19.6 8.2l261.2 262.4 261.4-262.2c5.4-5.4 12.4-8.2 19.6-8.2 7 0 14.2 2.6 19.6 8.2l74.8 75.2c5.2 5.2 8.2 12.2 8.2 19.6-0.2 7.2-3.2 14.2-8.4 19.4z" />
-<glyph unicode="&#xe737;" d="M875 186.8l-261.2 261.2 261.2 261.2c28.2 28.2 28.2 73.6 0 101.8s-73.6 28.2-101.8 0l-261.2-261.2-261.2 261.2c-28.2 28.2-73.6 28.2-101.8 0-28.2-28.2-28.2-73.6 0-101.8l261.2-261.2-261.2-261.2c-28.2-28.2-28.2-73.6 0-101.8 28.2-28.2 73.6-28.2 101.8 0l261.2 261.2 261.2-261.2c28.2-28.2 73.6-28.2 101.8 0 28 28.2 28 73.8 0 101.8z" />
-<glyph unicode="&#xe738;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM741.8 597.8l-278.2-357c-2.2-2.2-5.8-7-10.2-7-4.6 0-7.6 3.2-10.2 5.8-2.6 2.6-157.8 151.8-157.8 151.8l-3 3c-1.2 1.8-2.2 4-2.2 6.4s1 4.6 2.2 6.4c0.8 0.8 1.4 1.4 2.2 2.4 15.4 16.2 46.6 49 48.6 51 2.6 2.6 4.8 6 9.6 6 5 0 8.2-4.2 10.6-6.6 2.4-2.4 90-86.6 90-86.6l222.6 286c2 1.6 4.4 2.8 7 2.8s5-1 7-2.6l61.2-48.2c1.6-2 2.6-4.4 2.6-7 0.2-2.6-0.8-4.8-2-6.6z" />
-<glyph unicode="&#xe739;" d="M923.2 740.8l-109.8 86.6c-3.4 2.8-7.6 4.8-12.4 4.8s-9.2-2-12.6-5l-399.4-513.2c0 0-157 151-161.4 155.4s-10.2 11.8-19 11.8c-8.8 0-12.8-6.2-17.4-10.8-3.4-3.6-59.4-62.4-87-91.6-1.6-1.8-2.6-2.8-4-4.2-2.4-3.4-4-7.2-4-11.4 0-4.4 1.6-8 4-11.4l5.6-5.2c0 0 278.6-267.6 283.2-272.2s10.2-10.4 18.4-10.4c8 0 14.6 8.6 18.4 12.4l498.2 640c2.4 3.4 4 7.2 4 11.6 0 5-2 9.2-4.8 12.8z" />
-<glyph unicode="&#xe73a;" d="M896 816.2c-34.6 26.8-83 18.6-108.2-18.2l-359.8-526.4-198.2 214.6c-29.2 33.2-78.2 34.8-109.4 3.6-31.2-31-32.8-83.2-3.4-116.2 0 0 240.8-267.2 275.4-294 34.6-26.8 83-18.6 108.2 18.2l412.6 603.4c25.2 37 17.4 88.4-17.2 115z" />
-<glyph unicode="&#xe73b;" d="M427.4 448v0 0l334.4 348.2c8.4 8.6 8.2 22.8-0.4 31.6l-59.8 61.2c-8.6 8.8-22.6 9-31 0.4l-408.4-425.2c-4.4-4.4-6.4-10.4-6-16.2-0.2-6 1.8-11.8 6-16.2l408.4-425.4c8.4-8.6 22.4-8.4 31 0.4l59.8 61.2c8.6 8.8 8.8 23 0.4 31.6l-334.4 348.4z" />
-<glyph unicode="&#xe73c;" d="M596.6 448v0 0l-334.4 348.2c-8.4 8.6-8.2 22.8 0.4 31.6l59.8 61.2c8.6 8.8 22.6 9 31 0.4l408.4-425.4c4.4-4.4 6.4-10.4 6-16.2 0.2-6-1.8-11.8-6-16.2l-408.4-425.2c-8.4-8.6-22.4-8.4-31 0.4l-59.8 61.2c-8.6 8.8-8.8 23-0.4 31.6l334.4 348.4z" />
-<glyph unicode="&#xe73d;" d="M512 363.4v0 0l348.4 334.4c8.6 8.4 22.8 8.2 31.6-0.4l61.2-59.8c8.8-8.6 9-22.6 0.4-31l-425.4-408.4c-4.4-4.4-10.4-6.4-16.2-6-6-0.2-11.8 1.8-16.2 6l-425.4 408.4c-8.6 8.4-8.4 22.4 0.4 31l61.2 59.8c8.8 8.6 23 8.8 31.6 0.4l348.4-334.4z" />
-<glyph unicode="&#xe73e;" d="M512 532.6v0 0l348.4-334.4c8.6-8.4 22.8-8.2 31.6 0.4l61.2 59.8c8.8 8.6 9 22.6 0.4 31l-425.4 408.4c-4.4 4.4-10.4 6.4-16.2 6-6 0.2-11.8-1.8-16.2-6l-425.4-408.4c-8.6-8.4-8.4-22.4 0.4-31l61.2-59.8c8.8-8.6 23-8.8 31.6-0.4l348.4 334.4z" />
-<glyph unicode="&#xe73f;" d="M767.2 314.6l-210-200.6c-11.6-12-27.4-18-44.8-18s-33 6-44.8 18l-210.8 200.6c-25 23.8-25 62.6 0 86.4s65.4 23.8 90.4 0l100.8-96.4v434c0 33.8 28.6 61.2 64 61.2 35.4 0 64-27.4 64-61.2v-434l100.8 96.4c25 23.8 65.4 23.8 90.4 0s25-62.4 0-86.4z" />
-<glyph unicode="&#xe740;" d="M256.8 581.4l210 200.6c11.6 12 27.4 18 44.8 18s33-6 44.8-18l210.8-200.6c25-23.8 25-62.6 0-86.4-25-23.8-65.4-23.8-90.4 0l-100.8 96.2v-434c0-33.8-28.6-61.2-64-61.2s-64 27.4-64 61.2v434l-100.8-96.4c-25-23.8-65.4-23.8-90.4 0-25 24-25 62.6 0 86.6z" />
-<glyph unicode="&#xe741;" d="M645.4 703.2l200.6-210c12-11.6 18-27.4 18-44.8s-6-33-18-44.8l-200.6-210.8c-23.8-25-62.6-25-86.4 0s-23.8 65.4 0 90.4l96.4 100.8h-434c-34 0-61.4 28.6-61.4 64s27.4 64 61.2 64h434l-96.4 100.8c-23.8 25-23.8 65.4 0 90.4 24 25 62.6 25 86.6 0z" />
-<glyph unicode="&#xe742;" d="M378.6 703.2l-200.6-210c-12-11.6-18-27.4-18-44.8s6-33 18-44.8l200.6-210.8c23.8-25 62.6-25 86.4 0 23.8 25 23.8 65.4 0 90.4l-96.2 100.8h434c33.8 0 61.2 28.6 61.2 64s-27.4 64-61.2 64h-434l96.4 100.8c23.8 25 23.8 65.4 0 90.4-24 25-62.6 25-86.6 0z" />
-<glyph unicode="&#xe743;" d="M654.6 762.2l-4.2-3.6-313-272c-10.6-9.2-17.2-23-17.2-38.4s6.8-29.2 17.2-38.4l317.6-276.4c5-3.4 11-5.4 17.4-5.4 17.4 0 31.6 14.8 31.6 33.2v0 573.6 0c0 18.4-14.2 33.2-31.6 33.2-6.6 0-12.8-2.2-17.8-5.8z" />
-<glyph unicode="&#xe744;" d="M197.8 590.6l3.6-4.2 272-313c9.2-10.6 23-17.2 38.4-17.2s29.2 6.8 38.4 17.2l276.4 317.6c3.4 5 5.4 11 5.4 17.4 0 17.4-14.8 31.6-33.2 31.6v0h-573.6c-18.4 0-33.2-14.2-33.2-31.6 0-6.6 2.2-12.8 5.8-17.8z" />
-<glyph unicode="&#xe745;" d="M369.4 133.8l4.2 3.6 313 272c10.6 9.2 17.2 23 17.2 38.4s-6.8 29.2-17.2 38.4l-317.6 276.4c-5 3.4-11 5.4-17.4 5.4-17.4 0-31.6-14.8-31.6-33.2v0-573.6 0c0-18.4 14.2-33.2 31.6-33.2 6.6 0 12.8 2.2 17.8 5.8z" />
-<glyph unicode="&#xe746;" d="M826.2 305.4l-3.6 4.2-272 313c-9.2 10.6-23 17.2-38.4 17.2s-29.2-6.8-38.4-17.2l-276.4-317.6c-3.4-5-5.4-11-5.4-17.4 0-17.4 14.8-31.6 33.2-31.6v0h573.6c18.4 0 33.2 14.2 33.2 31.6 0 6.6-2.2 12.8-5.8 17.8z" />
-<glyph unicode="&#xe747;" d="M832 256l192 218.6h-132.2c-13.6 201.8-177.8 357.4-381.4 357.4-210.8 0-382.4-172.2-382.4-384 0-211.8 171.6-384 382.4-384 86.2 0 167.6 28.2 235.4 81.4l15 11.8-86.4 92.4-12.4-9.2c-44.2-32.6-96.6-49.8-151.6-49.8-141.2 0-256.2 115.4-256.2 257.4s115 257.4 256.2 257.4c132.8 0 241.4-100 254.8-230.6h-148.2l215-218.8z" />
-<glyph unicode="&#xe748;" d="M913.4 202.6c-105 16-113 31.4-113 31.4 21.6 129.8-45.4 294.2-154.8 383.2-145.6 118.4-367 32.4-539.4 212.4-40.2 42-16.8-471 199-665.4 157.8-142 343.6-98.4 394.6-75.2 46.2 21.2 78.6 59.8 78.6 59.8 84.2-26 125.8-24.4 125.8-24.4 29.6-3.6 44.6 72.8 9.2 78.2zM721.2 193.8c-276.4 81.8-484.2 369-484.2 369s182.4-215.4 504-320.4c0.4-16.2-9.2-39.4-19.8-48.6z" />
-<glyph unicode="&#xe749;" d="M704 672v61.4c-2 56.4-43.4 98.6-102.4 98.6h-179.2c-58.8 0-100.4-42.2-102.4-98.6v-61.4h-96v-608h576v608h-96zM640 727.6c0-0.6 0-1.2 0-2v-53.6h-256v53.6c0 0.8 0 1.4 0 2s0 1.2 0 2c0 19.4 17.2 38.6 37.6 38.6h180.8c20.2 0 37.6-19 37.6-38.6 0-0.8 0-1.4 0-2zM944.4 672h-112.4v-608h112.4c8.8 0 15.6 7.2 15.6 16v576c0 8.8-6.6 16-15.6 16zM79.6 672c-8.8 0-15.6-7.2-15.6-16v-576c0-8.8 6.6-16 15.6-16h112.4v608h-112.4z" />
-<glyph unicode="&#xe74a;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM850 630.6l-10 17.4c3.4-5.6 6.8-11.4 10-17.4zM712 776l-17.2 10c5.8-3.2 11.6-6.6 17.2-10zM329.8 786.2l-18.2-10.6c6 3.8 12 7.4 18.2 10.6zM184.2 648.2l-10.4-18c3.4 6.2 6.8 12.2 10.4 18zM173.8 265.8l10.6-18.4c-3.8 6.2-7.4 12.2-10.6 18.4zM311.4 120.4l18.6-10.8c-6.2 3.4-12.4 7-18.6 10.8zM694.6 110l17.6 10.2c-5.8-3.6-11.8-7-17.6-10.2zM783.6 176.4c-20.2-20.2-42.2-37.8-65.8-52.8l-31.8 55.2-27.8-16 32-55.2c-49.6-26-104.8-41-162-43.2v63.6h-32v-63.6c-57.4 2.4-112.4 17.2-162 43.2l32 55.2-27.8 16-31.8-55.2c-23.6 15-45.6 32.6-65.8 52.8-20.2 20.2-37.8 42.2-52.8 65.8l55.2 31.8-16 27.8-55.2-32c-26 49.6-41 104.8-43.2 162h63.2v32h-63.6c2.4 57.4 17.2 112.4 43.2 162l55.2-32 16 27.8-55.2 31.8c15 23.6 32.6 45.6 52.8 65.8s42.2 37.8 65.8 52.8l31.8-55.2 27.8 16-32 55.2c49.6 26 104.8 41 162 43.2v-63.2h32v63.6c57.4-2.4 112.4-17.2 162-43.2l-32-55.2 27.8-16 31.8 55.2c23.6-15 45.6-32.6 65.8-52.8 20.2-20.2 37.8-42.2 52.8-65.8l-55.2-31.8 16-27.8 55.2 32c26-49.6 41-104.8 43.2-162h-63.2v-32h63.6c-2.4-57.4-17.2-112.4-43.2-162l-55.2 32-16-27.8 55.2-31.8c-15-23.8-32.6-46-52.8-66.2zM850.2 265.6c-3.2-6-6.8-12-10.4-17.8l10.4 17.8zM800 462h-225.6c-4 17.6-15.2 32.6-30.4 41.4v168.6h-64v-168.6c-19.2-11-32-31.8-32-55.4 0-14.8 5-28.4 13.6-39.4l-140.8-141.4 11.4-11.4 140.8 141.4c10.8-8.4 24.4-13.4 39.2-13.4 29 0 53.6 19.4 61.4 46h226.4v32.2z" />
-<glyph unicode="&#xe74b;" d="M606 288.8v514.4c0 51.4-42 93-94 93s-94-41.6-94-93v-513.6c-40-29-65.8-76.4-65.8-129.8 0-88.4 72-160 160.4-160 88.4 0 159.6 71.6 159.6 160-0.2 53-26.2 100-66.2 129zM482 803.2c0 16 13.4 29 30 29s30-13 30-29v-99.2h-60v99.2zM544 384h-32v32h32v-32zM544 448h-32v128h32v-128z" />
-<glyph unicode="&#xe74c;" d="M931.4 159.4l-429.4 405c-8.6 7.8-12.2 18.8-9.6 31.6 0.8 3.4 2.4 7.4 3.8 10.8 23.8 77 12.2 161.2-46.4 223.6-1.6 1.8-3.6 3.6-5.2 5.4-43 43.2-85 56.4-125.8 59.4-24.8 1.8-70.8-8.8-83.6-33.2l123.6-123.6c1.8-2.6 3-5.8 3-9.2 0-3.8-1.4-7.4-3.6-10.2l-8.6-8.6-107.4-107.6c-3.4-2.4-8-3.8-12.4-3.8-4 0-7.6 1.4-10.4 3.8l-121.8 121.8c-23.6-12.2-34.8-58.6-33-83.4 3-40.6 16.4-82.6 59.6-125.6 1.8-1.8 3.6-3.6 5.4-5.2 62.4-58.6 146.6-70.2 223.6-46.2 3.2 1.6 7.2 3.2 10.8 3.8 12.8 2.6 23.8-1 31.6-9.6l404.8-429.4c33.4-38.6 94.6-36.4 131-0.6 35.8 36 38.6 97.6 0 131zM895.2 64.8c-12.6-12.6-33.2-12.6-45.8 0-12.6 12.6-12.6 33.2 0 45.8 12.6 12.6 33.2 12.6 45.8 0 12.6-12.6 12.6-33.2 0-45.8z" />
-<glyph unicode="&#xe74d;" d="M944.4 672h-240.4v61.4c-2 56.4-43.4 98.6-102.4 98.6h-179.2c-58.8 0-100.4-42.2-102.4-98.6v-61.4h-240.4c-8.8 0-15.6-7.2-15.6-16v-576c0-8.8 6.6-16 15.6-16h865c8.8 0 15.6 7.2 15.6 16v576c-0.2 8.8-6.8 16-15.8 16zM384 725.6c0 0.8 0 1.4 0 2s0 1.2 0 2c0 19.4 17.2 38.6 37.6 38.6h180.8c20.2 0 37.6-19 37.6-38.6 0-0.6 0-1.2 0-2s0-1.2 0-2v-53.6h-256v53.6zM704 320h-128v-128h-128v128h-128v128h128v128h128v-128h128v-128z" />
-<glyph unicode="&#xe74e;" d="M581.2 368c2.6 1 6 1.8 8.6 2.2 18.2 5.8 36 13.6 52.4 23.2 24 13.8 45.6 31.6 63.8 52.2 40.8 45.8 62 102.2 62 172.2 0 99.8-7.4 202-16.2 229.2s-27 49-61.4 49h-356.8c-34.2 0-52.4-22-61.2-49s-16.2-129.6-16.2-229.4c0-70.2 21.2-126.4 61.8-172.2 18.2-20.6 39.8-38.2 63.6-52 16.4-9.6 33.8-17.2 52-23.2 2.6-0.6 4.6-1.2 7.2-2.2 24.4-9.2 37.2-33.4 37.2-61v-189c0-21.4-5.8-38-22.2-49.6-5.6-4.2-12.6-8.6-28.6-13-63-17.2-93.8-31.2-98.4-34.4-4-2.8-9-7-9-14 0-3.2 85-6 175-6 5.6 0 11.4 0 17.2 0 5.8 0 11.4 0 17.2 0 90 0 174.8 2.8 174.8 6 0 7-5 11.2-9.2 14-4.6 3.2-35.6 17.2-98.8 34.4-16 4.4-24.4 8.8-30 13-16.2 11.6-24 28.2-24 49.6v189c0 27.6 14.8 51.8 39.2 61zM512 420c-50.8 0-97 20-131 52.6-5.4 4.8-10.4 10-15.2 15.4-31.2 35-45.8 76.2-45.8 129.6 0 108.2 8.6 194 13.2 209.8 0.6 2 1.4 4.8 1.8 4.8h354c0.6 0 1.2-2.6 1.8-4.8 4.6-15.8 13.2-101.2 13.2-209.4 0-53.4-14.6-94.6-45.8-129.8v0 0c-4-4.4-8-8.6-12.4-12.8-34.2-34.2-81.6-55.4-133.8-55.4zM672.4 619.4c0 31.4-4.8 92.4-6.2 117.6-5.6 7.4-14.4 12.4-23.4 12.8-1 0-2.6 0-3.6 0-2-0.2-4-0.6-5.6-1.2-15.6-6.2-25.6-7.8-38.2-9.6-15-2.2-28.4-1.8-40.8 0-54 8.2-89 45.4-167 24.2 0 0-17.6-7.2-26-20l-3.6-5.2c0-2 0-1 0-1-2-25.4-6.2-86.6-6.2-118.2 0-21.8 3-41.2 9-58.8 6.2-18.2 16-34.6 29.2-49.4 4-4.6 8.2-8.8 12.8-12.8 28.4-27.2 67-44 109.4-44 43.6 0 83 17.6 111.8 46.2 3.6 3.4 7 7 10.4 10.6v0 0c13.2 14.8 22.8 31 29 49.2 6 18 9 37.4 9 59.6zM623.6 570.2c-3.2 0-6.2 1-8.8 2.6-4.4 2.8-7.2 7.8-7.2 13.4v52c0 8.8 7.2 16 16 16s16-7.2 16-16v-52c0-8.8-7.2-16-16-16zM638.6 681c-2.4-3.6-6-6-10.2-7-4.2-0.8-8.6 0-12 2.2-3.6 2.4-6 6-7 10.2-0.8 4.2 0 8.6 2.2 12 2.4 3.6 6 6 10.2 7 4.2 0.8 8.6 0 12-2.2 3.6-2.4 6-6 7-10.2 1-4 0.2-8.4-2.2-12z" />
-<glyph unicode="&#xe74f;" d="M864 480h-160c-17.6 0-32-14.4-32-32s14.4-32 32-32h160c17.6 0 32 14.4 32 32s-14.4 32-32 32zM352 448c0 17.6-14.4 32-32 32h-160c-17.6 0-32-14.4-32-32s14.4-32 32-32h160c17.6 0 32 14.4 32 32zM512 288c-17.6 0-32-14.4-32-32v-160c0-17.6 14.4-32 32-32s32 14.4 32 32v160c0 17.6-14.4 32-32 32zM512 832c-17.6 0-32-14.4-32-32v-160c0-17.6 14.4-32 32-32s32 14.4 32 32v160c0 17.6-14.4 32-32 32zM650.6 528c8.8-15.4 28.4-20.6 43.8-11.8l138.6 80c15.4 8.8 20.6 28.4 11.8 43.8s-28.4 20.6-43.8 11.8l-138.6-80c-15.4-9-20.6-28.4-11.8-43.8zM373.4 368c-8.8 15.4-28.4 20.6-43.8 11.8l-138.6-80c-15.4-8.8-20.6-28.4-11.8-43.8s28.4-20.6 43.8-11.8l138.6 80c15.4 9 20.6 28.4 11.8 43.8zM635.8 297.8c-8.8 15.4-28.4 20.6-43.8 11.8s-20.6-28.4-11.8-43.8l80-138.6c8.8-15.4 28.4-20.6 43.8-11.8 15.4 8.8 20.6 28.4 11.8 43.8l-80 138.6zM363.8 768.8c-8.8 15.4-28.4 20.6-43.8 11.8-15.4-8.8-20.6-28.4-11.8-43.8l80-138.6c8.8-15.4 28.4-20.6 43.8-11.8s20.6 28.4 11.8 43.8l-80 138.6zM592 586.6c15.4-8.8 34.8-3.6 43.8 11.8l80 138.6c8.8 15.4 3.6 34.8-11.8 43.8-15.4 8.8-34.8 3.6-43.8-11.8l-80-138.6c-8.8-15.4-3.6-35 11.8-43.8zM432 309.4c-15.4 8.8-34.8 3.6-43.8-11.8l-80-138.6c-8.8-15.4-3.6-34.8 11.8-43.8 15.4-8.8 34.8-3.6 43.8 11.8l80 138.6c8.8 15.4 3.6 35-11.8 43.8zM832.8 299.8l-138.6 80c-15.4 8.8-34.8 3.6-43.8-11.8-8.8-15.4-3.6-34.8 11.8-43.8l138.6-80c15.4-8.8 34.8-3.6 43.8 11.8 8.8 15.4 3.6 34.8-11.8 43.8zM191.2 596.2l138.6-80c15.4-8.8 34.8-3.6 43.8 11.8s3.6 34.8-11.8 43.8l-138.6 80c-15.4 8.8-34.8 3.6-43.8-11.8-8.8-15.4-3.6-34.8 11.8-43.8z" />
-<glyph unicode="&#xe750;" d="M114 442v1c0 0.4 0 0 0 0.6v3.6c0 2.4 0 4.6 0 7 0.2 4.6 0.4 9.4 0.8 14 0.6 9.2 1.8 18.6 3 27.8 1.4 9.4 3.2 18.4 5 27.6 2 9 4.2 18 6.8 27 10.4 35.6 25.8 69.8 45.4 100.8 39.2 62.4 95.2 112 157.6 144 15.4 7.8 31.4 14.6 47.6 20.4 16.2 5.6 32.6 10.2 49 13.8 16.4 3.4 32.8 6 49.2 7.4 4 0.2 8.2 0.6 12.2 0.8 2 0.2 4 0.2 6 0.4l5.8-0.2c3.8 0.2 8.4 0 12.6 0h2.2c0 0 0 0 0.2 0s0.4 0 0.4 0h3c2 0 4 0 6 0 64-1.8 123-19 171.6-45.4 12.2-6.6 23.6-13.8 34.6-21.2 11-7.6 21.2-15.4 30.8-23.6 19.2-16.4 35.6-33.6 49.8-51.2 28.2-35 46.6-70.2 58.8-100 12.2-30 18.2-54.8 21.8-71.8 0.8-4.2 1.8-8.2 2.2-11.2 0.6-3.2 1-5.6 1.4-8.2 0.8-4.8 1.2-7.2 1.2-7.2 2.8-17.2 18.8-28.8 34.8-25.8 17 2.6 28.6 18.4 26 35.4 0 0-0.4 2.4-1.2 7.2-0.2 2.2-1 5.6-1.6 9.4-0.8 3.8-1.6 8-2.6 13-4.2 19.4-11.2 48-25.4 82.4s-35.8 74.8-68.8 115c-16.4 20-35.8 40-58.2 58.8-11.2 9.2-23.2 18.4-35.8 27-12.8 8.6-26.2 16.6-40.4 24.2-28.4 15.2-59.6 27.8-93 36.6-33.6 8.8-69 14.4-105.6 14.4-2.2 0-4.6 0-6.8 0h-7c-4.4 0-8.4-0.2-13.4-0.4-2.4-0.2-4.8-0.2-7.2-0.4-2.4 0-4.6-0.2-7-0.4-4.6-0.2-9.4-0.8-14-1.2-18.6-1.8-37.4-5-56-9.2-18.6-4.4-37.2-10-55.6-16.6-18.4-6.8-36.4-14.8-54-24-70.4-36.8-133.2-93.8-176.6-164.8-21.8-35.4-38.8-74.2-49.8-114.6-2.8-10-5-20.4-7.2-30.6-2-10.2-3.8-20.6-5-31-1.2-10.4-2.2-21-2.8-31.4-0.4-5.4-0.6-10.6-0.6-15.8 0-2.6 0-5.2 0-7.8v-4-2.2-1.8l0.2-7.4 0.8-16 0.6-7.8c1-10.4 2.2-20.8 3.8-31.2 1.6-10.4 3.6-20.6 6-30.8 1.2-5 2.6-10.2 3.8-15.2 1.4-5 2.8-10 4.4-15 12.2-40 30-78 52.6-112.4 22.6-34.6 49.6-65.6 80-92.2 30.4-26.8 63.8-48.8 99-66 35-17.2 72-29.4 108.8-36.8 36.8-7.2 73.8-10 109.4-8.2 36 1.6 70.4 7.6 102.6 16.8 32.2 9.2 62.2 22 89.4 37s51.6 32.2 73 50.6c21.4 18.4 37.8 37.8 53.6 57.2 31.4 39.2 48.6 77.6 60.8 111.2 6.4 17.4 8.8 25.4 12.4 41.2 4.2 19.2 6.2 32.2 6.6 48 0.4 12.4-0.4 21.4-0.4 21.4-0.8-4.6-2.4-17.2-7.8-33.8-6.2-19.2-12.4-33-27.2-65.6-7.2-15.6-17-35-27.8-52.2s-21.8-35.2-37.2-52.8c-15.4-17.6-31.2-35.2-51.8-51.6-10.4-8.2-21.2-16-32.8-23.6-11.4-7.6-23.6-14.6-36.4-21.2-12.8-6.6-26-12.6-40-18-14-5.2-28.4-10-43.4-14-29.8-7.8-61.6-12.6-94.2-13.4-33-1-66.6 2-100.2 9.2-33.4 7.4-66.8 19-98.4 35.2-31.8 16.2-61.8 36.6-88.8 61.2-27 24.4-51 52.8-70.8 84.2s-35.2 65.6-45.6 101.6c-1.2 4.6-2.4 9-3.6 13.6-1.2 4.4-2.2 9-3.2 13.6-2 9-3.4 18.4-4.8 27.6-1.4 9.4-2.2 18.6-3 28l-0.4 7-0.2 3.6v3.4 6.8 7.4 1.8z" />
-<glyph unicode="&#xe751;" d="M576 640c0-35.4-28.6-64-64-64v0c-35.4 0-64 28.6-64 64v192c0 35.4 28.6 64 64 64v0c35.4 0 64-28.6 64-64v-192zM512 320c-35.4 0-64-28.6-64-64v-192c0-35.4 28.6-64 64-64s64 28.6 64 64v192c0 35.4-28.6 64-64 64v0zM896 512h-192c-35.4 0-64-28.6-64-64s28.6-64 64-64h192c35.4 0 64 28.6 64 64s-28.6 64-64 64v0zM320 512h-192c-35.4 0-64-28.6-64-64s28.6-64 64-64h192c35.4 0 64 28.6 64 64s-28.6 64-64 64v0zM693 538.6c-25-25-65.6-25-90.6 0v0c-25 25-25 65.6 0 90.6l135.8 135.8c25 25 65.6 25 90.6 0v0c25-25 25-65.6 0-90.6l-135.8-135.8zM421.4 357.4c-25 25-65.6 25-90.6 0l-135.8-135.8c-25-25-25-65.6 0-90.6s65.6-25 90.6 0l135.8 135.8c25 25.2 25 65.6 0 90.6v0zM828.8 221.8l-135.8 135.8c-25 25-65.6 25-90.6 0s-25-65.6 0-90.6l135.8-135.8c25-25 65.6-25 90.6 0s25 65.6 0 90.6v0zM421.4 629l-135.8 135.8c-25 25-65.6 25-90.6 0s-25-65.6 0-90.6l135.8-135.8c25-25 65.6-25 90.6 0s25 65.6 0 90.6v0z" />
-<glyph unicode="&#xe752;" d="M640 768c0-70.692-57.308-128-128-128s-128 57.308-128 128c0 70.692 57.308 128 128 128 70.692 0 128-57.308 128-128zM288 448c0-53.019-42.981-96-96-96s-96 42.981-96 96c0 53.019 42.981 96 96 96 53.019 0 96-42.981 96-96zM752 672c0-8.837-7.163-16-16-16s-16 7.163-16 16c0 8.837 7.163 16 16 16 8.837 0 16-7.163 16-16zM360.2 744.8c-39.8 40.2-104.4 40.2-144.2 0-39.8-40.2-39.8-105.4 0-145.6 39.8-40.2 104.4-40.2 144.2 0 39.8 40.2 39.8 105.4 0 145.6zM864 448c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32 17.673 0 32-14.327 32-32zM786 222c0-26.51-21.49-48-48-48s-48 21.49-48 48c0 26.51 21.49 48 48 48 26.51 0 48-21.49 48-48zM576 128c0-35.346-28.654-64-64-64s-64 28.654-64 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64zM368 224c0-44.183-35.817-80-80-80s-80 35.817-80 80c0 44.183 35.817 80 80 80 44.183 0 80-35.817 80-80z" />
-<glyph unicode="&#xe753;" d="M752.4 384c0-0.2 0-0.4 0-0.8 0 0.4 0 0.6 0 0.8v0zM272.4 384c0-0.2 0-0.4 0-0.8 0 0.4 0 0.6 0 0.8v0zM544 862.4c0 0.6 0 1 0 1.6 0 17.6-14.4 32-32 32-17.6 0-32-14.4-32-32 0-0.4 0-1 0-1.4-232.6-16-416-206.2-416-442.8 0-7.2 0.4-28.4 0.8-35.6 5.4 52.6 49.4 103.4 103.4 103.4 57.4 0 103.8-46.2 104.2-103.4v0c0.4 57.2 46.8 103.4 104.2 103.4 53 0 101.8-42.2 103.4-91v-268.6c0-35.8-28.2-64-64-64-34.2 0-62 28.8-62 64 0 17.6-14.4 32-32 32s-32-14.4-32-32c0-70.6 56.6-128 126-128 34.6 0 67 13.4 91 37.6 23.8 24 37 56.2 37 90.4v270.6c6.6 65.4 46.8 88.8 104.2 88.8 57.4 0 103.8-46.2 104.2-103.4v0c0.4 57.2 46.8 103.4 104.2 103.4 52.2 0 95.2-53.4 102.8-103.4 0.2 5.6 0.4 18.2 0.4 23.6 0.2 236.8-183.4 437.8-415.8 454.8z" />
-<glyph unicode="&#xe754;" d="M525.4 826.2c0 23.4 2.8 42.6 9.2 69.8-37.8-17.2-85.4-67-85.4-123.2 0-96.6 112.6-97.4 112.6-169.6 0-31.6-9.8-65-19.2-91.2 57.2 25.2 97.4 82.8 97.4 138.2 0 75.8-114.6 112.8-114.6 176zM370.2 700.4c0 14 2 25.6 6.4 42-25.8-10.2-56.6-40-56.6-73.6 0-58 75-58.6 75-102 0-19-4.6-39-11-54.8 39 15.2 64.4 49.6 64.4 82.8 0 45.6-78.2 67.8-78.2 105.6zM766.2 381.2c1.2 10.8 1.8 20 1.8 27.6 0 39.2-6.6 39.4-32 39.4h-576c-25.4 0-32-0.2-32-39.4s15.4-122.6 56.6-222 88.8-143.2 122.4-172.4l0.2 0.4c10.2-9.2 23.6-14.6 38.4-14.6h204.8c14.8 0 28.2 5.4 38.4 14.6l0.2-0.4c18 15.6 40 35.6 62.8 65.8 9.4-4 19.6-7.4 30.8-10 16.8-4 33.6-6 49.6-6 48 0 91.2 18.4 121.6 51.6 26.8 29.2 42.2 68.8 42.2 108.4 0 77.8-56 142.8-129.8 157zM732.2 127.6c-17.2 0-31.2 2.4-44.2 8.4 0 0 0 0 0 0 8 16 15.8 31.8 23.4 50.2 20.2 48.8 34.2 94 43.2 131.6 44-8.6 77.4-47.6 77.4-94.2 0-45.4-34.4-96-99.8-96z" />
-<glyph unicode="&#xe755;" d="M793.4 697.2c-0.2 0.2-0.4 0.2-0.6 0.4-1.2 0.4-2.2 1-3.2 1.4 0 0 0 0-0.2 0-84.8 36.4-178.6 57-277.4 57-98.8 0-192.6-20-277.4-56 0 0-0.2 0-0.2 0-1.2-2-2.4-1.6-3.8-2.2-0.2 0-0.2-0.2-0.2-0.4-9.6-5-16.2-14.8-16.2-26.2 0-3.6 0.6-7.2 2-10.2v-0.2l295.8-660.8 295.2 659.8c1.6 3.6 2.4 7.4 2.4 11.6 0 11-6.6 20.8-16.2 25.8zM494.6 724c7.6 4.4 17.4 1.6 21.8-6 0.2-0.4 6.8-11.6 18.6-19 14.2-9.2 29.6-9 47 0.8 7.6 4.4 17.4 1.6 21.8-6 4.4-7.6 1.6-17.4-6-21.8-28-15.8-56.8-15.4-81.4 1-17.4 11.8-26.8 27.6-27.6 29.4-4.6 7.4-2 17.2 5.8 21.6zM320 639.8c0 35.4 28.6 64 64 64s64-28.6 64-64-28.6-64-64-64-64 28.8-64 64zM427.6 437.2c-0.6-8.8-8.4-15.4-17.2-14.8s-15.4 8.4-14.8 17.2c2.4 32 18.8 55.8 46.2 67 19.4 8 37.8 6.8 39.8 6.6 8.8-0.6 15.4-8.4 14.8-17.2-0.6-8.8-8.4-15.4-17-14.8-0.4 0-13.4 0.8-26.2-4.8-15.8-6.4-24-19.4-25.6-39.2zM536.2 169.8c-18.6-10-36.8-10.8-38.8-10.8-8.8-0.2-16.2 6.6-16.4 15.6-0.2 8.8 6.6 16.2 15.4 16.4 0.4 0 13.4 0.6 25.6 7.4 14.8 8.4 21.6 22 21 42-0.2 8.8 6.6 16.2 15.6 16.4 8.8 0.2 16.2-6.6 16.4-15.6 1-32-12.8-57.4-38.8-71.4zM512 281.8c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64zM640 511.8c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64zM847.4 828.2c-1.2 0.6-2.4 1.8-3.6 1.8-0.2 0-0.2 0-0.2 0-101.4 42-213.6 66.2-331.6 66.2-117.8 0-230.2-23.8-331.6-66.6v0c-1.4-0.6-2.6-1.2-4-1.8 0 0 0 0-0.2 0-9.6-5-16.2-14.8-16.2-26 0-3.4 0.6-6.8 1.8-10 0.2-0.8 0.4-1.4 0.8-2l13.2-31.8 2-4.8c5-9.8 15.4-16.4 27.6-16.4 4.2 0 8.4 0.8 12 2.4 0.4 0.2 1 0.4 1.4 0.6 89.8 38 189 59.2 293.4 59.2 104.4 0 203.6-21.2 293.4-59.2 0.4-0.2 1-0.4 1.4-0.6 3.6-1.6 7.6-2.4 12-2.4 12 0 22.4 6.6 27.4 16.2l2.2 5.2 13 31.6c0.4 0.6 0.6 1.2 0.8 2 1.2 3.2 1.8 6.6 1.8 10-0.2 11.4-7 21.4-16.8 26.4z" />
-<glyph unicode="&#xe756;" d="M256 448l256-448 256 448zM805 614.8c-1.6 0.8-3 1.6-4.6 2.6-8.8 5.6-16.8 17-17.4 25.4l0.2 1.4c6.4 18 10 38.4 10 59.6 0 106.2-86 192.2-192.2 192.2-62.8 0-118.4-30-153.6-76.6 0 0-18.2-28-21.6-58 0 0 2.2 38.8 8.4 63-14.8 5-30.8 7.6-47.2 7.6-83.4 0-151.2-67.6-151.2-151.2 0-12.8 1.6-25.2 4.6-37 0-0.8-0.2-1.4-0.4-2-1.8-10.2-8-19-16.8-24.6-1.4-1-3-1.8-4.4-2.6-16.4-10-27-27.2-27-46.8 0-30.8 27-56 59.8-56h520.4c32.8 0 59.6 25 59.6 56 0.4 19.6-10.4 37-26.6 47z" />
-<glyph unicode="&#xe757;" d="M640 640c0 128-53 256-128 256s-128-128-128-256v0c1.8-50 31.4-108.6 73.2-128.6 1-0.4 1.8-0.8 2.8-1.2 0 0 0 0 0.2 0 6.8-3.8 19.6-11 19.6-19.4 0 0-32-397.4-32-420.2s10-41 21-52c11-11 26.2-18.4 42.6-18.4 0.2 0 0.2 0 0.4 0 0.2 0 0.2 0 0.4 0 16.4 0 31.6 7.4 42.8 18.4 11 11 20.6 25.8 20.6 52s-32 420.2-32 420.2c0 8.4 12.8 15.8 19.6 19.6l3.4 1.8c43.2 19.8 73.4 75.8 73.4 127.8" />
-<glyph unicode="&#xe758;" d="M563.4 510.4l3.4 1.6c43.2 20 73.2 64.6 73.2 116 0 86.4-29.8 186.4-47.8 267.4v0.6h-16.2l-0.4-233.8c0-12.2-5.8-22.2-18-22.2-11.4 0-16 8.6-17.2 19.8-0.2 0.8 0 1.6 0 2.4 0 0 0-0.2 0-0.2l-20.6 234h-16l-18-234-0.2-2.2c-1.2-11.2-7.4-19.8-19-19.8-12.2 0-18.2 10-18.2 22.2l-0.6 233.8h-16c-17.8-81-47.6-181.8-47.6-268.2 0-51.4 29.8-95.8 73.2-116.4 1-0.4 1.8-0.6 2.8-1.2 0 0 0 0 0.2 0 6.8-3.8 19.6-11 19.6-19.4 0 0-32-397.4-32-420.2s10-41 21-52c11-11 26.4-18.4 42.8-18.4 0.2 0 0.2 0 0.4 0 0.2 0 0.2 0 0.4 0 16.4 0 31.6 7.4 42.8 18.4 11 11 20.6 25.8 20.6 52s-32 420.2-32 420.2c-0.2 8.2 12.6 15.8 19.4 19.6z" />
-<glyph unicode="&#xe759;" d="M576 567v311.2c0 10-1 17.8-4.6 17.8-8.4 0-12-2.8-16-7.6-37.6-45.8-107.4-160.6-107.4-428.6 0-78.4 48.8-90.4 46.8-150.8 0-0.2 0-0.6 0-0.8-3.8-94.2-12.4-210.4-14.6-248.8 0-0.6 0 0.6 0 0-0.8-30.4 19-59.6 47.8-59.6 0.2 0 0.2 0 0.4 0 0 0 0.2 0 0.4 0 29 0 48 29 47.2 59.4 0 0.6 0 1.2 0 1.8-0.2 0.2 0 486.6 0 506z" />
-<glyph unicode="&#xe75a;" d="M681 706c1.2 0.6 2.6 1.2 3.8 1.8 1.2 0.6 2.6 0.6 2.6 0.6s1.6 0 2-1.6c1-4.4 1.6-8 2.2-12.6 0.4-2.4 1.4-4.6 3-6.4 2.4-2.8 5.4-3.8 9.2-3.4 2.4 0.2 4.8 1.2 7 2.4 3.4 1.8 6.4 4.2 9.4 6.8-0.4 1.2-0.6 2.4-0.8 3.6-2.4 8.2-6.4 15.8-12.4 22-2.8 2.8-5.8 5.2-9.6 6.8-1.4 0.6-2.6 1.4-3.6 2.6-1 1-1.8 2.2-2.6 3.2-0.8 1-1.8 2-2.8 2.8-0.4 0.4-1.2 0.8-1.8 1-2.6 0.4-4.8-0.4-6.6-2.2-0.8-1-1-2-0.4-3.2 1-2 1.4-4.2 2-6.4 0.2-0.4 0.2-1 0.2-1.6-0.8-0.6-1.6-1.4-2.6-2-0.8-0.6-1.6-1.2-2.6-2-1-0.6-1.8-1.4-2.6-2-0.8-0.6-1.8-1.2-2.4-2-1.4-1.2 4.4-10.2 6.8-9.4 1.4 0.6 1.4 0.6 2.6 1.2zM569.8 766.6c2.4-2.2 5-4 8.2-4.8 5-1.4 10-2.4 15.2-3 0.6 0 1.2 0 1.8 0 0.2 0.6 0.4 1 0.4 1.4 0.6 2.2 1.4 4.4 2 6.6 0.2 1 0.6 1.8 1.6 2.4 0.6 0.4 1 0.8 1.6 1.2 3 3 3 5.8 0 8.8-2 2-4.4 3.4-7 4.4-0.6-0.2-1-0.2-1.4-0.4-7-2.6-13.8-5.2-20.8-7.8-0.4-0.2-0.8-0.2-1.2-0.4-2.2-1-3.2-3.8-2.2-6 0.6-1 1.2-1.8 1.8-2.4zM332.6 604.2c1.2 0 2.6 0.4 3.6 0.8 1.4 0.6 1.8 2 1 3.2-0.4 0.4-0.8 1-1.2 1.2-0.8 0.4-1.6 0.8-2.4 1-1.4 0.4-2.8 0.6-4.2 0.8-3 0.4-6 0.6-9 0.8-4.4 0.2-8.4 1.6-11.8 4.4-0.8 0.6-1.6 1.2-2.4 1.8-0.6 0.6-1.4 1-2.2 1.4-2 1.2-4.2 2-6.6 1.8-1.4-0.2-3-0.2-4.4-0.6-1.6-0.4-3.2-1-4.6-2-2-1.6-4.4-6-4.4-6.8s0.4-1.6 1-1.8c1.2-0.4 2.4-1 3.6-1.2 1.8-0.4 3.8-0.6 5.6-1 9-1.6 18.2-3.2 27.4-4 3.8 0.2 7.4 0 11 0.2zM352.6 589.2c-2 1.2-4 2.6-5.8 3.8-0.6 0.4-1.6 0.6-2 0.6s-1-0.2-1.6-0.4c-5-2.2-10-4.6-14.8-6.8-1.2-0.6-2.4-1.2-3.6-1.8-0.4-0.2-1-0.8-1.4-1.2-0.4-0.4-0.2-1 0.2-1.2 0.6-0.2 1.4-0.6 2-0.6 2.4-0.4 5-0.2 7.4-0.2 2.2 0 4.6 0.2 6.8 0.2 5 0 9.6-1 14-3.4 0.6-0.2 1.2-0.6 1.8-0.8 0.6-0.2 1 0.2 1.4 0.6 0.2 0.2 0.2 0.4 0.4 0.8 0.8 2.6 1.4 5.8 1 6.8s-1.2 1.8-2.4 2.2c-1.2 0.2-2.4 0.8-3.4 1.4zM512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448 448 200.6 448 448-200.6 448-448 448zM240.4 176.4c-72.4 72.6-112.4 169-112.4 271.6 0 72.4 20 141.8 57.2 201.8 0.2-0.2 0.2-0.6 0.4-0.6 0.4-0.2 0.6-0.6 0.8-0.8 0.4-0.2 0.6-0.4 1-0.6-0.2-1.2-0.2-2.4-0.4-3.6-0.8-6.6-1.8-13-2.6-19.6-0.6-4 0.2-7.8 1.8-11.4 1.2-2.8 3-5.4 5.2-7.8 2.6-3 5.6-5.4 8.8-7.6 5.4-3.8 11.2-6.6 17.2-9 0.6-0.2 1-0.4 1.8-0.6-0.2-2.8-0.6-5.4-1-8-0.4-2.6-1-4-0.8-6.2 0.2-1.4 0.6-2.8 1.2-3.2 3.2-2.8 6.4-5.8 9.8-8.6 1-0.8 2.2-4.8 2.4-6 1.6-7 2.6-10.6 4.4-17.6 0.2-1.2 0.8-2.2 1.8-2.8 3.6-2.6 7-5.4 10.4-8 0.6-0.4 1.4-1 2-1.2 3.4-1.8 5.4-4.4 6.4-8 0.6-2.2 0.8-4.4 0.8-6.8 0-4.4-1-8.4-2.2-12.6-0.8-3-2.2-5.8-3.8-8.2-2.6-3.6-5-7.2-7.6-10.8-3.2-4.4-6.4-9-9.4-13.4-1.2-1.6-2.2-3.6-3.2-5.2-2.4-3.8-3.4-7.8-4-12.2-0.6-5-0.8-9.8-0.4-14.8 0.4-4.6 1.2-9 2.8-13.2 0.4-1 0.4-1.8 0.2-3-1-4.6-0.4-8.8 1.4-13 1-2.6 2.4-5 4-7.2 1.8-2.4 3.6-4.6 5.4-7 3-3.6 5.8-7 8.6-10.8 6-8 13.4-14.4 21.6-19.8 0.6-0.4 1.2-0.8 2-1.2-0.2-0.6-0.2-1-0.4-1.6-1.2-3.6-2-7.4-2-11.4-0.2-5.6 1-10.8 4.2-15.4 1.4-2 2.4-3 5.4-5.4 0.2-0.8 0-1.6-0.2-2.6-0.8-6.4-1.8-12.8-2.6-19.2-0.4-3.4-0.8-6.8-1.4-10.2-0.2-1.4-0.4-2.8-0.8-4-1.4-4.8-2.4-9.6-3-14.4-0.2-3.2-0.4-6.2 0.2-9.4 0.4-2.6 1.4-5.2 3.4-7.2-0.2-1.6-0.4-3.2-0.6-4.8-0.6-5.2-1.4-10.2-2-15.4-0.4-2.4-0.8-4.6-1.2-6.8-0.8-5.2-1.2-10.4-1-15.6 0.2-2.8 0.4-5.4 1.2-8 0.6-2.2 1.4-4.4 2.8-6.2 0.4-0.4 0.6-1 0.6-1.6 1-6.8 1.8-13.4 2.8-20.2 0.6-4.2 1.2-8.6 1.8-12.8 0.2-0.8 0.4-1.4 0.6-2 4.8-8.2 6.8-19 13-26.2 3.8-4.4 9.4-9.6 14-13 1.6-1.2 4.2-4.2 7-7-26.2 15.8-50.8 35-73.4 57.4zM869.2 565.8c-3.6 0.8-7.2 1.2-10.8 1.4-6 0.4-12.2 0.6-18.2 0.2-0.4 0-0.8 0-1.2 0-1.2-0.2-2.2 0.2-3 1-9.2 7.2-18.4 14.2-27.6 21.4-1.2 0.8-2.2 1.6-3.4 2.6-1.4 1-2.8 1.8-4.4 2.4-3.6 1.2-7.2 1.8-11 2.4-5.6 0.6-11 0.6-16.6 0.4-1.4 0-2.6 0.2-3.8 0.6-5 2-10.4 3.4-15.8 4.2-5 0.8-10 1-15.2 0.8-5.6-0.2-11.2-1-16.6-2.8-7.2-2.2-14.4-4.4-21.6-6.6-1.2-0.4-2.2-1-3-2-5-6-10-11.8-14.8-17.8-0.8-0.8-1.6-1.4-2.6-1.6-13.6-3.2-23.6-11-30-23.6-0.6-1.4-1.2-2.6-1.8-4-0.4-0.8-0.6-1.6-0.8-2.4-0.4-1.2-0.2-2.4 0.4-3.6 0.2-0.2 0.2-0.4 0.4-0.8 1-1.8 1.4-3.6 1.4-5.6 0.2-3.2-0.2-6.4-0.6-9.6-0.6-4-1.4-8-2.6-11.8-3-9.6-5.2-19.2-7-29-1.4-7.4-2.4-15-2.2-22.6 0-3.6 0.4-7 1.2-10.4 0.2-0.8 0.6-1.8 0.8-2.6 0.2-0.8 0.8-1.4 1.4-2 6.8-6.6 13.4-13.2 20.4-19.4 6.2-5.6 12.6-10.8 19.6-15.4 5.2-3.4 10.8-6.4 16.6-8.6 6.4-2.4 13-3.4 19.8-2.8 7 0.6 14 1 21.2 1.2 5 0.2 10 0 15-1 1.6-0.4 3.2-0.8 4.8-1.6 1.8-0.8 3.4-2 4.6-3.8 0.2-0.4 0.4-0.6 0.8-1 1.2-1.4 2.8-2 4.6-1.6 1 0.2 2 0.6 2.8 1 1 0.4 2 0.8 3 1.4 0.8 0.4 1.6 0.6 2.4 1 2 0.6 3.4 0 4.2-2 0.4-1.2 0.8-2.4 1-3.6 1.2-5 1.8-10 1-15.2-0.4-3.6-1.4-7-2.6-10.4-1.2-3.4-2.6-6.6-3.8-10-1-2.4-1.8-5-2.6-7.6-2.2-6.8-2.2-13.8-0.2-20.6 1-3.6 2.4-7 3.6-10.6 1.4-3.6 2.6-7.2 3.4-11 1.4-6.2 0.8-12.2-1.6-18-1.6-4.2-3.8-7.8-6.8-11.2-2.2-2.4-4.4-4.8-6.6-7.2-0.8-0.8-1.6-1.8-2.4-2.6-3.4-3.8-6.4-7.8-8.6-12.4-1.8-3.6-3.6-7.4-5-11.2-2-5.6-2.4-11.2-1.2-17 1-4.4 2-8.8 2.8-13.2 0.6-2.8 1-5.6 1.4-8.2 0.2-1.4 0.2-3-0.2-4.4-0.6-2.4-1.4-4.6-2.4-7-2.4-6.2-5.4-12-8.2-18-3.2-6.6-6.2-13.2-9.2-19.8-1.4-3.2-2.6-6.6-3.6-10-0.4-1.4-0.6-3-0.8-4.6-0.2-2 1.2-4.4 3.2-5.6-63.6-44-139-67.8-218-67.8-65.4 0-128.2 16.2-183.8 46.8 0 0.6-0.2 1.2-0.2 1.8-2.4 13-7.2 38-9.6 50.8-0.2 1.4-0.4 3-0.4 3.8s0.2 2.8 0.6 3.6c2 4.2 3.4 7.6 5.4 11.8 1.8 3.8 3.4 7.6 5.2 11.4 0.6 1.2 1.4 2.4 2.4 3.4 4.6 4.4 9 8.8 13.4 13 0.6 0.6 1.4 1.2 2.2 1.8 8.6 5.8 17.4 11.6 26 17.4 1.4 1 2.4 2 3.4 3.4 3.8 5.8 7.8 11.6 11.6 17.6 1.6 2.6 3 5.2 4.6 7.8 0.4 0.6 0.8 1.2 1.2 1.6 5.2 6.6 10.4 13.2 15.4 19.8 0.8 1 1.6 1.6 3 1.8 8.4 1.8 16.6 4.4 24.2 8.2 1.8 1 3.6 2 5.4 3 0.8 0.4 1.4 1 1.8 1.8 5.6 7.6 11 15.4 16.6 23 0.6 0.8 1 1.8 1.4 2.6 3.8 10.4 7.8 20.6 11.6 31 0.4 1.2 1 2 2 2.6 11 7.2 17.6 17.2 19.6 30.2 0.4 3 0.6 5.8 0.2 8.8-0.4 3-2 5.8-3.2 7.2-5.2 6.4-9.6 9.2-16.6 13.4-9 5.2-18.4 8.8-28.6 11.2-2.4 0.6-5.8 1.6-6.6 2s-1.4 0.8-1.6 1.6c-2.2 4.4-4.4 8.8-7.2 12.8-2.4 3.6-5 7-8.2 10-0.6 0.6-0.8 1.2-1 2-0.8 2.6-1.6 5.4-2.6 8-3.4 8.6-8.4 16.2-14.8 22.8-10.6 10.8-23.4 18.4-37.8 23.2-1.2 0.4-2 1-2.8 2-5.4 7.6-12.6 12.8-21 16.2-3 1.2-6 2.2-9.2 2.8-0.8 0.2-1.6 0.4-2.2 0.8-5.6 2.8-11.4 5.6-17 8.4-1 0.4-1.8 1-2.4 1.8-1.4 1.6-3.2 2.8-5 4-2.2 1.2-4.4 1.8-6.8 1.8-2.8-0.2-5.2-1.4-7.2-3.4-0.4-0.4-0.8-1-1.2-1.6-1.4-2.4-2.8-4.8-4.8-6.8-3-3-6.4-5-10.8-5.6-2.8-0.4-5.8 0-8.4 0.8-3.6 1-6.8 2.8-10 5-0.8 0.6-1.6 1-2.6 1.6-5.8 3.4-9.4 8.4-10.4 15-0.2 1.4-0.2 2.8-0.4 4.2-0.2 6.2 0.2 12.6 0.8 18.8 0.2 1.6 0.4 2.2 0.4 3.2 0 0.8-0.4 2.2-1.4 2.6-1.4 0.6-2.6 1.4-3.6 2.4-0.8 0.6-1.4 1.4-2 2.2-1.2 1.8 0.4 3 1.4 5 0.8 1.6 0 3.6 1.6 4.6 1.6 1 3.4 2.2 5 3.4 1.8 1.4 3.4 2.8 5 4.6 0.8 1 1.4 2 1.8 3.2 0.8 2.4 0.6 4.6-1 6.6-1.4 1.8-2 3.2-4.2 4.2-0.6 0.2-2.4 0-3-0.2-2.4-0.6-4.6-1.2-7-1.6-3-0.6-6.2-0.6-9.4 0.2-4 1-6.6 3.4-8.2 7.2-1 2.8-1.4 5.6-1.2 8.6 0.2 5.8 1.4 11.4 3.2 16.8 0.2 0.6 0.4 1.2 0.8 1.8 9.2 13 21.2 22.2 36.6 26.8 3.8 1 7.4 1.8 11.4 2.2 1.6 0.2 3 0 4.6-0.2 4.4-0.4 8.6-1.2 12.6-2.8 2.4-0.8 4.4-2 6.4-3.6 4.2-3.2 6.6-7.2 7-12.4 0.2-3.4 1.2-6.6 2.4-9.6 0.6-2 1.4-3.8 2.4-5.8 0.6-1.2 1.2-2.2 2-3.2 0.6-0.8 1.4-1.4 2.2-2 1.4-1 3-0.8 4.6-0.2 0.8 0.4 1.4 1 1.6 2 0.2 1.8 0.6 3.6 0.8 5.6 1.2 7.4 2.4 14.8 3.4 22 0.6 3.8 1.2 7.4 1.8 11.2 0 0.4 0.2 0.8 0.2 1.2 7.4 11 33.4 12.8 44 24.2 0.4-0.2 0.6-0.4 1-0.8 1.2-1 2.4-1.4 3.8-1.4 2-0.2 4 0.2 6 0.6 2.8 0.8 5.6 1.8 8.2 3.2 2.2 1 4.2 2.2 6.2 3.4 1 0.6 1.8 1 3 1.2 6.2 1.8 12.4 3.6 18.6 5.4 1.2 0.4 2.4 0.4 3.6 0.2 5.2-0.6 10.4-0.6 15.8 0 3.6 0.4 7 1 10.4 2 0.6 0.2 1.2 0.4 1.8 0.6 0.8 0.2 1.2 0.6 1.6 1.4 0.8 1.6 1.8 3 2.8 4.4 0.8 1.2 1.8 2.2 3 3.2 0.8 0.6 1.6 1.2 2.6 1.6 1.8 0.8 3.8 0.8 5.8 0.2 1.6-0.6 2.8-1.4 4-2.6 1-1 2-1.6 3.2-2.2 1.6-0.8 3.4-1.4 5.2-1.8 4-0.8 7.6 0.2 10.4 3 1.6 1.4 2.6 3.2 3.6 5 1.6 3 2.6 6 3.4 9.4 1 4 1.6 8 2 12.2 0 0.6 0 1.4 0 2.2-0.4-0.2-1-0.2-1.2-0.4-1.8-0.8-3.4-1.4-5.2-1.8-0.6 0-1-0.2-1.6 0-1.2 0.2-1.8 1-1.6 2.2 0.2 1 0.4 2 1 2.8 1 1.8 2 3.4 3 5.2 1.2 2 2.4 3.8 3.4 5.8 0.6 1.2 1 2.6 1 4 0.2 1.8-0.4 3.4-1.8 4.6-0.8 0.8-1.8 1.6-2.8 2.2-1.2 0.8-2.4 1.6-3.6 2.6-1.8 1.4-3.4 3-4.6 5.2-0.2 0.2-0.4 0.6-0.6 0.8-2.2 3.2-5.2 4.2-8.8 3.2-2.8-0.8-5.2-2.4-7.4-4.6-1.2-1.2-2.2-2.2-3.4-3.4-1.4-1.2-3-2.4-4.6-3.2-2.8-1.4-5.8-1.4-8.6 0-0.8 0.4-1.4 0.8-2.2 1.2-0.4 0.2-1 0.4-1.4 0.6-1.2 0.4-2 0.2-2.8-1-0.4-0.6-0.8-1.2-1-2-1-3-3-5.4-5.2-7.6-2.8-2.6-5.8-4.6-9.2-6.4-2.6-1.4-5.2-2.4-8-3.6-1-0.4-2.2-0.6-3.4-0.6-3.2 0.2-5.4 1.6-6.8 4.6-0.8 2-1.2 4-1.2 6-0.2 3.8 0.2 7.4 1 11.2 0.2 1.4 0.6 2.6 0.8 3.8 0.2 1 0.6 1.6 1.4 2 3.8 2.4 7.4 4.8 11 7.2 0.4 0.2 0.8 0.6 1.4 0.8 2.6 1.6 5 3.4 7.2 5.4 1.8 1.8 4 3.4 6.2 4.8 1 0.6 2 1 3 1.4 0.4 0.2 1 0.2 1.6 0.4 1.6 0.2 2.8-0.4 3.6-1.8 1.6-3.2 4.4-3.8 7.6-3.6 1.6 0 3.4 0.4 5 0.8 1.8 0.4 3.4 1.2 5 1.8 0.8 0.4 1.6 0.6 2.6 0.6 4 0.2 7.8 0.2 11.8 0.4 0.6 0 1.2 0 1.8-0.6 3.2-2.2 6.2-4.4 9-7 1.8-1.8 2.4-2.6 3.4-4.8 0.4 0.4 1 0.8 1.4 1.2 3.4 3 6.6 6.2 10 9.2 0.8 0.6 1.6 1.4 2.2 2 3.4 2.6 6.6 5 10 7.6 0.6 0.4 1 0.8 1.6 1.2 0.2 0.8-0.4 1.4-0.6 2-2.2 5-4.6 9.8-7 14.8-0.2 0.4-0.4 0.8-0.6 1.2 2.2 0 4.6 0 6.8 0 3.4 0 6.6 0 10-0.2 0 0 0 0 0 0 0.4-1.2 1-2.4 1.4-3.6 0.2-0.6 0.4-1.2 0-2-0.6-1.8-1.4-3.4-2-5.2-2.4-6.2-4.8-12.4-7.2-18.6-0.4-1-0.6-1.8-0.4-3 0.8-8 2.2-15.6 5.2-23.2 1.8-4.4 4-8.8 7-12.6 2.8-3.6 6.2-6.6 10.4-8.6 0.4-0.2 1-0.4 1.4-0.6 0.2 0 0.2 0 0.6 0 0.4 0.4 0.8 1 1.2 1.4 5.6 7 11.4 14 17 20.8 3.8 4.6 7.8 9 11.8 13.6 0.4 0.4 0.8 0.8 1 1.2 2 2.2 2 2.2 5 2.8 4.2 0.8 8.4 1.4 12.6 2.2 2.4 0.4 1.8 0 3 2.2 4.4 7 8.8 14 13.2 21 0.2 0.4 0.6 0.8 0.8 1.2 40.6-9.8 79-26.4 114.2-48.8-6.4-0.8-12.8-1.2-19-2-0.2-0.4-0.2-0.8-0.2-1.2-0.8-7.8-0.8-15.6 0.4-23.4 0.6-3.2 1.4-6.6 2.8-9.6 1-2.2 2.2-4 4-5.6 0.8-0.8 1.6-1.2 2.8-1.4 3.4-0.4 6.6-0.8 9.8-1.4 0.8-0.2 1.6-0.2 2.6-0.4 2.6-4.2 5-8.4 7.6-12.6 6-1 12.2-1.6 18.2-2.6 0-1.6-0.4-3-0.4-4.4-0.4-3.4-1-6.8-1.4-10-0.2-1 0-2 0.4-3.2 1.4-3 2.6-6.2 4-9.2 0.2-0.6 0.4-1 0.6-1.6-0.4-0.4-0.6-1-1-1.4-3.2-4.2-6.4-8.2-9.4-12.4-0.4-0.6-1-1.2-1.6-1.6-4.8-3-9.6-6-14.2-9-1.8 0.2-3.6 0.4-5.2 0.4-3.6 0-7.2-0.6-10.8-1.6-2.4-0.6-4.6-1.6-7-2.4-0.6-0.2-1.2-0.4-1.6-0.8-2.8-1.6-5.6-3.2-8.6-4.8-0.2-0.2-0.6-0.4-0.8-0.6 0.2-0.4 0.4-0.8 0.6-1.2 3.8-6.8 7.4-13.6 11.2-20.2 2.2-4 5.2-7.6 8.6-10.8 2.6-2.4 5.4-4.2 8.6-5.4 4-1.6 8.2-1.8 12.4-0.8 5.6 1.4 11.4 2.8 17 4.4 0.6 0.2 1 0.4 1.6 0.4 0.2 1 0.2 1.8 0.4 2.8 0.6 5 1 10 1.8 15 0.4 3 1 6 1.6 8.8 0.2 1 0.6 1.8 1 2.8 0 0.2 0.4 0.4 0.6 0.4 0.2 0 0.6-0.2 0.6-0.4 0.4-1.6 5.4 3 5.4 3s12.4 8.8 47.2-32 54.2-28.8 54.2-28.8c2.2-2.6 4-5.6 5.4-8.6 1.8-4 3-8.2 3.6-12.4 0-0.6 0-1 0-1.6-2.4 0.6-3 0.8-3.8 0.8z" />
-<glyph unicode="&#xe75b;" d="M512 896c-128 0-320-266.4-320-513.8s128-382.2 320-382.2 320 134.8 320 382.2c0 247.4-192 513.8-320 513.8z" />
-<glyph unicode="&#xe75c;" d="M65.2 448h446.8v382.8 64c-10 0.8-21.2 1.2-32 1.2-229.8 0-416-186.2-416-416 0-10.8 0.4-22 1.2-32zM219.6 155.6c76.2-94.8 193.2-155.6 324.4-155.6 229.8 0 416 186.2 416 416 0 131.2-60.8 248.2-155.6 324.4-63.4 51-142.4 83.8-228.4 90.4v-446.8h-446.8c6.6-86 39.4-165 90.4-228.4z" />
-<glyph unicode="&#xe75d;" d="M837.8 146.2c0 9.4-6.4 18-15.2 20.6l-2.4 0.6-100.8 22.6-2.2 0.6c-2 0.6-5.2 1.4-7.6 1.4-9 0-16.8-5.4-19.4-13l-3.6-9c-15.6-38.4-29-57.2-45.2-94.6 0-0.2-0.2-0.4-0.4-0.8-1-2.4-1.6-5.2-1.6-8 0-7.8 4.4-14.8 11-18.6l3.6-1.6 102.6-43.4 3.4-1.6c2.6-0.8 5.2-1.4 8-1.4 8.4 0 15.8 4.6 19.8 11.4 0 0 0.2 0.2 0.2 0.4 0.4 0.8 0.8 1.6 1 2.4 20.4 46 32.6 76.4 47.6 124.8 0 0 0 0 0 0 0.4 1 0.6 1.8 0.8 2.8 0.4 1.6 0.4 3 0.4 4.4zM512 768c148.4 0 232.6-134.2 232.6-277.2 0-91.6-7.4-132.2-27.6-218 0-0.2 0-0.2 0-0.2-0.2-1-0.4-2-0.6-2.8v-0.2c-0.2-1-0.4-2.2-0.4-3.4 0-9.2 6-17 14.4-20.2l5.2-1.2 27.6-6.2 72.4-17.4 6.2-1.4c0.8 0 1.4 0 2.4 0 10 0 18.6 6.4 21.4 15.2 0 0 0 0 0 0 0.2 0.8 0.4 1.8 0.6 2.6 22.8 95.2 30 160 30 258.8-0.2 245.2-153.2 399.6-384.2 399.6v0 0c-231 0-384-154.4-384-399.6 0-98.8 7.2-163.6 30-258.8 0.2-0.8 0.4-1.8 0.6-2.6 0 0 0 0 0 0 2.8-8.8 11.2-15.2 21.4-15.2 0.8 0 3.2 0.2 4.2 0.6l4.2 1 72.2 17.4 32.8 7.4c8.4 3.2 14.4 11 14.4 20.2 0 1.2-0.2 2.2-0.4 3.4v0.2c-0.2 0.8-0.4 1.8-0.6 2.8 0 0 0 0 0 0.2-20.2 85.6-27.6 126.4-27.6 218 0 142.8 84.4 277 232.8 277M382.8 74.6c-0.2 0.2-0.2 0.4-0.4 0.8-16.4 37.4-29.8 56.6-45.8 96l-3 7.8c-3.6 7.4-10.4 13-19.2 13-2.4 0-5.8-0.6-7.8-1.2l-2-0.4-100.6-22.8-2.6-0.8c-9-3-15.2-11-15.2-20.6 0-1.4 0.4-3 0.8-4.4l0.8-2.8c14-48.4 27.2-79 47.6-125l1.2-2.6c3.8-6.8 11-11.6 19.6-11.6 2.8 0 5.4 0.4 8 1.4l3.4 1.6 106.2 45c6.6 3.8 11 10.6 11 18.6-0.4 2.8-0.8 5.6-2 8z" />
-<glyph unicode="&#xe75e;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448 448 200.6 448 448-200.6 448-448 448zM868.6 591l-123-37.8c-12.6 28-30.2 53.6-52.6 76s-48 40-76 52.6l37.8 123c47.6-19 91.2-47.8 128.6-85 37.4-37.6 66.2-81.2 85.2-128.8zM512 256c-106 0-192 86-192 192s86 192 192 192 192-86 192-192c0-106-86-192-192-192zM240.4 719.6c37.4 37.4 81 66 128.6 85l37.8-123c-28-12.6-53.6-30.2-76-52.6-22.4-22.4-40-48-52.6-76l-123 37.8c19.2 47.8 48 91.4 85.2 128.8zM155.4 305l123 37.8c12.6-28 30.2-53.6 52.6-76s48-40 76-52.6l-37.8-123c-47.6 19-91.2 47.8-128.6 85-37.4 37.6-66.2 81.2-85.2 128.8zM783.6 176.4c-37.4-37.4-81-66-128.6-85l-37.8 123c28 12.6 53.6 30.2 76 52.6s40 48 52.6 76l123-37.8c-19.2-47.8-48-91.4-85.2-128.8z" />
-<glyph unicode="&#xe75f;" d="M608 416c0-53.019-42.981-96-96-96s-96 42.981-96 96c0 53.019 42.981 96 96 96 53.019 0 96-42.981 96-96zM608 416c0-53.019-42.981-96-96-96s-96 42.981-96 96c0 53.019 42.981 96 96 96 53.019 0 96-42.981 96-96zM960 416h-320c0-47.8-26.2-89.4-65.2-111.4l156.4-272.6c135 77.2 228.8 217.4 228.8 384zM512 544c23.4 0 45.4-6.4 64.2-17.4l161.2 276.6c-66.2 38.6-143.2 60.8-225.4 60.8-82.4 0-159.8-22.4-226.2-61.2l159.6-277.6c19.4 12 42.2 18.8 66.6 18.8zM384 416h-320c0-166.6 93.8-306.8 228.8-384l156.4 272.6c-39 22-65.2 63.6-65.2 111.4z" />
-<glyph unicode="&#xe760;" d="M877.8 167.6l-98.6 146-95.6 144.8-5.6 8.2c-25.6 40.6-38.2 88.8-38.2 140.4v148.8c0 11.4 2 26.4 4.2 37.2 3.6 19.4 8 39.8 17.4 56.4 1.2 2 2.6 4.2 4 6.2 2.8 4.8 4.8 9.6 4.8 15.6 0 17.4-14 24.8-31.4 24.8h-253.6c-17.4 0-31.6-7.4-31.6-24.8 0-6 1.6-11.2 4.6-16 1.2-2 2.6-3.8 3.8-6 9.6-16.6 16.2-36.8 20-56.4 2-10.8 2.2-25.8 2.2-37v-148.8c0-51.6-14.6-99.6-40.2-140.4l-4.6-7.6-94.6-145.4-98.4-145.8c-11.6-18-18.2-40.4-18.2-63.4 0-56 32.6-104.4 126.4-104.4h515.2c94 0 126.4 48.4 126.4 104.4-0.2 23-6.8 45.2-18.4 63.2zM818.6 78c-8.8-8.4-23.2-14-49-14h-515.2c-25.6 0-41.6 6-50.4 14.4-5.4 5.2-12 13.6-12 26.2 0 10 2.8 20 7.8 28l98 145 0.4 0.8 94.2 145 6 9.8c31.4 50.4 49.6 110.4 49.6 173.8v148.8c0 12.2 0 44.4 0 44.4 0 17.6 10.4 31.8 28 31.8h72c17.6 0 28-13.8 28-31.4 0 0 0-31.4 0-44.6v-148.8c0-62.4 15.6-122.6 47.8-174 2.6-4.2 6.4-10 6.4-10l95.6-144.2 0.4-0.8 98-145c5-8 7.8-18 7.8-28 0-12.8-8-22-13.4-27.2zM377 346v0c0 0 0 0 0 0zM783.4 136.8c-0.4 0.6-0.6 1-1 1.6l-16.8 25.8-32.8 50.2-83.2 127c-4.8 6.4-12.6 10.4-21.2 10.4-0.8 0-1.6 0-2.4 0-1.8-0.2-3.4-0.4-5-1-100.2-39.2-121.2 37-217.8 11 0 0-18.6-4.6-26-15.8-7.2-10.8-0.6-0.8 0 0l-118.6-181.6-17.2-26.2c-3-4.2-4.6-9.6-4.6-15.2 0-15 12.2-27 27-27h496.4c15 0 27 12.2 27 27 0 5-1.2 9.8-3.8 13.8zM614 268.6c-3 3-4.6 7.2-4.6 11.4 0 4.2 1.8 8.4 4.6 11.4 3 3 7.2 4.6 11.4 4.6 4.2 0 8.4-1.6 11.4-4.6 3-3 4.6-7.2 4.6-11.4 0-4.2-1.8-8.4-4.6-11.4-3-3-7-4.6-11.4-4.6-4.2 0-8.4 1.8-11.4 4.6zM708.2 150.6c-2.8-1.8-5.8-2.6-8.8-2.6-5.2 0-10.4 2.6-13.4 7.2l-47 71.8c-4.8 7.4-2.8 17.4 4.6 22.2 7.4 4.8 17.4 2.8 22.2-4.6l47-71.8c4.8-7.4 2.8-17.4-4.6-22.2z" />
-<glyph unicode="&#xe761;" d="M944 481.6v0c0 0-0.2 0 0 0l-379.8 382.2c0 0 0 0 0 0l-2.8 2.8c0 0-1 0-1 0-15 14.4-32.2 21.8-54.2 22.2v0l-187.6 6.8c-20.2-0.2-40-8.2-55.4-23.6l-54.2-54.4c14.8 13.2 33.2 20 52 20.2l7.6-0.2 179.6-6.6c22-0.4 39.4-7.8 54.4-22.2 0 0 0.8 0 1 0l2.8-2.8c0 0 0 0 0 0l379.6-382.2c0 0 0 0 0 0v0c20-21.6 21.4-56.4 0-77.8l58 57.8c21.2 21.4 20 56.2 0 77.8zM856 395c0 0 0.6 0 0.6 0l-379.4 382.2c0 0 0 0 0 0l-2.6 2.8c0 0-0.6 0-0.6 0-15 14.4-31.8 21.8-53.8 22.2v0l-188.2 6.8c-18.4-0.2-36.4-6.8-51.2-19.6-0.6-0.6-1.4-1.2-2-1.8-0.8-0.8-1.6-1.6-2.4-2.4l-88.6-89c-16.2-16.2-23.8-37.8-23.8-59 0 0 0 0 0-0.2l0.2-7.6 11.8-175.8c0-0.2 0-0.2 0-0.4v-3.4c0 0 0 0 0 0 2-15.8 8.4-31.2 19.2-44l10.2-9.8 378.2-382.4c21.4-18.8 54.2-18 74.6 2.6l26.2 26.4c1 0.8 1.8 1.6 2.8 2.6l53.8 54c-0.4-0.2-0.6-0.4-1-0.8l216.6 218.6c21.2 21.4 21.4 56.4-0.6 78v0zM221.2 681c13.2 8 28.6 12.6 45.2 12.6 47.8 0 86.8-38.8 86.8-86.8 0-16.6-4.6-32-12.6-45.2-15.2-25-42.6-41.6-74-41.6-47.8 0-86.8 38.8-86.8 86.8-0.2 31.6 16.4 59 41.4 74.2z" />
-<glyph unicode="&#xe762;" d="M942 437.2v0c0 0 0 0 0 0l-420.2 423.2c0 0 0 0 0 0l-3 3c0 0-0.8 0-0.8 0-16.6 15.8-35.8 24-59.8 24.6v0l-208.2 7.8c-22.4-0.4-44.4-9-61.4-26.2l-98.4-98.2c-18-18-26.2-41.8-26.2-65.4 0 0 0 0 0-0.2l0.6-8.4 13.4-194.6c0-0.2 0-0.4 0-0.4v-3.8c0 0 0 0 0 0 2-17.4 9-34.6 20.8-48.8l11-10.8 418.8-423.8c23.8-21 60-20 82.6 2.8l330.8 333.2c23.6 23.6 24 62.2 0 86zM288 576c-53 0-96 43-96 96s43 96 96 96 96-43 96-96-43-96-96-96z" />
-<glyph unicode="&#xe763;" d="M900 683.4l-95.4-97-5.4-5.6-3.2-3.4c-2.2-1.6-4.8-2.4-7.8-2.4-3.2 0-6.2 1.2-8.6 3.2l-7.2 7.2-90.4 92c-2 3-3.2 6.8-3.2 10.6 0 3.4 1.2 6.4 3.2 8.8l1.4 1.6 5.2 5.2 95.8 97.4c-10.2 20.2-49.4 29.8-70.2 28.2-34.2-2.6-69.4-14-105.6-51-1.4-1.6-3-3.2-4.4-4.6-49.2-53.6-59-125.6-39-191.6 1.4-2.8 2.6-6.2 3.2-9.2 2.2-11-0.8-20.4-8-27l-75.8-72.8c-23.6 24-27 27.2-27 27.2-4 4-12 6.6-19 2.4l-11.8-7.2c-45.4 46.2-64.6 64.8-70.8 87.2-6.4 23.4-0.6 54.6 5.4 66.2 5 9.2 20.6 17.8 33.8 18.8l17.2-17.6c4-4 10.2-4 14.2 0l61.8 62.8c4 4 4 10.6 0 14.6l-99.8 101.4c-4 4-10.4 4-14.2 0l-61.8-62.8c-4-4-4-10.6 0-14.6l6.6-6.8c0-9.8-1.4-25-9.4-33.2-12.4-12.6-37 2-53-9.4-15.8-11.2-35.8-29.2-48.6-42-12.6-12.8-61-63.6-95.6-149.2-34.6-85.6-8-165 10.8-185.8 10-11 28.2-22.2 25-1.4-3.2 21-8.4 93.8 15.4 123.6 23.8 29.8 55.2 54.2 96 56.2 39.2 2 61.8-11.4 112.6-63l-5.6-10.4c-3.6-6.8-1.6-15.4 2.4-19.4 0 0 3-3.2 24.2-24.8l-194.4-186.4c-32.4-28.6-30.6-81-0.6-112 30.4-30.4 82.2-32.6 110.4 0.4l182.8 197.2c98.2-104.6 186.6-214.8 186.6-214.8 4-4 10.4-4 14.2 0l99.8 101.4c4 4 4 10.4 0 14.6 0 0-110.4 91.4-214 192.4l71 76.6c6.6 7.4 15.8 10.4 26.6 8.2 3-0.6 6.2-2 9-3.4 64.8-20.4 135.6-10.4 188 39.6 1.6 1.4 3 3 4.6 4.6 36.2 36.8 47.4 72.8 50 107.6 2 21.2-7 60.6-27.4 71.6z" />
-<glyph unicode="&#xe764;" d="M820 896h-104c-6.6 0-12-5.4-12-12v-11.2c-8-8-21.8-19.6-35.6-19.6-21 0-29.6 32.8-52.2 36.8s-54.4 6-75.8 6-104-1.4-204-43c-100-41.6-143.4-129.8-144.6-162.8-0.6-17.4 5.4-42.2 20-22.2 14.6 20 70.6 84.6 115.4 89.4 44.6 4.6 91.4-1.6 127.4-34.4 34.6-31.4 42.6-61.6 42.6-147l-13.2-4c-8.6-2.6-14-11.4-14-18 0 0-0.4-13-0.4-140.8 0-189.2-21.6-401.2-21.6-401.2 0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12 0 0-21.6 212-21.6 401.2 0 127.8-0.4 140.8-0.4 140.8 0 6.6-4.6 15.6-14 18l-16 4c0 76.4-0.8 108 12.6 131.8 14 24.8 44.6 45.8 59.4 50.2 11.8 3.6 32-2.6 44-13v-29c0-6.6 5.4-12 12-12h104c6.6 0 12 5.4 12 12v168c0 6.6-5.4 12-12 12z" />
-<glyph unicode="&#xe765;" d="M512 448c-35.4 0-64 28.6-64 64v320c0 35.4 28.6 64 64 64s64-28.6 64-64v-320c0-35.4-28.6-64-64-64zM758 822.4v0c-10 6-21.6 9.6-34 9.6-35.4 0-64-28.6-64-64 0-12.4 3.6-24 9.6-33.8 4-6.4 9.2-12.2 15.2-16.8 2.4-1.8 4.8-3.4 7.4-5 16.2-11.2 31.6-23.8 46-38.2 60.6-60.4 93.8-140.8 93.8-226.2 0-85.4-33.2-165.8-93.8-226.2-60.4-60.6-140.8-93.8-226.2-93.8-85.4 0-165.8 33.2-226.2 93.8-60.6 60.4-93.8 140.8-93.8 226.2 0 85.4 33.2 165.8 93.8 226.2 14.2 14.2 29.6 27 45.8 38 2.8 1.6 5.2 3.2 7.8 5.2 6 4.6 11 10.2 15 16.6 6.2 9.8 9.6 21.4 9.6 33.8 0 35.4-28.6 64-64 64-12.4 0-24-3.6-33.8-9.6l-0.2 0.2c-121.6-80-202-217.8-202-374.4 0-247.4 200.6-448 448-448 247.4 0 448 200.6 448 448 0 156.6-80.4 294.4-202 374.4z" />
-<glyph unicode="&#xe766;" d="M576 392c110.4 28.4 192 128.6 192 248 0 141.4-114.6 256-256 256s-256-114.6-256-256c0-119.2 81.6-219.4 192-248v-136h-128v-128h128v-128h128v128h128v128h-128v136zM512 480c-88.2 0-160 71.8-160 160s71.8 160 160 160 160-71.8 160-160-71.8-160-160-160z" />
-<glyph unicode="&#xe767;" d="M960 576v320h-320l126-126-137.4-137.4c-59 44.8-132.8 71.4-212.6 71.4-194.4 0-352-157.6-352-352s157.6-352 352-352 352 157.6 352 352c0 79.8-26.6 153.6-71.4 212.6l137.4 137.4 126-126zM597 171c-48.4-48.4-112.6-75-181-75s-132.6 26.6-181 75c-48.4 48.4-75 112.6-75 181s26.6 132.6 75 181c48.4 48.4 112.6 75 181 75s132.6-26.6 181-75 75-112.6 75-181-26.6-132.6-75-181z" />
-<glyph unicode="&#xe768;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM783.6 176.4c-65-65-149.2-103.8-239.6-111.2l-16 126.8h-32l-15.8-126.6c-90.6 7.4-174.8 46.2-239.6 111.2-65 65-103.8 149.2-111.2 239.6l126.6 15.8v32l-126.6 15.8c7.4 90.6 46.2 174.8 111.2 239.6 65 65 149.2 103.8 239.6 111.2l15.8-126.6h32l15.8 126.6c90.6-7.4 174.8-46.2 239.6-111.2 65-65 103.8-149.2 111.2-239.6l-126.6-15.8v-32l126.6-15.8c-7.4-90.6-46.2-174.8-111-239.8z" />
-<glyph unicode="&#xe769;" d="M663.6 504c0 0 0 0 0 0-2.4 1-4.8 2-7 3.4-14 8-24.4 21.8-27.8 38.4l-37 235.4-0.4 11.6c0 14.2 8.2 20.4 20 26v0c1.4 0.6 2.8 1.2 4.2 1.8 14.4 6.8 24.2 15.6 24.2 32.6 0 40.2-13 42.8-36.4 42.8h-182.6c-23.4 0-36.4-2.4-36.4-42.8 0-17 9.8-25.8 24.2-32.6 1.4-0.6 2.8-1 4.2-1.8 0 0 0 0 0 0 11.8-5.8 20-12 20-26l-0.4-11.6-37-235.4c-3.4-16.6-13.8-30.4-27.8-38.4-2.2-1.4-4.6-2.4-7-3.4 0 0 0 0 0 0-39.4-20.4-72.4-61.6-72.4-109.4 0-31.8 7-42.6 30.4-42.6h161.4l24-352h16l24 352h161.6c23.4 0 30.4 9.4 30.4 42.6 0 47.8-33 89-72.4 109.4z" />
-<glyph unicode="&#xe76a;" d="M960 896l-896-384h512v-512z" />
-<glyph unicode="&#xe76b;" d="M856 658c-67-19.6-179.2-23.6-270 114-97.4 148-238.4 132-314.2 109.4-2.8-0.8-11.2-3.8-11.2-3.8-21.2-9.6-31.2-23-35.4-45-1.2-6.2-1.4-12.2-0.6-18 0-0.4 0-0.6 0.2-1l41.6-350.8c0 0 0-0.2 0-0.2l5.4-43.4c22.6-6 43 5.4 48.8 7.2 1.4 0.6 2.8 1 4.4 1.6 46.4 16.4 104.4 35 233.8-20 174.2-74 285.6 99.6 327.2 205.8 3 7.4 10.2 29.2 10.2 59.8-18.4-9.4-40.2-15.6-40.2-15.6zM255.4 0c-16 0-29.8 12-31.8 28.4l-95.4 831c-2 17.6 10.6 33.4 28.2 35.4s33.4-10.6 35.4-28.2l95.4-831c2-17.6-10.6-33.4-28.2-35.4-1-0.2-2.4-0.2-3.6-0.2z" />
-<glyph unicode="&#xe76c;" d="M662 391.8c13 13 13 34 0 46.8-13 13-34.6 13-47.6 0l-70.4-69.4v237.6c0 18.4-13.6 33.2-32 33.2s-32-14.8-32-33.2v-237.8l-70 69.6c-13 13-34.2 13-47.2 0s-13-34-0.2-46.8l126.2-126c0 0 0 0 0-0.2 1.4-1.4 3-2.8 4.8-3.8 0.2-0.2 0.4-0.2 0.6-0.4 0.6-0.4 1.4-0.8 2-1.2 0.2-0.2 0.4-0.2 0.6-0.4 0.8-0.4 1.6-0.8 2.6-1.2 0 0 0 0 0 0 0.8-0.4 1.6-0.6 2.4-0.8 0.2 0 0.4-0.2 0.6-0.2 0.4 0 0.6-0.2 1-0.2 2.8-0.8 5.8-1.2 8.6-1.2 2.8 0 5.8 0.4 8.6 1.2 0.4 0 0.6 0.2 1 0.2 0.2 0 0.4 0.2 0.6 0.2 0.8 0.2 1.6 0.6 2.4 0.8 0 0 0 0 0 0 0.8 0.4 1.8 0.8 2.6 1.2 0.2 0.2 0.4 0.2 0.8 0.4 0.6 0.4 1.4 0.8 2 1.2 0.2 0.2 0.4 0.2 0.6 0.4 0.8 0.6 1.6 1.2 2.4 1.8 0 0 0 0 0 0 0.8 0.6 1.6 1.4 2.4 2.2 0 0 0.2 0 0.2 0.2l126.4 125.8zM672 224c-8.2 0-16.4 3.2-22.6 9.4-12.4 12.4-12.4 32.8 0 45.2l169.4 169.4-169.4 169.4c-12.4 12.4-12.4 32.8 0 45.2s32.8 12.4 45.2 0l192-192c12.4-12.4 12.4-32.8 0-45.2l-192-192c-6.2-6.2-14.4-9.4-22.6-9.4zM352 224c8.2 0 16.4 3.2 22.6 9.4 12.4 12.4 12.4 32.8 0 45.2l-169.4 169.4 169.4 169.4c12.4 12.4 12.4 32.8 0 45.2s-32.8 12.4-45.2 0l-192-192c-12.4-12.4-12.4-32.8 0-45.2l192-192c6.2-6.2 14.4-9.4 22.6-9.4z" />
-<glyph unicode="&#xe76d;" d="M672 224c-8.2 0-16.4 3.2-22.6 9.4-12.4 12.4-12.4 32.8 0 45.2l169.4 169.4-169.4 169.4c-12.4 12.4-12.4 32.8 0 45.2s32.8 12.4 45.2 0l192-192c12.4-12.4 12.4-32.8 0-45.2l-192-192c-6.2-6.2-14.4-9.4-22.6-9.4zM352 224c8.2 0 16.4 3.2 22.6 9.4 12.4 12.4 12.4 32.8 0 45.2l-169.4 169.4 169.4 169.4c12.4 12.4 12.4 32.8 0 45.2s-32.8 12.4-45.2 0l-192-192c-12.4-12.4-12.4-32.8 0-45.2l192-192c6.2-6.2 14.4-9.4 22.6-9.4zM416.4 447.6c0-26.51-21.49-48-48-48s-48 21.49-48 48c0 26.51 21.49 48 48 48 26.51 0 48-21.49 48-48zM560.4 447.6c0-26.51-21.49-48-48-48s-48 21.49-48 48c0 26.51 21.49 48 48 48 26.51 0 48-21.49 48-48zM704.4 447.6c0-26.51-21.49-48-48-48s-48 21.49-48 48c0 26.51 21.49 48 48 48 26.51 0 48-21.49 48-48z" />
-<glyph unicode="&#xe76e;" d="M608 224c-8.2 0-16.4 3.2-22.6 9.4-12.4 12.4-12.4 32.8 0 45.2l169.4 169.4-169.4 169.4c-12.4 12.4-12.4 32.8 0 45.2s32.8 12.4 45.2 0l192-192c12.4-12.4 12.4-32.8 0-45.2l-192-192c-6.2-6.2-14.4-9.4-22.6-9.4zM416 224c8.2 0 16.4 3.2 22.6 9.4 12.4 12.4 12.4 32.8 0 45.2l-169.4 169.4 169.4 169.4c12.4 12.4 12.4 32.8 0 45.2s-32.8 12.4-45.2 0l-192-192c-12.4-12.4-12.4-32.8 0-45.2l192-192c6.2-6.2 14.4-9.4 22.6-9.4z" />
-<glyph unicode="&#xe76f;" d="M288 520c0 0 0.2-0.2 0 0v0zM768 703.4c0 35.6-28.8 64.4-64.2 64.4-35.4 0-64.2-28.8-64.2-64.2 0-24.2 13.4-45.4 33.2-56.4 2.6-3 4.4-9 4.4-12 0-0.2 0-0.4 0-0.8-1.6-35.2-7.6-63.8-14.2-83.4-8.6-25.2-76.4-79.2-103-84.4-11.6-2.4-15.8 1.2-15.8 20.4 0 0 0 277.8 0 280.8s0.4 7 3.8 10c0 0 0 0 0 0 17.2 11.6 28.6 31.2 28.6 53.6 0 35.6-28.8 64.4-64.2 64.4-35.4 0-64.2-28.8-64.2-64.4 0-22.6 11.6-42.6 29.2-54 0 0 0.2-0.2 0.2-0.2 0.2-0.2 0.4-0.2 0.8-0.4 0.4-0.2 0.8-0.4 1.2-0.8 4.6-3 6.6-6 6.6-8.4 0-2.6 0-378.6 0-392.6s-2.2-24.6-16.8-23.6-83.4 47-102.8 88.2c-9 19-13.6 37.6-13.6 56v0c0 0 0 0.8 0 1 0 6.2 0 22.6 6.4 27.2 15.6 11.8 25.6 30.4 25.6 51.4 0 35.6-28.8 64.4-64.2 64.4s-64.8-28.4-64.8-64c0-23.8 13-44.6 32-55.6 4.8-3 6-5.8 7.6-21.2s6-49.2 18.2-79.8c14.6-37.2 41.8-65.2 79.4-90.4 27.2-18.6 50.6-33.2 64.2-52.8s20.4-27 20.4-54c0 0 0 1.8 0 0 0-25.6-8-28-18.6-35.6-28.2-17.4-47-48.4-47-84 0-0.2 0-0.6 0-0.8 0-0.4 0-1 0-1.4 0-55 44.6-99.6 99.6-99.6 55 0 99.6 44.6 99.6 99.6 0 26.6-10.4 50.8-27.4 68.6-5.8 6.4-12 12-19.2 16.6-15 10.4-20.6 23-20.6 36.2v48.2c0 50.2 8.2 82.2 22.2 106.6 14.6 25.4 36.6 45.2 70.8 68.4 37.6 25.2 64.4 53.2 79.2 90.4 11.4 28.8 15.2 62 17.2 101.8 0.2 3.6 2.8 11.6 6.6 13.6v0c16.6 11.6 27.8 31 27.8 53zM320.2 543.4c-17.8 0-32.2 14.6-32.2 32.4s14.4 32.4 32.2 32.4 32.2-14.6 32.2-32.4-14.4-32.4-32.2-32.4zM512 799.4c-17.8 0-32.2 14.6-32.2 32.4s14.4 32.2 32.2 32.2 32.2-14.6 32.2-32.4-14.4-32.2-32.2-32.2zM703.8 671.4c-17.8 0-32.2 14.6-32.2 32.4s14.4 32.2 32.2 32.2 32.2-14.6 32.2-32.4-14.4-32.2-32.2-32.2z" />
-<glyph unicode="&#xe770;" d="M688 832h-352c-8.8 0-16-7.2-16-16v-752l192 192 192-192v752c0 8.8-7.2 16-16 16z" />
-<glyph unicode="&#xe771;" d="M608.6 358c0 0-10.8 56-14.6 180-3.8 124-18 285-18 285-5 56-23.6 73-64 73-18.8 0-41-4.6-46.6-6.6-18.8-7.2-17.4-23.2-17.4-45v-35.6c0-6.4 2.4-12 6.4-16.4l9.8-9.8c0.8-0.6 0.2-1.4 0.8-2 3.8-4.4 6.2-10 6.2-16.2v-49c0-6.4-2.4-6.4-6.4-10.6-0.4-0.6-1-1.2-1.6-1.6l-8.8-8.8c-0.2-0.2-0.6-0.6-0.8-0.8-4.2-4.4-6.8-10.4-6.8-16.8v-14.4c0-6.2 2.2-11.8 6.2-16.2 0 0 0.2-0.2 0.2-0.2l1.6-1.6c0 0 0.2-0.2 0.2-0.2l8-8c0.8-0.6 1.4-1.4 2-2 3.8-4.4 6.2-10 6.2-16.2 0-1.4-0.2-16.2-0.4-17.6-0.8-4.6-3-8.8-6-12.2-0.4-0.6-1-1.2-1.6-1.6l-7.8-7.8-2.8-3c-1-1.2-1.4-2.6-2.2-4.2-1.8-3.4-2.4-7.4-2.4-11.8v-15.6c0-5.8-0.2-11.4-0.4-17.2 0.4-4.8 14.4-11.4 14.4-21v-40.8c0-12.4-21-14-22-22.6-9.4-50.8-23.8-83.6-23.8-83.6-57.4-33.2-96-95.2-96-166.4 0-106 86-192 192-192s192 86 192 192c-0.2 70.2-38.6 132-95.6 165.4zM512 64c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64z" />
-<glyph unicode="&#xe772;" d="M512 896c-141.4 0-256-110.8-256-247.6 0-9.8 0.6-19.4 1.8-29 1.2-10.8 3.2-21.2 6-31.4 0.2-1 0.6-2.2 0.8-3.2 33.2-125.6 90.6-143 117.8-335.2 0-0.4 0.2-0.8 0.2-1 3-18.4 19.6-24.6 39.6-24.6h179.8c20 0 36.4 6.2 39.4 24.6 0 0.4 0.2 0.8 0.2 1 27.2 192.2 84.6 209.4 117.8 335.2 0.4 1 0.6 2 0.8 3.2 2.6 10.2 4.6 20.8 6 31.4 1.2 9.4 1.8 19.2 1.8 29 0 136.8-114.6 247.6-256 247.6zM635.6 167c0.2 0.4 0.6 0.8 0.8 1.2 2.2 3.4 3.4 7.2 3.4 11.4 0 7 3.2 12.4-13 12.4h-229.6c-16.2 0-13-4.2-13-12.4 0-4.2 1.2-8 3.4-11.4 0.2-0.4 0.6-0.8 1-1.2 0-0.2 0.2-0.2 0.2-0.4 3.4-5.2 5.4-8.8 5.4-15.2 0-6.2-1.8-9.8-5.2-15-0.6-0.8-1-1.4-1.4-2-2-3.4-3.2-7.2-3.2-11.2 0-4.2 1.2-8 3.4-11.6 0.2-0.4 0.6-0.8 0.8-1.2 3.6-5.4 5.6-9 5.6-15.6 0-6.2-1.8-9.8-5.2-14.8-0.4-0.8-1-1.4-1.6-2.2-2-3.4-3.2-7.2-3.2-11.2 0-10.8 8.6-20.2 20.4-23.2 0.6-0.2 1.2-0.2 1.8-0.4 12-2.8 24.4-3.2 37-5 1.4-0.2 2.8-0.4 4.4-0.6 11.2-2 20.6-7.8 26.8-15.4v0c7.6-10.6 21.6-22 37.6-22 15.2 0 28.6 10.8 36.4 20.8v0c6 8.4 16 14.6 27.8 16.8 1.4 0.2 2.8 0.6 4.4 0.6 12.6 1.8 25 2.2 37 5 0.6 0.2 1.2 0.2 1.8 0.4 11.8 3.2 20.4 12.4 20.4 23.2 0 4-1.2 7.8-3.2 11.2-0.6 0.8-1 1.4-1.6 2.2-3.2 5.2-5.2 8.6-5.2 14.8 0 6.4 2 10.2 5.6 15.6 0.2 0.4 0.6 0.8 0.8 1.2 2.2 3.4 3.4 7.4 3.4 11.6 0 4-1.2 7.8-3.2 11.2-0.6 0.6-1 1.4-1.4 2-3.2 5.2-5.2 8.6-5.2 15 0 6.4 2 10 5.4 15.2 0-0.2 0 0 0.2 0.2z" />
-<glyph unicode="&#xe773;" d="M800 896h-576c-17.6 0-32-14.4-32-32v-832c0-17.6 14.4-32 32-32h576c17.6 0 32 14.4 32 32v832c0 17.6-14.4 32-32 32zM288 544h64v-64h-64v64zM288 416h64v-64h-64v64zM288 288h64v-64h-64v64zM480 96h-192v64h192v-64zM480 224h-64v64h64v-64zM480 352h-64v64h64v-64zM480 480h-64v64h64v-64zM608 96h-64v64h64v-64zM608 224h-64v64h64v-64zM608 352h-64v64h64v-64zM608 480h-64v64h64v-64zM736 96h-64v192h64v-192zM736 352h-64v64h64v-64zM736 480h-64v64h64v-64zM736 640h-448v160h448v-160z" />
-<glyph unicode="&#xe774;" d="M141.8 597c0 82 50 153 121.2 183h-15.4c-82.2 0-150.2-65.6-162.2-150.4-12-2-21.4-15.8-21.4-32.2 0-17.2 10.2-30.8 23.2-31.8 14.4-72.8 70.2-131.6 139.4-137.6 0 0 0.2 0 0.2 0 2.8 0 5.6-1.2 8.4-1.8 2.2-0.4 4.4-0.8 6.6-1.4-59.8 34.2-100 98.4-100 172.2zM930.2 778c-2.2 5.8-4.6 11.2-7 16.6-13 28.8-28.8 52-46.8 69.2-22.4 21-48.2 32.2-74.8 32.2-16.6 0-32.8-4.4-48.2-12.8 0 0 0 0-0.2 0-2.4-1.4-4.8-2.6-7.2-4-98-58-208.2-92.4-325.2-98.8-13-0.8-26-0.4-39-0.4h-84.6c-68-30-118-101-118-183 0-73.6 38.4-138.2 95.6-172.2 26-21.8 83.4-23.4 80-47.8-3.8-26.4-11-43.8-15.6-61.4-2.6-9.6-47.2-145.8-50.6-289.4 0-4 0-7.4 0.4-13.2 0.4-5.8 4.4-12.8 17-12.8h153.6c13.2 0 19.4 6.6 18.6 18.6-0.4 3.8-1.2 8.6-1.6 13-4.8 46.2-9.2 99.6-6.6 163.2 2.6 68 10.4 103.8 14 122.6 4.2 20.8 15.2 44.8 24.2 60.6 61.6-1.8 185.8-38.6 230.2-57.8 0 0 14.4-6.8 20.2-10.4 14-6.8 28.4-10.2 43.2-10.2 1.8 0 3.6 0 5.4 0.2 24.6 1.4 48.4 19.4 69.4 39 18.2 17 33.8 40.4 46.8 69.2 2.4 5.6 4.8 11.2 7 17.2 19.2 50 29.6 111.8 29.6 176.2 0 64.4-10.4 126.4-29.8 176.4zM884 425c-15.6-37-36.4-66.6-59-66.6s-43.2 29.4-58.8 66.6c-18.2 43.2-29.8 106.2-29.8 176.2 0 70.4 11.6 133.6 30 176.8 15.6 36.8 36.2 59 58.6 59 22.6 0 43-22.4 58.8-59 18.4-43.2 30-106.4 30-176.8 0-70-11.6-133-29.8-176.2z" />
-<glyph unicode="&#xe775;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM783.6 176.4c-72.6-72.4-169.6-112.4-271.6-112.4v768c102 0 199-40 271.6-112.4 72.4-72.6 112.4-169 112.4-271.6 0-102.6-40-199-112.4-271.6z" />
-<glyph unicode="&#xe776;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM783.6 176.4c-72.6-72.4-169-112.4-271.6-112.4s-199 40-271.6 112.4c-72.4 72.6-112.4 169-112.4 271.6 0 102.6 40 199 112.4 271.6 72.6 72.4 169 112.4 271.6 112.4 102.6 0 199-40 271.6-112.4 72.4-72.6 112.4-169 112.4-271.6 0-102.6-40-199-112.4-271.6zM538 348.4l-10 227.6h-32l-12.8-228.4c-39-12.2-67.2-48.6-67.2-91.6 0-53 43-96 96-96s96 43 96 96c0 44-29.6 81.2-70 92.4zM803.2 591.2c0 0-2.6 5.8-4.4 9.4-0.2 0.6-0.6 1.2-1 1.8-0.4 0.8-0.8 1.4-1.2 2.2-0.8 1.6-1.8 3.6-3 5.6-1 2-2.2 4.2-3.4 6.4-1.2 2.2-2.6 4.4-3.8 6.8-5.6 9.4-12.6 20.8-21.8 33-9 12.2-20 25.4-33.2 38.6-13 13.2-28.4 26.4-45.6 38.6-2.2 1.6-4.4 3-6.6 4.6-2.2 1.4-4.4 3-6.8 4.4-4.6 2.8-9.2 5.8-14 8.4-9.6 5.6-19.8 10.4-30.2 15-10.4 4.6-21.4 8.4-32.6 12-11.2 3.4-22.6 6.2-34.4 8.4-11.6 2.2-23.6 3.6-35.4 4.4-12 0.8-23.8 0.6-35.8 0-1 0-0.4 0-0.8 0h-1.8l-2-0.2-4.2-0.4-2-0.2c-0.6 0-1.4-0.2-2.2-0.2l-4.6-0.6c-6.2-0.6-12-1.6-17.8-2.6-11.6-2.2-23-4.8-34-8.2-11-3.4-21.8-7.2-32.2-11.8-10.2-4.6-20.2-9.4-29.6-15-9.4-5.4-18.4-11.2-26.8-17.4-4.2-3-8.2-6.2-12.2-9.4-2-1.6-3.8-3.2-5.8-4.8-2-1.6-3.8-3.2-5.6-4.8-14.6-13.2-27.4-26.8-37.8-40.2-10.6-13.4-19-26.4-26-38.4-7-11.8-12-22.6-16-31.6-1-2.2-2-4.4-2.8-6.4-0.8-2-1.6-4-2.2-5.6-1.4-3.6-2.6-6.6-3.4-9-1.8-5-2.6-7.6-2.6-7.6-0.2-0.4 0-1 0.4-1.2 0.4-0.2 1 0 1.4 0.4v0c0 0 1.2 2.4 3.6 7.2 1.2 2.4 2.6 5.2 4.4 8.4 1 1.6 1.8 3.4 3 5.2 1 1.8 2.2 3.8 3.4 5.8 5 8.2 11.2 18.2 19.2 28.6 8 10.6 17.8 22 29.2 33.4 11.4 11.4 24.8 22.8 39.8 33.2 1.8 1.4 3.8 2.6 5.8 3.8 2 1.2 3.8 2.6 5.8 3.8 4 2.4 8 5 12.2 7.2 8.2 4.6 17 8.8 26 12.8 9 4 18.4 7.2 28 10 9.6 2.8 19.4 5 29.4 6.8 10 1.8 20.2 2.8 30.2 3.4 5 0.2 10.2 0.4 15 0.2h3.6c0.6 0 1.2 0 2 0h2l4.2-0.2h3.8c-0.2 0 0.6 0-0.2 0 10.2-0.8 20.2-2 30-3.8 9.8-2 19.4-4.2 28.8-7.2 9.4-3 18.4-6.4 27.2-10.4 8.6-4 17.2-8.2 25-13 8-4.8 15.6-9.8 22.6-15 3.6-2.6 7-5.4 10.4-8 1.6-1.4 3.2-2.8 5-4.2 1.6-1.4 3.2-2.8 4.8-4.2 12.4-11.4 23.2-23.2 32.2-34.8 9-11.6 16.2-22.8 22-33.2 5.8-10.2 10.2-19.6 13.6-27.4 0.8-2 1.6-3.8 2.4-5.6 0.4-0.8 0.6-1.6 1-2.4h91.8c-0.6 6.6-2.4 12.4-3.4 15.2z" />
-<glyph unicode="&#xe777;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448c247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM783.6 176.4c-72.6-72.4-169-112.4-271.6-112.4s-199 40-271.6 112.4c-72.4 72.6-112.4 169-112.4 271.6 0 102.6 40 199 112.4 271.6 72.6 72.4 169 112.4 271.6 112.4 102.6 0 199-40 271.6-112.4 72.4-72.6 112.4-169 112.4-271.6 0-102.6-40-199-112.4-271.6zM544 736c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32 17.673 0 32-14.327 32-32zM400 697.4c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32 17.673 0 32-14.327 32-32zM793.4 592c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32 17.673 0 32-14.327 32-32zM294.6 592c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32 17.673 0 32-14.327 32-32zM688 697.4c0-17.673-14.327-32-32-32s-32 14.327-32 32c0 17.673 14.327 32 32 32 17.673 0 32-14.327 32-32zM538 348.4l-10 227.6h-32l-12.8-228.4c-39-12.2-67.2-48.6-67.2-91.6 0-53 43-96 96-96s96 43 96 96c0 44-29.6 81.2-70 92.4z" />
-<glyph unicode="&#xe778;" d="M512 896c-78 0-151.2-20-215-54.8-23.2 33-61.6 54.8-105 54.8-70.6 0-128-57.4-128-128 0-43.4 21.8-81.8 54.8-105-34.8-63.8-54.8-137-54.8-215 0-247.4 200.6-448 448-448 247.4 0 448 200.6 448 448 0 247.4-200.6 448-448 448zM128 768c0 35.4 28.6 64 64 64 21 0 39.6-10 51.2-25.6-34-25.4-64.2-55.6-89.6-89.6-15.6 11.6-25.6 30.2-25.6 51.2zM783.6 176.4c-72.6-72.4-169-112.4-271.6-112.4s-199 40-271.6 112.4c-72.4 72.6-112.4 169-112.4 271.6 0 102.6 40 199 112.4 271.6 72.6 72.4 169 112.4 271.6 112.4 102.6 0 199-40 271.6-112.4 72.4-72.6 112.4-169 112.4-271.6 0-102.6-40-199-112.4-271.6zM704 704c0 0-203.2-167.4-240-208s-144-304-144-304 204.8 164.6 240 208 144 304 144 304z" />
-<glyph unicode="&#xe779;" d="M640 448c0-70.692-57.308-128-128-128s-128 57.308-128 128c0 70.692 57.308 128 128 128 70.692 0 128-57.308 128-128zM320 448c0 69.6 37.2 130.6 92.6 164.4l-46.2 46.2c-12.6-8.6-24.4-18.6-35.4-29.6-48.4-48.4-75-112.6-75-181 0-68.4 26.6-132.6 75-181 11-11 22.8-20.8 35.4-29.6l46.2 46.2c-55.4 33.8-92.6 94.8-92.6 164.4zM704 448c0-69.6-37.2-130.6-92.6-164.4l46.2-46.2c12.6 8.6 24.4 18.6 35.4 29.6 48.4 48.4 75 112.6 75 181 0 68.4-26.6 132.6-75 181-11 11-22.8 20.8-35.4 29.6l-46.2-46.2c55.4-33.8 92.6-94.8 92.6-164.4zM192 448c0 105 50.6 198 128.6 256.4l-45.8 45.6c-12-9.4-23.4-19.6-34.4-30.6-35.2-35.2-63-76.4-82.2-122-20-47.2-30.2-97.6-30.2-149.4 0-51.8 10.2-102.2 30.2-149.4 19.4-45.8 47-86.8 82.2-122 11-11 22.4-21.2 34.4-30.6l45.6 45.6c-77.8 58.4-128.4 151.4-128.4 256.4zM832 448c0-105-50.6-198-128.6-256.4l45.6-45.6c12 9.4 23.4 19.6 34.4 30.6 35.2 35.2 63 76.4 82.2 122 20 47.4 30.2 97.6 30.2 149.4 0 51.8-10.2 102.2-30.2 149.4-19.4 45.8-47 86.8-82.2 122-11 11-22.4 21.2-34.4 30.6l-45.6-45.6c78-58.4 128.6-151.4 128.6-256.4z" />
-<glyph unicode="&#xe77a;" d="M768 640l128-128-128-128v96h-304c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h304v96zM704 608v208c0 8.8-7.2 16-16 16h-544c-8.8 0-16-7.2-16-16v-604c0-17 0-20 18.4-29.2l237.6-118.8v128h304c8.8 0 16 7.2 16 16v208h-64v-160h-256v448l-96 64h352v-160h64z" />
-<glyph unicode="&#xe77b;" d="M448 384l128 128-128 128v-96h-304c-8.8 0-16-7.2-16-16v-32c0-8.8 7.2-16 16-16h304v-96zM880 832h-544c-8.8 0-16-7.2-16-16v-208h64v160h352l-96-64v-448h-256v160h-64v-208c0-8.8 7.2-16 16-16h304v-128l237.6 118.8c18.4 9.2 18.4 12.2 18.4 29.2v604c0 8.8-7.2 16-16 16z" />
-<glyph unicode="&#xe77c;" d="M254 761.6v38.4c0 17.6-14.4 32-32 32s-32-14.4-32-32v-43c-17-11.6-28-31-28-53s11-41.4 28-53v-555c0-17.6 14.4-32 32-32s32 14.4 32 32v550.4c21.4 10.4 36 32.2 36 57.6s-14.6 47.2-36 57.6zM446 374.2v425.8c0 17.6-14.4 32-32 32s-32-14.4-32-32v-423.4c-20.2-10.8-34-32-34-56.6s13.8-45.8 34-56.6v-167.4c0-17.6 14.4-32 32-32s32 14.4 32 32v169.8c18 11.4 30 31.4 30 54.2s-12 42.8-30 54.2zM638 633.4v166.6c0 17.6-14.4 32-32 32s-32-14.4-32-32v-166.6c-19.2-11-32-31.8-32-55.4s12.8-44.4 32-55.4v-426.6c0-17.6 14.4-32 32-32s32 14.4 32 32v426.6c19.2 11 32 31.8 32 55.4s-12.8 44.4-32 55.4zM862 194c0 23.6-12.8 44.4-32 55.4v550.6c0 17.6-14.4 32-32 32s-32-14.4-32-32v-550.6c-19.2-11-32-31.8-32-55.4s12.8-44.4 32-55.4v-42.6c0-17.6 14.4-32 32-32s32 14.4 32 32v42.6c19.2 11 32 31.8 32 55.4z" />
-<glyph unicode="&#xe77d;" d="M160 256h128v-128h-128v128zM352 384h128v-256h-128v256zM544 576h128v-448h-128v448zM736 768h128v-640h-128v640z" />
-<glyph unicode="&#xe77e;" d="M448 768h128v-640h-128v640zM256 384h128v-256h-128v256zM640 576h128v-448h-128v448z" />
-<glyph unicode="&#xe77f;" d="M800.4 479.6l-224.4-223.6-192 192-192-192-64 64 256 256 192-192 160 160-96 96h256v-256z" />
-<glyph unicode="&#xe780;" d="M800.4 416.4l-224.4 223.6-192-192-192 192-64-64 256-256 192 192 160-160-96-96h256v256z" />
-<glyph unicode="&#xe781;" d="M576 768l99.8-99.8-127.8-127.6-256.2-256.4-99.8 99.8v-256h256l-99.8 99.8 384 384 99.8-99.8v256z" />
-<glyph unicode="&#xe782;" d="M960 448l-192 192v-152h-216v216h152l-192 192-192-192h152v-216h-216v152l-192-192 192-192v152h216v-216h-152l192-192 192 192h-152.4l-0.8 217 217.2-0.6v-152.4z" />
-<glyph unicode="&#xe783;" d="M548 540.6l127.8 127.6-99.8 99.8h256v-256l-99.8 99.8-127.6-127.8zM548 355.4l127.8-127.6-99.8-99.8h256v256l-99.8-99.8-127.6 127.8zM476 355.4l-127.8-127.6 99.8-99.8h-256v256l99.8-99.8 127.6 127.8zM476 540.6l-127.8 127.6 99.8 99.8h-256v-256l99.8 99.8 127.6-127.8z" />
-<glyph unicode="&#xe784;" d="M896 775.4l-163.8-163.6 99.8-99.8h-256v256l99.8-99.8 163.6 163.8zM896 120.6l-163.8 163.6 99.8 99.8h-256v-256l99.8 99.8 163.6-163.8zM128 120.6l163.8 163.6-99.8 99.8h256v-256l-99.8 99.8-163.6-163.8zM128 775.4l163.8-163.6-99.8-99.8h256v256l-99.8-99.8-163.6 163.8z" />
-<glyph unicode="&#xe785;" d="M144 576h496v-128l256 192-256 192v-128h-496c-8.8 0-16-7.2-16-16v-96c0-8.8 7.2-16 16-16zM880 320h-496v128l-256-192 256-192v128h496c8.8 0 16 7.2 16 16v96c0 8.8-7.2 16-16 16z" />
-<glyph unicode="&#xe786;" d="M128 320l256 192v-128h384v256h-560c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h672c8.8 0 16-7.2 16-16v-480c0-8.8-7.2-16-16-16h-496v-128l-256 192z" />
-<glyph unicode="&#xe787;" d="M896 320l-256 192v-128h-384v256h560c8.8 0 16 7.2 16 16v96c0 8.8-7.2 16-16 16h-672c-8.8 0-16-7.2-16-16v-480c0-8.8 7.2-16 16-16h496v-128l256 192z" />
-<glyph unicode="&#xe788;" d="M704 544v-121-177h-78v-31-103c0-8.8-6-15.8-14.6-16v0h-0.2c-0.2 0-0.4 0-0.6 0-3.2 0-6.2 1.2-8.6 3.2l-0.2 0.2-0.8 0.2c-4 3.2-6.8 8-6.8 12.4v103 31h-162.2v-31-103c0-8.8-7.2-16-16-16s-16 7.2-16 16v103 31h-80v177.2 120.8h384M736 576h-448v-152.8-179.2c0-13.8 11-30 24.8-30h55.2v-102c0-26.6 21.4-48 48-48s48 21.4 48 48v102h98v-102c0-15 7.8-28.4 18.6-37.2 7.8-6.8 18.6-10.8 30-10.8 0.2 0 0.6 0 0.8 0 0.2 0-0.6 0-0.4 0 26.6 0 47.2 21.4 47.2 48v102h57.2c14 0 20.8 16.2 20.8 29.8v179.2 153h-0.2zM816 576c8.8 0 16-7.2 16-16v-192c0-8.8-7.2-16-16-16s-16 7.2-16 16v192c0 8.8 7.2 16 16 16M816 608c-26.6 0-48-21.4-48-48v-192c0-26.6 21.4-48 48-48s48 21.4 48 48v192c0 26.6-21.4 48-48 48v0zM208 576c8.8 0 16-7.2 16-16v-192c0-8.8-7.2-16-16-16s-16 7.2-16 16v192c0 8.8 7.2 16 16 16M208 608c-26.6 0-48-21.4-48-48v-192c0-26.6 21.4-48 48-48s48 21.4 48 48v192c0 26.6-21.4 48-48 48v0zM510 771.4h1.8c28.4 0 54.6-3.8 77.6-11.2l20-8.8c57.4-25.2 79.8-74.8 88.8-111.4h-372.6c8.8 37.2 31.2 87.2 88.2 112l20.6 9c22.6 6.8 48 10.4 75.6 10.4M370.8 832c-1 0-2.4-0.4-3.6-1.6-2.2-1.6-3.4-3.6-2.6-5l36.6-44.2c-96.4-41.8-110.8-143.4-112.8-173.4h447.2c-2.2 30-16.4 130.2-113.2 172.8l37 44.4c0.8 1-0.4 3.4-2.6 5.2-1.4 1-3 1.6-4 1.6-0.6 0-1-0.2-1.4-0.6l-38.4-45.4c-27.2 10.8-60.4 17.6-101.2 17.6-0.6 0-1.2 0-2 0-40 0-72.8-6.6-99.6-17l-38 45c0 0.4-0.6 0.6-1.4 0.6v0zM413.2 682.2c-14.8 0-27 12-27 26.6s12 26.6 27 26.6c14.8 0 27-12 27-26.6 0-14.6-12-26.6-27-26.6zM610 682.2c-14.8 0-27 12-27 26.6s12 26.6 27 26.6c14.8 0 27-12 27-26.6 0-14.6-12.2-26.6-27-26.6z" />
-<glyph unicode="&#xe789;" d="M288 423.2v-179.2c0-13.8 9-28 22.8-28h57.2v-104c0-26.6 21.4-48 48-48s48 21.4 48 48v104h98v-104c0-15 6.8-28.4 17.6-37.2 7.8-6.8 18.2-10.8 29.4-10.8 0.2 0 0.4 0 0.6 0 0.2 0 0.2 0 0.4 0 26.6 0 48 21.4 48 48v104h55.2c14 0 22.8 14.2 22.8 27.8v179.2 153h-448v-152.8zM816 608c-26.6 0-48-21.4-48-48v-192c0-26.6 21.4-48 48-48s48 21.4 48 48v192c0 26.6-21.4 48-48 48zM208 608c-26.6 0-48-21.4-48-48v-192c0-26.6 21.4-48 48-48s48 21.4 48 48v192c0 26.6-21.4 48-48 48zM622.4 781.8l37 43.8c0.8 1-0.4 3.2-2.6 5-2.2 1.6-4.8 2-5.4 0.8l-38.4-45.6c-27.2 10.8-60.4 17.6-101.2 17.6-41 0.2-74.4-6.4-101.6-17l-38 44.8c-0.8 1-3.2 0.8-5.4-0.8-2.2-1.6-3.4-3.6-2.6-5l36.6-43.2c-96.4-41.8-110.8-144.4-112.8-174.4h447.2c-1.8 30.2-16 131.4-112.8 174zM413.6 682.2c-14.8 0-27 12-27 26.6s12 26.6 27 26.6c14.8 0 27-12 27-26.6 0-14.6-12-26.6-27-26.6zM610.4 682.2c-14.8 0-27 12-27 26.6s12 26.6 27 26.6c14.8 0 27-12 27-26.6 0-14.6-12.2-26.6-27-26.6z" />
-<glyph unicode="&#xe78a;" d="M354 806l-226-147.8 156.2-125.4 227.8 141zM128 407.4l226-147.8 158 132.2-227.8 141zM512 391.8l158-132.2 226 147.8-156.2 125.4zM896 658.2l-226 147.8-158-132.2 227.8-141zM512.4 363.4l-159.6-132-68.8 44.4v-49.8l228-136 228 136v49.8l-68.4-44.4z" />
-<glyph unicode="&#xe78b;" d="M354 805.8l-226-147.8 156.6-126 227.4 141.6-158 132.2zM182.8 653.4l169 113.6 105.8-92-170.8-105-104 83.4zM739.6 534l-227.6-142.2 158-132.2 38 25.2v-40.4l-196-118.4-196 117v41l38-24.4 158 132.2-227.6 142.2-156.4-126.6 156-103v-78.8l228-135.6 228 137v78.4l156 102.4-156.4 126.2zM286.8 498.2l170.8-110.8-105.8-88.2-169 111.6 104 87.4zM566.4 387.4l170.8 110.8 104.2-87.2-169-111.6-106 88zM896 658l-226 147.8-158-132.2 227.6-141.6 156.4 126zM566.4 674.8l105.8 92 169-113.6-104-83.2-170.8 104.8z" />
-<glyph unicode="&#xe78c;" d="M580.8 670l-126.8 98 127.2-204.4zM658 768v-159.2-166.8h-72.8l-126.4 197.2 3.4-197.2h-80.2v214l-74.6 58.6c2-2.4 4-4.8 5.8-7.4 20-27.8 30-61 30-101 0-98.4-61.2-164.2-153.8-164.2h-125.4v-0.8l399.2-313.2h496.8v403.8l-302 236.2zM259.8 603.8c0 58-28.4 90.2-79.4 90.2h-38.4v-178h38c52 0 79.8 30.8 79.8 87.8z" />
-<glyph unicode="&#xe78d;" d="M581.8 668.2l-128.8 99.8 129.2-205.6zM65 440M658 768v-160.6-167.4h-71.8l-126.4 196 3.4-196h-81.2v214.2l-74.2 58.2c2-2.4 4.2-4.8 6-7.2 20-27.6 30-61.4 30-101 0-97.8-61-164-153.6-164h-126.2l400.2-312h495.8v402.4l-302 237.4zM928 160h-452.6l-318.2 248h33c27 0 52.4 5.4 75.4 14.8s42.8 23.6 59.6 41.4c9.6 10.2 18.8 22 24.8 34.2v-57.4-33h146l-0.6 33-1.4 83.8 65.2-101.4 9.4-15.2h121.4v33 166.2 94l0.4-0.6 237.6-185.6v-355.2zM181.2 659.2c22 0 47.4-6.4 47.4-57.6 0-13.8-2-32.6-12-43.6-7.2-7.8-19.2-12-35.4-12h-7.2v114h6M181.4 692h-39.4v-178h39c52 0 79.8 31.2 79.8 87.8 0 57.6-28.6 90.2-79.4 90.2v0z" />
-<glyph unicode="&#xe78e;" d="M128 832v-768h768v768h-768zM556 402v-144h-80v144l-132 240h94.2l79.4-167.2 76 167.2h90.4l-128-240z" />
-<glyph unicode="&#xe78f;" d="M832 768v-640h-640v640h640M896 832h-768v-768h768v768 0zM593.4 642h90.6l-127.8-240v-144h-79.8v144l-132.4 240h94.2l79.4-167.2 75.8 167.2z" />
-<glyph unicode="&#xe790;" d="M404.2 426.6h-217.4c-14.8 0-26.8-12.2-26.8-27.4v-178c0-13.2 9.2-23.8 21.4-26.4l210.8-42.2 13.8-2.4c14 0.6 25.4 12.8 25.4 27v222c0 15.4-12.4 27.4-27.2 27.4v0zM836.8 426.6h-336.4c-14.8 0-26.8-12.2-26.8-27.4v-241-0.4c0-11 6.6-20.2 15.8-24.4 0.4-0.4 0.4-0.4 0.4-0.4l10.6-2.2c0.4 0 0.4 0 0.6 0l329.4-65.8c0.4-0.2 1-0.6 1.4-0.6 0.2 0 0.4 0 0.6 0.2 1.4-0.8 2.8-0.8 4.2-0.8 14.8 0 27.2 12 27.2 27v308.4c0.2 15.4-12.2 27.4-27 27.4v0zM836.8 832c-1.4 0-2.8 0-4.2-0.8-0.2 0.2-0.4 0.2-0.6 0.2-0.4 0-1-0.2-1.4-0.6l-329.6-65.6c-0.4 0-0.4 0-0.6 0l-10.2-2.2c0 0-0.4 0-0.8-0.4-9.2-4.2-15.8-13.8-15.8-24.8v-241c0-15.2 12-27.4 26.8-27.4h336.4c14.8 0 27.2 12.2 27.2 27.4v308.2c0 14.8-12.4 27-27.2 27v0zM406 746l-13.8-2.4-210.8-42.4c-12.2-2.6-21.4-13.2-21.4-26.4v-178c0-15.2 12-27.4 26.8-27.4h217.6c14.8 0 27.2 12.2 27.2 27.4v222.2c-0.2 14.2-11.4 26.2-25.6 27v0z" />
-<glyph unicode="&#xe791;" d="M399.8 394.6v-211l-1.6 0.2-206.6 41.6v169.2h208.2M404.2 426.6h-217.4c-14.8 0-26.8-12.2-26.8-27.4v-178c0-13.2 9.2-23.8 21.4-26.4l210.8-42.2 13.8-2.4c14 0.6 25.4 12.8 25.4 27v222c0 15.4-12.4 27.4-27.2 27.4v0zM832.4 394.6v-294.4l-4.2-2.2-322.8 64.4v232h327M836.8 426.6h-336.4c-14.8 0-26.8-12.2-26.8-27.4v-241-0.4c0-11 6.6-20.2 15.8-24.4 0.4-0.4 0.4-0.4 0.4-0.4l10.6-2.2c0.4 0 0.4 0 0.6 0l329.4-65.8c0.4-0.2 1-0.6 1.4-0.6 0.2 0 0.4 0 0.6 0.2 1.4-0.8 2.8-0.8 4.2-0.8 14.8 0 27.2 12 27.2 27v308.4c0.2 15.4-12.2 27.4-27 27.4v0zM828 797.8l4.2-2.2v-294.4h-327v232l322.8 64.6M836.8 832c-1.4 0-2.8 0-4.2-0.8-0.2 0.2-0.4 0.2-0.6 0.2-0.4 0-1-0.2-1.4-0.6l-329.6-65.6c-0.4 0-0.4 0-0.6 0l-10.2-2.2c0 0-0.4 0-0.8-0.4-9.2-4.2-15.8-13.8-15.8-24.8v-241c0-15.2 12-27.4 26.8-27.4h336.4c14.8 0 27.2 12.2 27.2 27.4v308.2c0 14.8-12.4 27-27.2 27v0zM399.8 712.2v-211h-208.2v169.2l208.2 41.8M406 746l-13.8-2.4-210.8-42.4c-12.2-2.6-21.4-13.2-21.4-26.4v-178c0-15.2 12-27.4 26.8-27.4h217.6c14.8 0 27.2 12.2 27.2 27.4v222.2c-0.2 14.2-11.4 26.2-25.6 27v0z" />
-<glyph unicode="&#xe792;" d="M667.2 652.2c-67.2 0-95.6-33-142.4-33-48 0-84.6 32.8-142.8 32.8-57 0-117.8-35.8-156.4-96.8-54.2-86-45-248 42.8-386 31.4-49.4 73.4-104.8 128.4-105.4 0.4 0 0.6 0 1 0 47.8 0 62 32.2 127.8 32.6 0.4 0 0.6 0 1 0 64.8 0 77.8-32.4 125.4-32.4 0.4 0 0.6 0 1 0 55 0.6 99.2 62 130.6 111.2 22.6 35.4 31 53.2 48.4 93.2-127 49.6-147.4 234.8-21.8 305.8-38.4 49.4-92.2 78-143 78v0zM652.4 832c-40-2.8-86.6-29-114-63.2-24.8-31-45.2-77-37.2-121.6 1 0 2 0 3.2 0 42.6 0 86.2 26.4 111.6 60.2 24.6 32.2 43.2 77.8 36.4 124.6v0z" />
-<glyph unicode="&#xe793;" d="M667.2 620.2c32.6 0 66.4-14.8 94.8-40.8-19.8-17-35.8-37.4-47.4-60.4-16-32-23.2-68.6-20.4-105.4 2.6-37.4 15.2-73.2 36-103.6 16-23.2 36.4-42.4 60-56.6-10-21.4-18.4-36.8-33.6-61-16.8-26.2-61-96-104-96.4h-0.8c-14.8 0-24.4 4.4-38.6 11.2-20 9.4-44.6 21.2-86.8 21.2h-1.2c-42.2-0.2-67.6-11.8-87.8-21.2-14.8-6.8-24.6-11.4-39.8-11.4h-0.8c-39.2 0.4-75 48.6-101.6 90.4-38.6 60.8-63.4 131.2-69.8 198.2-5.8 61 4 117 27 153.4 16 25.4 37 46.6 60.8 61.2 22.4 13.6 46 20.8 68.4 20.8 24.8 0 45.4-7.6 67.4-15.6 23-8.4 47-17.2 75.4-17.2 27.2 0 48.6 8.4 69.2 16.4 22.4 8.8 42.8 16.8 73.6 16.8M667.2 652.2c-67.2 0-95.6-33-142.4-33-48 0-84.6 32.8-142.8 32.8-57 0-117.8-35.8-156.4-96.8-54.2-86-45-248 42.8-386 31.4-49.4 73.4-104.8 128.4-105.4 0.4 0 0.6 0 1 0 47.8 0 62 32.2 127.8 32.6 0.4 0 0.6 0 1 0 64.8 0 77.8-32.4 125.4-32.4 0.4 0 0.6 0 1 0 55 0.6 99.2 62 130.6 111.2 22.6 35.4 31 53.2 48.4 93.2-127 49.6-147.4 234.8-21.8 305.8-38.4 49.4-92.2 78-143 78v0zM619.8 791c-5.4-29.8-21-53.6-29.2-64.4-14.8-19.6-36-34.8-57.6-42.2 1 6 2.6 12.2 4.8 18.4 7 20.4 17.8 36.4 25.6 46.2 14.2 17.6 35.2 32.8 56.4 42M652.4 832c-40-2.8-86.6-29-114-63.2-24.8-31-45.2-77-37.2-121.6 1 0 2 0 3.2 0 42.6 0 86.2 26.4 111.6 60.2 24.6 32.2 43.2 77.8 36.4 124.6v0z" />
-<glyph unicode="&#xe794;" d="M1017.2 662.4c0 90-66.2 162.4-148 162.4-110.8 5.2-223.8 7.2-339.2 7.2-6 0-12 0-18 0s-12 0-18 0c-115.2 0-228.4-2-339.2-7.2-81.6 0-147.8-72.8-147.8-162.8-5-71.2-7.2-142.4-7-213.6-0.2-71.2 2-142.4 6.8-213.8 0-90 66.2-163 147.8-163 116.4-5.4 235.8-7.8 357.2-7.6 121.6-0.4 240.6 2 357.2 7.6 81.8 0 148 73 148 163 4.8 71.4 7 142.6 6.8 214 0.4 71.2-1.8 142.4-6.6 213.8zM414 252.2v393l290-196.4-290-196.6z" />
-<glyph unicode="&#xe795;" d="M530 768c130.6 0 237.4-2.2 336.2-6.6h2.8c46.2 0 84-44 84-98.2v-2.2l0.2-2.2c4.6-68 6.8-138.6 6.8-209.8v0 0c0.2-71.2-2.2-141.8-6.8-209.8l-0.2-2.2v-2.2c0-27.6-9.4-53.2-26.8-72.2-15.6-17.2-36-26.8-57.2-26.8h-3.2c-105.8-5-217.6-7.6-332.8-7.6-7 0-14.2 0-21.2 0v0c-7.2 0-14.4 0-21.6 0-115.6 0-227.4 2.6-332.4 7.4h-3.2c-21.2 0-41.4 9.6-57 26.8-17.2 19-26.8 44.6-26.8 72.2v2.2l-0.2 2.2c-4.8 68.2-7 138.8-6.6 209.4v0.2 0.2c-0.2 70.6 2 141 6.6 209.2l0.2 2.2v2.2c0 54.4 37.6 98.6 83.8 98.6h2.8c99 4.6 205.8 6.6 336.4 6.6h36.2M530 832c-6 0-12 0-18 0s-12 0-18 0c-115.2 0-228.4-1.6-339.2-6.6-81.6 0-147.8-72.6-147.8-162.6-5-71.6-7.2-142.8-7-214.2-0.2-71.4 1.8-142.6 6.8-214 0-90 66.2-163.2 147.8-163.2 109.6-5.2 221.4-7.6 335.6-7.6 7.2 0 14.6 0 21.8 0 7.2 0 14.4 0 21.4 0 114.2 0 226 2.4 335.8 7.6 81.8 0 148 73.2 148 163.2 4.8 71.4 7 142.8 6.8 214.2 0.2 71.4-2 142.6-6.8 214.2 0 90-66.2 162.2-148 162.2-110.8 5.2-223.8 6.8-339.2 6.8v0zM414 252.4v392.8l290-196.4-290-196.4z" />
-<glyph unicode="&#xe796;" d="M834.4 832h-640.8c-35 0-65.6-25.2-65.6-59.8v-642.2c0-34.8 30.6-65.8 65.6-65.8h640.6c35.2 0 61.6 31.2 61.6 65.8v642.2c0.2 34.6-26.4 59.8-61.4 59.8zM366 192h-110v342h110v-342zM314.8 586h-0.8c-35.2 0-58 26.2-58 59 0 33.4 23.4 59 59.4 59 36 0 58-25.4 58.8-59 0-32.8-22.8-59-59.4-59zM768 192h-110v187c0 44.8-16 75.4-55.8 75.4-30.4 0-48.4-20.6-56.4-40.6-3-7.2-3.8-17-3.8-27v-194.8h-110v342h110v-47.6c16 22.8 41 55.6 99.2 55.6 72.2 0 126.8-47.6 126.8-150.2v-199.8z" />
-<glyph unicode="&#xe797;" d="M365.6 192v342.2h-109.8v-342.2h109.8zM314.8 586c36.6 0 59.4 26.2 59.4 59-0.6 33.4-22.8 59-58.8 59-36 0-59.4-25.6-59.4-59 0-32.8 22.8-59 58-59h0.8zM641.2 542c-58.2 0-83.2-32.8-99.2-55.6v47.6h-110v-342h110v194.8c0 10 0.8 20 3.8 27 8 20 26 40.6 56.4 40.6 39.8 0 55.8-30.6 55.8-75.4v-187h110v199.8c0 102.6-54.4 150.2-126.8 150.2zM834.4 832h-640.8c-35 0-65.6-25.2-65.6-59.8v-642.2c0-34.8 30.6-65.8 65.6-65.8h640.6c35.2 0 61.6 31.2 61.6 65.8v642.2c0.2 34.6-26.4 59.8-61.4 59.8zM828 128c-2.2 0-626.2 0-629.8 0s-6.2 2.8-6.2 6.2 0 627.6 0 629.8 2 4 4 4 630 0 632 0 4-2 4-4c0-46.6 0-629.8 0-632 0-1.8-1.8-4-4-4z" />
-<glyph unicode="&#xe798;" d="M873.8 366.4c5.6 25 8.4 50.8 8.4 77.4 0 199.4-164 361.2-366.4 361.2-21.4 0-42.2-1.8-62.6-5.2-32.6 20.4-71.2 32.2-112.8 32.2-117.2 0-212.4-93.8-212.4-209.4 0-38.8 10.6-75 29.2-106-4.8-23.4-7.4-47.8-7.4-72.6 0-199.6 164-361.2 366.2-361.2 23 0 45.4 2 67 6 30-15.8 64.2-24.8 100.4-24.8 117.4 0 212.4 93.8 212.4 209.4 0.2 33.4-7.8 65-22 93zM703.8 271.4c-17-23.6-42-42.4-74.4-55.6-32.2-13.2-70.6-19.8-114.6-19.8-52.6 0-96.6 9.2-131.2 27.2-24.6 13.2-44.8 30.8-60.4 52.8-15.6 22-23.4 44-23.4 65.2 0 13.2 5.2 24.6 15.2 34.2 10 9.2 23 14 38.2 14 12.6 0 23.4-3.6 32.2-11 8.4-7 15.6-17.4 21.4-31 6.6-14.6 13.6-27 21.2-36.8 7.2-9.4 17.4-17.2 30.6-23.4 13.4-6.2 31.2-9.4 53.2-9.4 30.2 0 55 6.4 73.6 19 18.4 12.2 27.2 27 27.2 45 0 14.2-4.6 25.4-14.2 34.2-10 9.2-23 16.4-39.2 21.2-16.6 5.2-39.2 10.6-67.2 16.4-38 8-70.2 17.6-96 28.4-26.2 11-47.4 26.4-63 45.4-15.8 19.4-23.6 43.8-23.6 72.4 0 27.4 8.4 51.8 24.8 73 16.4 21 40.2 37.4 71.2 48.6 30.4 11.2 66.6 16.8 107.4 16.8 32.8 0 61.4-3.8 85.4-11 24.2-7.4 44.4-17.4 60.6-29.8 16-12.4 28-25.6 35.6-39.4 7.6-14 11.4-27.8 11.4-41.2 0-12.8-5-24.6-15-34.8-10-10.2-22.6-15.6-37.6-15.6-13.6 0-24.2 3.2-31.6 9.6-6.8 6-14 15.2-21.8 28.6-9.2 17-20.2 30.6-32.8 40.2-12.4 9.2-32.8 14-61.2 14-26.2 0-47.6-5.2-63.4-15.4-15.2-9.8-22.6-21.2-22.6-34.6 0-8.2 2.4-15 7.4-21 5.2-6.2 12.4-11.8 21.8-16.4 9.6-4.8 19.6-8.6 29.4-11.2 10.2-2.8 27.2-7 50.6-12.2 29.8-6.2 57-13.4 81-20.8 24.4-7.8 45.4-17.2 62.6-28.2 17.6-11.2 31.4-25.8 41.4-43 9.8-17.2 14.8-38.8 14.8-63.6 0.8-30.2-7.8-57.4-25-81z" />
-<glyph unicode="&#xe799;" d="M340.4 768c28 0 55.4-7.8 79.2-22.6l20.6-12.8 24 4c17 3 34.4 4.4 51.8 4.4 81 0 157-31 214-87.4 56.8-56 88.2-130.6 88.2-209.8 0-21.4-2.4-42.8-7-63.6l-5-22.2 10.2-20.4c10.2-20.2 15.4-41.8 15.4-64.4 0-80.2-66.6-145.4-148.4-145.4-25 0-48.6 5.8-70.4 17.4l-19.6 10.4-21.8-4c-18.2-3.4-37-5-55.6-5-81 0-157 31-214 87.4-56.8 56-88.2 130.6-88.2 209.8 0 20 2 40.2 6 59.8l5 24.4-12.8 21.4c-13 22.2-20 47.4-20 73.2 0 80.2 66.6 145.4 148.4 145.4M340.4 832c-117.2 0-212.4-93.8-212.4-209.4 0-38.8 10.6-75 29.2-106-4.8-23.4-7.4-47.8-7.4-72.6 0-199.6 164-361.2 366.2-361.2 23 0 45.4 2 67 6 30-15.8 64.2-24.8 100.4-24.8 117.4 0 212.4 93.8 212.4 209.4 0 33.4-8 65-22.2 93 5.6 25 8.4 50.8 8.4 77.4 0 199.4-164 361.2-366.4 361.2-21.4 0-42.2-1.8-62.6-5.2-32.4 20.4-71 32.2-112.6 32.2v0zM703.8 271.8c-17-23.6-42-42.4-74.4-55.6-32.2-13.2-70.6-19.8-114.6-19.8-52.6 0-96.6 9.2-131.2 27.2-24.6 13.2-44.8 30.8-60.4 52.8-15.6 22-23.4 44-23.4 65.2 0 13.2 5.2 24.6 15.2 34.2 10 9.2 23 14 38.2 14 12.6 0 23.4-3.6 32.2-11 8.4-7 15.6-17.4 21.4-31 6.6-14.6 13.6-27 21.2-36.8 7.2-9.4 17.4-17.2 30.6-23.4 13.4-6.2 31.2-9.4 53.2-9.4 30.2 0 55 6.4 73.6 19 18.4 12.2 27.2 27 27.2 45 0 14.2-4.6 25.4-14.2 34.2-10 9.2-23 16.4-39.2 21.2-16.6 5.2-39.2 10.6-67.2 16.4-38 8-70.2 17.6-96 28.4-26.2 11-47.4 26.4-63 45.4-15 19.2-23 43.6-23 72.2 0 27.4 8.4 51.8 24.8 73 16.4 21 40.2 37.4 71.2 48.6 30.4 11.2 66.6 16.8 107.4 16.8 32.8 0 61.4-3.8 85.4-11 24.2-7.4 44.4-17.4 60.6-29.8 16-12.4 28-25.6 35.6-39.4 7.6-14 11.4-27.8 11.4-41.2 0-12.8-5-24.6-15-34.8-10-10.2-22.6-15.6-37.6-15.6-13.6 0-24.2 3.2-31.6 9.6-6.8 6-14 15.2-21.8 28.6-9.2 17-20.2 30.6-32.8 40.2-12.4 9.2-32.8 14-61.2 14-26.2 0-47.6-5.2-63.4-15.4-15.2-9.8-22.6-21.2-22.6-34.6 0-8.2 2.4-15 7.4-21 5.2-6.2 12.4-11.8 21.8-16.4 9.6-4.8 19.6-8.6 29.4-11.2 10.2-2.8 27.2-7 50.6-12.2 29.8-6.2 57-13.4 81-20.8 24.4-7.8 45.4-17.2 62.6-28.2 17.6-11.2 31.4-25.8 41.4-43 9.8-17.2 14.8-38.8 14.8-63.6 0-30-8.6-57.2-25.6-80.8z" />
-<glyph unicode="&#xe79a;" d="M834.4 832c-15.2 0-30-1.4-43.2-3.4-38.2-5.8-171-52.4-215.2-188.6 11.2 2 21.8 3.2 31.8 3.2 54.8 0 89.4-32 83-104.6-3.2-35.8-21.4-75-41.8-112.6-17.6-32.6-46.8-88.6-84.6-88.6-12.6 0-26 6.2-40.4 21.4-52 55.2-48 160.8-60 231.2-6.6 39.4-13.6 88.6-26.6 129.2-11.2 34.8-37 77-68.4 86.2-7.4 2.2-15.2 3.2-23.2 3.2-28.2 0-57.6-11.8-76.8-23-78-45.6-137.6-110.4-205-164 13.4-12.8 18.6-42.6 38.2-45.6 2.8-0.4 5.6-0.6 8.4-0.6 28 0 54.4 18.6 77.4 18.6 12.6 0 24.2-5.6 34.4-22.8 18.8-31.8 24.6-66.4 36.6-100.6 16.2-45.4 28.6-95 41.6-147.4 22.2-88.6 49.6-221 126.6-253.6 9.8-4.2 20.8-5.8 32.2-5.8 34.6 0 73.6 15.8 96.2 29.2 81 47.6 144.2 116.8 198.2 187 123.6 166.4 191.8 355 202.2 408.8 6.6 37.2 6.6 75.6-16.6 104.6-23.2 29.6-65.4 38.6-105 38.6v0z" />
-<glyph unicode="&#xe79b;" d="M834.4 800c22.2 0 62-3.4 80.2-26.2 13.4-17 16.8-42 10.2-78.8-5-25.6-24.6-84.8-56.2-154.8-27.6-60.8-74.2-151.8-140-240.6-65.8-85.6-124-140.6-189-178.8-20.8-12.2-53.6-24.6-80-24.6-7.8 0-14.6 1.2-19.8 3.4-23.4 9.8-44.6 36.4-62.8 78.6-17.8 41.4-29.8 90.4-40.6 133.6-1.6 6.8-3.2 13.2-4.8 19.6l-0.6 2.4c-13.2 52.2-25.6 101.6-41.8 147.6-3.4 10-6.4 20-9.6 30.6-7.2 24.8-14.8 50.4-29.8 75.6v0 0c-19 31.6-44 38.4-61.8 38.4-16.6 0-31.4-5.4-45.8-10.6-11.6-4.2-22.4-8.2-31.6-8.2 0 0 0 0 0 0-1.4 2-3 4.8-4.4 7.4 15.8 13.2 31.2 26.8 46.2 40.2 41.2 36.6 84 74.4 132.6 102.8 15.4 9 39.4 18.6 60.6 18.6 5.2 0 10.2-0.6 14.4-1.8 15.8-4.6 36.8-33.8 46.8-65.2 10.4-32.4 16.8-71.8 22.6-106.6 1-6.2 2-12.2 3-18 2.8-16 4.6-34.4 6.6-53.8 7-67.6 14.8-144 61.6-193.8 19.6-21 41.2-31.6 63.8-31.6 56 0 90.6 64.4 111.4 102.8l1.4 2.6c20.4 37.4 41.6 81.6 45.4 125 4 45.2-5.6 80.6-28.2 105.4-16.8 18.4-40.4 29.6-68.6 33 18.4 32.2 44.4 60 78 82.6 39.8 26.8 77.8 38.2 92.4 40.4 12.6 1.8 25.8 2.8 38.2 2.8M834.4 832c-15.2 0-30-1.4-43.2-3.4-38.2-5.8-171-52.4-215.2-188.6 11.2 2 21.8 3.2 31.8 3.2 54.8 0 89.4-32 83-104.6-3.2-35.8-21.4-75-41.8-112.6-17.6-32.6-46.8-88.6-84.6-88.6-12.6 0-26 6.2-40.4 21.4-52 55.2-48 160.8-60 231.2-6.6 39.4-13.6 88.6-26.6 129.2-11.2 34.8-37 77-68.4 86.2-7.4 2.2-15.2 3.2-23.2 3.2-28.2 0-57.6-11.8-76.8-23-78-45.6-137.6-110.4-205-164 13.4-12.8 18.6-42.6 38.2-45.6 2.8-0.4 5.6-0.6 8.4-0.6 28 0 54.4 18.6 77.4 18.6 12.6 0 24.2-5.6 34.4-22.8 18.8-31.8 24.6-66.4 36.6-100.6 16.2-45.4 28.6-95 41.6-147.4 22.2-88.6 49.6-221 126.6-253.6 9.8-4.2 20.8-5.8 32.2-5.8 34.6 0 73.6 15.8 96.2 29.2 81 47.6 144.2 116.8 198.2 187 123.6 166.4 191.8 355 202.2 408.8 6.6 37.2 6.6 75.6-16.6 104.6-23.2 29.6-65.4 38.6-105 38.6v0z" />
-<glyph unicode="&#xe79c;" d="M141.4 631l338.4-163.4c8.8-4.2 20.6-6.4 32.2-6.4s23.4 2.2 32.2 6.4l338.4 163.4c17.8 8.6 17.8 22.6 0 31.2l-338.4 163.4c-8.8 4.2-20.6 6.4-32.2 6.4s-23.4-2.2-32.2-6.4l-338.4-163.4c-17.8-8.6-17.8-22.6 0-31.2zM882.6 463.6c0 0-61.8 29.8-70 33.8s-10.4 3.8-19-0.2-249.6-120.4-249.6-120.4c-9-4.2-20.6-6.4-32.2-6.4s-23.4 2.2-32.2 6.4c0 0-234.6 113.2-245.6 118.6-12 5.8-15.4 5.8-26.2 0.6-11.2-5.4-66.8-32.2-66.8-32.2-17.8-8.6-17.8-22.6 0-31.2l338.4-163.4c8.8-4.2 20.6-6.4 32.2-6.4s23.4 2.2 32.2 6.4l338.4 163.4c18.2 8.4 18.2 22.4 0.4 31zM882.6 265c0 0-61.8 29.8-70 33.8s-10.4 3.8-19-0.2-249.4-120.6-249.4-120.6c-9-4.2-20.6-6.4-32.2-6.4s-23.4 2.2-32.2 6.4c0 0-234.6 113.2-245.6 118.6-12 5.8-15.4 5.8-26.2 0.6-11.2-5.4-66.8-32.2-66.8-32.2-17.8-8.6-17.8-22.6 0-31.2l338.4-163.4c8.8-4.4 20.6-6.4 32.2-6.4s23.4 2.2 32.2 6.4l338.4 163.4c18 8.6 18 22.6 0.2 31.2z" />
-<glyph unicode="&#xe79d;" d="M141.4 631l338.4-163.4c8.8-4.2 20.6-6.4 32.2-6.4s23.4 2.2 32.2 6.4l338.4 163.4c17.8 8.6 17.8 22.6 0 31.2l-338.4 163.4c-8.8 4.2-20.6 6.4-32.2 6.4s-23.4-2.2-32.2-6.4l-338.4-163.4c-17.8-8.6-17.8-22.6 0-31.2zM493.6 796.8c3.2 1.6 9.8 3.2 18.4 3.2 8.6 0 15-1.6 18.4-3.2l311-150.2-311-150.2c-3.2-1.6-9.8-3.2-18.4-3.2s-15 1.6-18.4 3.2l-311 150.2 311 150.2zM882.6 463.6c0 0-61.8 29.8-70 33.8s-10.4 3.8-19-0.2-249.6-120.4-249.6-120.4c-9-4.2-20.6-6.4-32.2-6.4s-23.4 2.2-32.2 6.4c0 0-234.6 113.2-245.6 118.6-12 5.8-15.4 5.8-26.2 0.6-11.2-5.4-66.8-32.2-66.8-32.2-17.8-8.6-17.8-22.6 0-31.2l338.4-163.4c8.8-4.2 20.6-6.4 32.2-6.4s23.4 2.2 32.2 6.4l338.4 163.4c18.2 8.4 18.2 22.4 0.4 31zM530.4 297.8c-3.2-1.6-9.8-3.2-18.4-3.2s-15 1.6-18.4 3.2l-311 150.2 37.8 18.2 245.4-118.6c12.8-6.2 29.2-9.6 46.2-9.6s33.2 3.4 46.2 9.6l245.4 118.6 37.8-18.2-311-150.2zM882.6 265c0 0-61.8 29.8-70 33.8s-10.4 3.8-19-0.2-249.4-120.6-249.4-120.6c-9-4.2-20.6-6.4-32.2-6.4s-23.4 2.2-32.2 6.4c0 0-234.6 113.2-245.6 118.6-12 5.8-15.4 5.8-26.2 0.6-11.2-5.4-66.8-32.2-66.8-32.2-17.8-8.6-17.8-22.6 0-31.2l338.4-163.4c8.8-4.4 20.6-6.4 32.2-6.4s23.4 2.2 32.2 6.4l338.4 163.4c18 8.6 18 22.6 0.2 31.2zM530.4 99.2c-3.2-1.6-9.8-3.2-18.4-3.2s-15 1.6-18.4 3.2l-311 150.2 37.8 18.2 245.4-118.6c12.8-6.2 29.2-9.6 46.2-9.6s33.2 3.4 46.2 9.6l245.4 118.6 37.8-18.2-311-150.2z" />
-<glyph unicode="&#xe79e;" d="M769.2 823.2c-22.6 0-45 1.6-65.2 8.8l-192-320-192 320c-20.2-7.2-41.4-8.8-64-8.8-22.2 0-44.2 1.8-64 8.8l256-425.4v-342.6c20 7 41.6 8.8 64 8.8s44-1.8 64-8.8v342l256 426c-19.8-6.8-40.6-8.8-62.8-8.8z" />
-<glyph unicode="&#xe79f;" d="M769.2 823.2c-22.6 0-45 1.6-65.2 8.8l-192-320-192 320c-20.2-7.2-41.4-8.8-64-8.8-22.2 0-44.2 1.8-64 8.8l256-425.4v-342.6c20 7 41.6 8.8 64 8.8s44-1.8 64-8.8v342l256 426c-19.8-6.8-40.6-8.8-62.8-8.8zM548.4 423l-4.4-8v-8.8-302.6c-10 1.2-22.4 1.4-32 1.4s-20-0.2-32-1.4v303 8.8l-4.8 7.6-221.2 368.2c0.6 0 1.4 0 2 0 15.2 0 32 0.6 49.4 3.8l179.6-299.6 26.8-45.6 28 45.8 179.6 299.8c18-3.2 35.2-3.4 49.6-3.4 0.4 0 0.6 0 1 0l-221.6-369z" />
-<glyph unicode="&#xe7a0;" d="M961 458c0 55.4-44.4 100.4-99 100.4-26 0-49.4-10-67.2-26.6-64.8 45.6-152.2 75.6-249.8 81.2l43.8 146.4 134.2-27c4.6-45.4 42.4-80.8 88.6-80.8 0.2 0 0.2 0 0.4 0 0.2 0 0.2 0 0.4 0 49.2 0 89 40.4 89 90.2s-40 90.2-89.2 90.2c-0.2 0-0.2 0-0.4 0 0 0-0.2 0-0.2 0-34.4 0-64-19.6-79-48.6l-179.4 36-61.6-206-5-0.2c-100.6-4.4-191-34.8-257.4-81.4-17.6 16.6-41.2 26.6-67.2 26.6-54.6 0-99-45-99-100.4 0-39.2 22-73 54.2-89.6-1.6-9.8-2.4-19.6-2.4-29.6 0.2-151.6 178-274.8 397.2-274.8s397 123.2 397 275c0 10-0.8 19.8-2.2 29.6 32.2 16.6 54.2 50.4 54.2 89.4zM131.6 417.8c-13.2 9-21.8 24.2-21.8 41.6 0 27.6 22.2 50.2 49.4 50.2 11.2 0 21.6-3.8 30-10.2-27-23.8-47-51.4-57.6-81.6zM778.6 741.8c0 18.4 14.8 33.6 33 33.6s33-15 33-33.6c0-18.4-14.8-33.6-33-33.6s-33 15-33 33.6zM317 383.2c0 35.2 28.4 63.6 63.6 63.6s63.6-28.4 63.6-63.6c0-35.2-28.4-63.6-63.6-63.6s-63.6 28.4-63.6 63.6zM512 160c-95.2 0.4-152 57-154.4 59.4l25.2 24.8c0.4-0.4 47.4-48.4 129.2-48.8 80.6 0.4 128.4 48.4 129 48.8l25.2-24.8c-2.4-2.4-59-59-154.2-59.4zM644.6 319.6c-35.2 0-63.6 28.4-63.6 63.6s28.4 63.6 63.6 63.6 63.6-28.4 63.6-63.6c0-35.2-28.6-63.6-63.6-63.6zM892.8 417c-10.8 30.6-31.2 58.8-58.6 82.8 8.4 6.6 19 10.4 30.4 10.4 27.8 0 50.2-22.8 50.2-51 0.2-17.6-8.6-33-22-42.2z" />
-<glyph unicode="&#xe7a1;" d="M708.2 383.2c0-35.125-28.475-63.6-63.6-63.6s-63.6 28.475-63.6 63.6c0 35.125 28.475 63.6 63.6 63.6 35.125 0 63.6-28.475 63.6-63.6zM444.2 383.2c0-35.125-28.475-63.6-63.6-63.6s-63.6 28.475-63.6 63.6c0 35.125 28.475 63.6 63.6 63.6 35.125 0 63.6-28.475 63.6-63.6zM961 458c0 55.4-44.4 100.4-99 100.4-26 0-49.4-10-67.2-26.6-66.4 46.8-156.8 77-257.4 81.4l46.6 155.4 139.2-27.8c0.4-49.4 40.2-89.4 89-89.4 49.2 0 89 40.4 89 90.2s-39.8 90.4-89 90.4c-37.2 0-69-23.2-82.4-56l-170.4 34-58.8-196.4-14.2-0.4c-100.6-4.4-191-34.8-257.4-81.4-17.6 16.6-41.2 26.6-67.2 26.6-54.6 0-99-45-99-100.4 0-39.2 22-73 54.2-89.6-1.6-9.8-2.4-19.6-2.4-29.6 0.4-151.6 178.2-274.8 397.4-274.8s397 123.2 397 275c0 10-0.8 19.8-2.2 29.6 32.2 16.6 54.2 50.4 54.2 89.4zM812.2 796.2c29.6 0 53.6-24.4 53.6-54.4s-24-54.4-53.6-54.4c-29.6 0-53.6 24.4-53.6 54.4 0 30 24 54.4 53.6 54.4zM98.4 458c0 35.6 28.6 64.4 63.6 64.4 14.4 0 27.8-5 38.4-13.2-34.6-30.4-60.2-66-74-104.8-16.8 11.8-28 31.4-28 53.6zM772.8 174.2c-69.2-47.8-161.8-74.2-260.8-74.2s-191.6 26.4-260.8 74.2c-65 45-100.8 103.6-100.8 164.8 0 6.4 0.4 13 1.2 19.4 1.4 12 4.4 23.8 8.6 35.4 11.2 31.2 32 60.6 61.4 86.8 8.8 7.8 18.4 15.4 28.8 22.6 0.2 0.2 0.6 0.4 0.8 0.6 69.2 47.8 161.8 74.2 260.8 74.2 99 0 191.6-26.4 260.8-74.2 0.2-0.2 0.6-0.4 0.8-0.6 10.4-7.2 20-14.8 28.8-22.6 29.4-26.2 50.2-55.6 61.4-86.8 4.2-11.6 7-23.4 8.6-35.4 0.8-6.4 1.2-12.8 1.2-19.4 0-61.2-35.8-119.8-100.8-164.8zM897.6 404.6c-13.8 38.8-39.4 74.4-74 104.8 10.6 8.2 24 13.2 38.4 13.2 35 0 63.6-29 63.6-64.4 0-22.4-11.2-42-28-53.6zM641 244.2c-0.4-0.4-48.4-48.4-129-48.8-81.8 0.4-128.8 48.4-129.2 48.8l-25.2-24.8c2.4-2.4 59.2-59 154.4-59.4 95.2 0.4 151.8 57 154.2 59.4l-25.2 24.8z" />
-<glyph unicode="&#xe7a2;" d="M518 417.4l-65.6-191.4h-0.2l-50.8-146.2c3.6-1 7-1.8 10.6-2.8 0.2 0 0.4 0 0.6 0 31.6-8.4 64.8-13 99-13 17 0 33.6 1 49.8 3.6 22.4 2.8 44 7.6 65 14.2 0 0 0 0 0 0 5.2 1.6 10.4 3.4 15.6 5.2-5.6 12-17.6 38.6-18.2 39.8l-105.8 290.6zM161.6 599c-20-45.2-33.6-100.8-33.6-151 0-12.6 0.6-25.2 1.8-37.6 13.8-142.4 105.8-262 232.2-315.8 5.2-2.2 10.6-4.4 16-6.4l-186 510.6c-16 0.6-19-0.4-30.4 0.2zM860.4 609.2c-8.6 18.6-18.8 36.4-30.2 53.2-3.2 4.8-6.8 9.6-10.2 14.4-43 57.6-101.6 102.8-169.8 129.2-42.8 16.8-89.6 26-138.4 26-120.6 0-228.4-56-298.8-143.4-13-16-24.6-33.2-35-51.2 28.4-0.2 63.6-0.2 67.6-0.2 36.2 0 92 4.4 92 4.4 18.8 1.2 20.8-26.2 2.2-28.4 0 0-18.8-2.2-39.6-3.2l125.8-374 75.6 226.6-53.6 147.2c-18.8 1-36.2 3.2-36.2 3.2-18.8 1-16.4 29.6 2 28.4 0 0 57-4.4 91-4.4 36.2 0 92 4.4 92 4.4 18.6 1.2 21-26.2 2.2-28.4 0 0-18.6-2.2-39.4-3.2l124.6-371.2 34.6 115.2c17.4 44.8 26.2 81.8 26.2 111.4 0 42.6-15.4 72.2-28.6 95.2-17.4 28.6-33.8 52.6-33.8 80.8 0 31.8 24 61.4 58 61.4 1.4 0 3 0 4.4 0 52.4 1.4 69.6-50.6 71.8-86 0 0 0-0.8 0-1.2 0.8-14.4 0.2-25 0.2-37.6 0-34.8-6.6-74.2-26.2-123.6l-78-225.6-44.6-131.4c3.6 1.6 7 3.2 10.6 5 113.4 54.8 196 164 213.4 293.4 2.6 17 3.8 34.4 3.8 52 0 57.8-12.8 112.6-35.6 161.6z" />
-<glyph unicode="&#xe7a3;" d="M511.8 832c-211.4 0-383.8-172.4-383.8-384.2 0-211.6 172.4-383.8 383.8-383.8 17 0 33.6 1 49.8 3.6 171.4 22 307.6 157.4 330.6 328.2 2.6 17 3.8 34.4 3.8 52 0 211.8-172.4 384.2-384.2 384.2zM166.8 447.8c0 50 10.8 97.6 30 140.4l164.6-451c-115.2 56-194.6 174.2-194.6 310.6zM556.6 105.4c-14.6-1.8-29.6-2.8-44.8-2.8-33.8 0-66.4 5-97.2 14.2l37.6 110h0.2l65.4 191 106.2-290.8c0.8-1.6 1.8-3.2 2.6-4.6-22.4-8-45.8-13.6-70-17zM559.6 609.8c20.8 1 39.4 3.2 39.4 3.2 18.8 2 16.4 29.6-2.2 28.4 0 0-56-4.4-92-4.4-33.8 0-91 4.4-91 4.4-18.4 1.2-20.8-27.4-2-28.4 0 0 17.4-2.2 36.2-3.2l53.8-147.4-75.6-226.6-125.8 374c21 1 39.6 3.2 39.6 3.2 18.4 2 16.4 29.6-2.2 28.4 0 0-55.8-4.4-92-4.4-6.6 0-14.2 0.2-22.2 0.4 61.6 93.6 167.8 155.4 288.2 155.4 90 0 171.8-34.4 233.2-90.4-1.6 0-3 0.2-4.6 0.2-34 0-58-29.6-58-61.4 0-28.4 16.4-52.4 33.8-80.8 13.2-23 28.6-52.6 28.6-95.2 0-29.6-8.8-66.8-26.2-111.4l-34.6-115.2-124.4 371.2zM685.4 149.4l27.4 79.4 78 225.6c19.8 49.2 26.2 88.6 26.2 123.6 0 12.6-0.8 24.6-2.2 35.6 27-49.2 42.4-105.6 42.4-165.8 0-16-1-31.6-3-47-14.8-107.4-79-199.2-168.8-251.4z" />
-<glyph unicode="&#xe7a4;" d="M642.4 167.4c-23.6 0-44.8 5.6-63 16.6-13.8 8.2-23 19.2-28 32.8-5.2 13.8-7.2 44.6-7.2 92.8v202.4h192v128h-192v224h-123.8c-5.4-43-15-89.4-29-117.2-14-27.8-28-51.6-51.2-71.4-23.2-19.8-51.2-35.8-83.8-46.6v-116.8h96v-280.8c0-38 4-67 11.8-87 8-20 22.2-39 42.8-56.8 20.6-17.8 45.6-31.4 74.6-41 29.2-9.6 62.8-14.4 100.8-14.4 33.4 0 60.6 3.4 89.4 10.2 28.8 6.8 61 18.6 96.4 35.2v131.2c-41.8-27.4-83.6-41.2-125.8-41.2z" />
-<glyph unicode="&#xe7a5;" d="M642.4 167.4c-23.6 0-44.8 5.6-63 16.6-13.8 8.2-23 19.2-28 32.8-5.2 13.8-7.2 44.6-7.2 92.8v202.4h192v128h-192v224h-123.8c-5.4-43-15-89.4-29-117.2-14-27.8-28-51.6-51.2-71.4-23.2-19.8-51.2-35.8-83.8-46.6v-116.8h96v-280.8c0-38 4-67 11.8-87 8-20 22.2-39 42.8-56.8 20.6-17.8 45.6-31.4 74.6-41 29.2-9.6 62.8-14.4 100.8-14.4 33.4 0 60.6 3.4 89.4 10.2 28.8 6.8 61 18.6 96.4 35.2v131.2c-41.8-27.4-83.6-41.2-125.8-41.2zM736 98c-26.2-11.4-50.2-19.8-71.8-24.8-26.2-6.2-51.2-9.2-82.2-9.2-34.4 0-65 4.4-90.8 12.8-25 8.2-46.4 20-63.8 35-16.6 14.4-28 29.2-34 44.4-4.4 11-9.6 33.2-9.6 75.2v280.6 32h-95.8v62.6c26.8 11.2 51 26 72.6 44.4 26.4 22.4 43.2 49.8 59.2 81.4 14.2 28 23.2 68 28.2 99.6h64v-191.4-32.6h192v-64h-192v-32-202.2c0-69.2 4.8-92 9.2-104 7.6-20.6 21.6-37.2 42-49.2 23.4-14 50-21 79.4-21 31.4 0 62.6 6.6 93.4 19.6v-57.2z" />
-<glyph unicode="&#xe7a6;" d="M239.8 287.8c-61.6 0-111.8-50.2-111.8-111.6 0-61.6 50.2-111.2 111.8-111.2 61.8 0 111.8 49.8 111.8 111.2 0 61.4-50 111.6-111.8 111.6zM128 576v-159.8c96 0 188.2-28.4 256-96.2 67.8-67.8 96-159.8 96-256h160c0 279.8-232 512-512 512zM128 832v-159.8c342 0 607.8-266 607.8-608.2h160.2c0 423.4-344 768-768 768z" />
-<glyph unicode="&#xe7a7;" d="M239.8 287.8c-61.6 0-111.8-50.2-111.8-111.6 0-61.6 50.2-111.2 111.8-111.2 61.8 0 111.8 49.8 111.8 111.2 0 61.4-50 111.6-111.8 111.6zM239.8 97c-44 0-79.8 35.6-79.8 79.2 0 43.8 35.8 79.6 79.8 79.6 44 0 79.8-35.8 79.8-79.6 0-43.6-35.8-79.2-79.8-79.2zM128 576v-159.8c96 0 188.2-28.4 256-96.2 67.8-67.8 96-159.8 96-256h160c0 279.8-232 512-512 512zM607 96h-96c-6.2 99.4-42 184.2-104.4 246.6-62.4 62.6-146.6 98.4-246.6 104.6v95.6c52-3.6 104.2-16 153.4-37 57-24.4 108.4-59.2 152.8-103.6 44.4-44.4 79.2-95.8 103.6-152.8 21.2-49.2 33.6-100.6 37.2-153.4zM128 832v-159.8c342 0 607.8-266 607.8-608.2h160.2c0 423.4-344 768-768 768zM582.8 519c-112 112.2-260.8 177-422.8 184.6v95.8c380-16.4 687-323 703.4-703.4h-96.4c-7.6 161.8-72.4 311-184.2 423z" />
-<glyph unicode="&#xe7a8;" d="M512 896c-247.4 0-448-205.6-448-459.4 0-203 128.4-375 306.4-435.8 22.4-4.2 30.6 10 30.6 22.2 0 11-0.4 39.8-0.6 78.2-124.6-27.8-151 61.6-151 61.6-20.4 53-49.8 67.2-49.8 67.2-40.6 28.6 3 28 3 28 45-3.2 68.6-47.4 68.6-47.4 40-70.2 104.8-50 130.4-38.2 4 29.6 15.6 50 28.4 61.4-99.4 11.6-204 51-204 227 0 50.2 17.4 91.2 46 123.2-4.6 11.6-20 58.4 4.4 121.6 0 0 37.6 12.4 123.2-47 35.8 10.2 74 15.2 112.2 15.4 38-0.2 76.4-5.2 112.2-15.4 85.6 59.4 123 47 123 47 24.4-63.2 9-110 4.4-121.6 28.6-32.2 46-73.2 46-123.2 0-176.4-104.8-215.2-204.6-226.6 16-14.2 30.4-42.2 30.4-85 0-61.4-0.6-111-0.6-126 0-12.2 8-26.6 30.8-22 178.4 60.6 306.6 232.6 306.6 435.4 0 253.8-200.6 459.4-448 459.4z" />
-<glyph unicode="&#xe7a9;" d="M512 863.4c56 0 110.4-11.2 161.6-33.4 49.6-21.4 94-52.2 132.2-91.4 38.2-39.2 68.4-85 89.4-135.8 21.8-52.8 32.8-108.8 32.8-166.6 0-91.6-27.8-179-80.4-252.6-25.2-35.4-55.6-66.4-90-92.4-31.6-23.8-66-42.6-102.4-56.4 0 3.8 0 8.2 0 13 0.2 23.8 0.4 59.6 0.4 100.8 0 24.8-4 45-9.8 61 74.4 16.6 184 67.4 184 250.8 0 49.2-14.2 93-42.4 130.2 6.2 25.8 11 71.2-10.2 126l-5.4 14.2-14.4 4.8c-3 1-9.6 2.6-20 2.6-23 0-61.8-7.8-119-45.2-34 8.4-69.6 13.2-106.2 13.2h-0.4c-36.6 0-72.4-4.8-106.2-13.2-57.2 37.4-96 45.4-119 45.4-10.4 0-17-1.8-20-2.8l-14.4-4.8-5.4-14.2c-21.2-55-16.4-100.4-10.2-126-28.2-37.4-42.4-81.2-42.4-130.2 0-99.2 32-159.8 73.2-197-16.2 13.2-37.2 24.2-62.4 26h-2.6c-26.2 0-44.6-10.8-50.4-29.4-9.4-29.6 19.6-50 29.2-56.8l1-1.2 3-1.2c3.2-2 20.2-14 33.8-49 4-12.4 12.6-29 27.2-44.4-26.2 22.4-49.6 48-69.8 76.2-52.6 73.4-80.4 160.8-80.4 252.4 0 57.8 11 113.8 32.8 166.6 21 51 51 96.6 89.4 135.8 38.2 39.2 82.8 70 132.2 91.4 51.2 22.2 105.6 33.6 161.6 33.6M273.4 258c33.6-28.2 72.6-41.8 104.6-49-1.6-4.4-3-9-4.2-13.8-6.8-2-15-3.6-23.4-3.6-21.8 0-38 10.8-51.2 33.8-4.8 9.2-13.6 21.4-25.8 32.6M280.8 80.8c19.6-10.6 44.2-17.6 74.4-17.6 4.4 0 8.8 0.2 13.4 0.4 0-5.6 0-11 0.2-15.8 0-4.8 0-9.2 0.2-13-31.2 11.6-60.6 27-88.2 46M512 895.4c-247.4 0-448-205.8-448-459.4 0-203 128.4-375 306.4-435.8 2.8-0.6 5.2-0.8 7.6-0.8 16.6 0 23 12.2 23 22.8 0 11-0.4 39.8-0.6 78.2-16.8-3.8-31.8-5.4-45.2-5.4-86.2 0-105.8 67-105.8 67-20.4 53-49.8 67.6-49.8 67.6-39 27.4-0.2 28.4 2.8 28.4 0.2 0 0.2 0 0.2 0 45-4 68.6-47.8 68.6-47.8 22.4-39.2 52.4-50.4 79.2-50.4 21 0 40 6.8 51.2 12 4 29.6 15.6 49.8 28.4 61.4-99.4 11.6-204 51-204 227 0 50.2 17.4 91.2 46 123.2-4.6 11.6-20 58.4 4.4 121.6 0 0 3.2 1 10 1 16.2 0 52.8-6.2 113.2-48.2 35.8 10.2 74 15.2 112.2 15.4 38-0.2 76.4-5.2 112.2-15.4 60.4 42 97 48.2 113.2 48.2 6.8 0 10-1 10-1 24.4-63.2 9-110 4.4-121.6 28.6-32.2 46-73.2 46-123.2 0-176.4-104.8-215.2-204.6-226.6 16-14.2 30.4-42.2 30.4-85 0-61.4-0.6-111-0.6-126 0-10.8 6.2-23 22.8-23 2.4 0 5.2 0.2 8 0.8 178.2 60.6 306.4 232.8 306.4 435.6 0 253.6-200.6 459.4-448 459.4v0z" />
-<glyph unicode="&#xe7aa;" d="M512 832c-212 0-384-172-384-384 0-212.2 172-384 384-384s384 171.8 384 384c0 212-172 384-384 384zM512 129c-176.2 0-319 142.8-319 319s142.8 319 319 319c176.2 0 319-142.8 319-319 0-176.2-142.8-319-319-319zM612.6 466.6c46.8 4.4 101.8 5.8 154.4 4.8-4.6 50.8-24 97.4-54 135.2-33-29.8-76-56.2-126.6-78 9.2-20 17.8-40.8 26.2-62zM670.8 648.8c-43.6 34.6-98.8 55.2-158.8 55.2-10.2 0-20.4-0.6-30.4-1.8 27.6-35.4 53.4-75.2 77.2-119 43.4 18.4 81.2 40.6 112 65.6zM411.8 683.6c-68.2-29-121.4-86.8-144-158.2 82.2 1.4 159.2 14 226.8 34.6-25.2 46-53.2 87.4-82.8 123.6zM766 415.6c-44.6 1.2-92 0.4-133.8-3 8.2-24.6 16.2-49.8 23-75.8 7.6-29.2 14-58.2 19.2-86.8 49.2 40.6 83.2 99.2 91.6 165.6zM516 447.8c7.8 3.2 17.6 6 28.6 8.6-6.8 16.6-14.2 32.8-21.6 48.6-78.2-25.2-169.2-40.6-266.6-42.6-0.2-4.8-0.4-9.6-0.4-14.6 0-58.2 19.4-111.8 52-154.8 49.8 65 121.8 118.6 208 154.8zM565.2 403.6c-13.8-3-25.8-6.4-34.8-10.6-74.2-33.6-136.6-83.2-180.8-143 44.2-36.4 100.8-58 162.4-58 37 0 72 7.8 103.6 21.8-5.4 30.2-12 60.6-20 91.4-8.8 33.8-19.2 66.8-30.4 98.4z" />
-<glyph unicode="&#xe7ab;" d="M512 832c-212 0-384-172-384-384 0-212.2 172-384 384-384s384 171.8 384 384c0 212-172 384-384 384zM755.8 655c43.2-50.8 70.6-115.2 75.4-185.8-69.2 3.6-152 3.6-218.4-2.6-8.4 21.2-17 42-26.4 62 76.6 33.2 135.6 76.8 169.4 126.4zM512 768c77.6 0 148.8-27.6 204.2-73.6-34.8-44-89.4-82.2-157.4-111.2-37.2 68.8-80 128-125.6 174.6 25.4 6.4 51.6 10.2 78.8 10.2zM367.2 733c46.2-46 89.6-104.6 127.6-173.2-72.2-22-155-34.6-243.4-34.6-16.8 0-33.2 0.6-49.4 1.6 23 90.2 84 165 165.2 206.2zM192.6 463.2c18.2-0.8 36.6-1.2 55.2-1 100.8 1.2 194.6 17 275.2 42.8 7.6-15.8 14.8-32 21.6-48.6-11-2.6-20.8-5.4-28.6-8.6-110.2-46.2-197-120.8-244-211-49.6 56.4-80 130.2-80 211.2 0 5.2 0.2 10.2 0.6 15.2zM512 128c-74 0-142 25.2-196.2 67.4 42.6 84.4 118.6 154.2 214.4 197.6 9 4.2 21 7.6 34.8 10.6 11.4-31.6 21.6-64.4 30.6-98.4 13.8-53 23.6-105.4 29.6-156.2-35.2-13.4-73.2-21-113.2-21zM685 179c-6 51.4-15.8 104.2-29.8 157.8-6.8 26-14.6 51.2-23 75.8 62.8 5.2 138 4.4 197.8 0-10.8-98.2-66-182.6-145-233.6z" />
-<glyph unicode="&#xe7ac;" d="M484.2 408.8l-36.4 27.4-0.2 0.2c-11.6 9.2-20 16.6-20 29.4 0 14 10 23.6 21.8 34.8l1 0.8c40 30.4 89.4 68.6 89.4 149.2 0 53.8-23.8 89.4-46.6 115.4h26l120.8 66h-267c-50.6 0-125.4-6.4-189.2-57.2l-0.2-0.6c-43.6-36-69.6-89-69.6-141.2 0-42.4 17.4-84.4 47.8-114.8 42.8-43.2 96.6-52.2 134.2-52.2 3 0 6 0 9 0.2-1.6-6-2.4-12.6-2.4-20.6 0-21.8 7.2-38.6 16.2-52.4-48-3.8-116.2-13-169.8-44.6-78.8-45.4-85-112-85-131.2 0-76.4 71.4-153.6 231-153.6 183.2 0 279 99.6 279 198 0 74.2-45.6 111.2-89.8 147zM233.4 680.2c0 26.8 6 47 18.6 61.8 13 15.8 36.4 26.2 58 26.2 39.8 0 65.8-30 80.8-55.2 18.4-31 29.8-72.2 29.8-107.2 0-9.8 0-40-20.4-59.6-14-13.4-37.4-22.8-57.2-22.8-41 0-67 29.4-81.4 54-20.8 35.6-28.2 76.4-28.2 102.8zM475.6 224c0-54.8-50.4-89-131.6-89-96.2 0-160.6 41.2-160.6 102.6 0 52.2 43 73.6 75.6 85 37.8 12.2 88.6 14.6 100.2 14.6 7.8 0 12.2 0 17.4-0.4 73.2-50.4 99-72.2 99-112.8zM804 676v156h-68v-156h-160v-68h160v-162h68v162h156v68z" />
-<glyph unicode="&#xe7ad;" d="M447 795.8c23.6-19.2 72.8-59.4 72.8-136 0-74.6-43-109.8-86.2-143-13.4-13.2-28.8-27.2-28.8-49.4 0-22.2 15.4-34.4 26.6-43.4l37-28.2c45.2-37.2 86.2-71.6 86.2-141.2 0-94.8-93.4-190.4-270-190.4-148.8-0.2-220.6 69.4-220.6 144 0 36.2 18.4 87.6 79 123 63.6 38.2 150 43.4 196 46.4-14.4 18.2-30.8 37.4-30.8 68.6 0 17.2 5.2 27.2 10.2 39.4-11.2-1-22.6-2-32.8-2-108.8 0-170.4 79.6-170.4 158.2 0 46.4 21.6 97.8 65.8 135 58.6 47.2 128.4 55.2 183.8 55.2h211.4l-65.6-36.2h-63.6zM374 348.2c-8.2 1-13.4 1-23.6 1-9.2 0-64.6-2-107.8-16-22.6-8-88.2-32.2-88.2-103.8 0-71.6 70.8-123 180.6-123 98.6 0 150.8 46.4 150.8 108.8 0 51.4-33.8 78.6-111.8 133M403.8 539.8c23.6 23.2 25.6 55.4 25.6 73.6 0 72.6-44.2 185.4-129.4 185.4-26.6 0-55.4-13-71.8-33.2-17.4-21.2-22.6-48.4-22.6-74.6 0-67.6 40-179.4 128.4-179.4 25.6-0.2 53.2 12 69.8 28.2M960 675.4h-156.6v156.4h-35.4v-156.4h-159.4v-35.6h159.4v-161.8h35.4v161.8h156.6z" />
-<glyph unicode="&#xe7ae;" d="M576 576v76.2c0 34.4 7.6 51.8 61 51.8h67v128h-111.8c-137 0-182.2-62.8-182.2-170.6v-85.4h-90v-128h90v-384h166v384h112.8l15.2 128h-128z" />
-<glyph unicode="&#xe7af;" d="M576 576v76.2c0 34.4 7.6 51.8 61 51.8h67v128h-111.8c-137 0-182.2-62.8-182.2-170.6v-85.4h-90v-128h90v-384h166v384h112.8l15.2 128h-128zM660.4 480h-116.4v-31-353h-102v353 31h-90v64h90v33 84.4c0 49 10.8 82.4 31 103.6 22.4 24 62.2 35 119.2 35h79.8v-64h-35c-24 0-55-2.2-74.2-23.4-16.2-18-18.8-40.2-18.8-60.2v-75.2-33.2h124l-7.6-64z" />
-<glyph unicode="&#xe7b0;" d="M984 741c-34.8-15.4-72-25.8-111.2-30.6 40 24 70.8 62 85.2 107.2-37.4-22.2-78.8-38.4-123-47-35.4 37.8-85.8 61.4-141.4 61.4-107 0-193.6-86.8-193.6-193.8 0-15.2 1.6-30 5-44.2-161 8-303.8 85.2-399.2 202.6-16.6-28.6-26.2-62-26.2-97.4 0-67.2 34.2-126.6 86.2-161.4-31.8 0.8-61.8 9.6-87.8 24.2 0-0.8 0-1.6 0-2.4 0-94 66.8-172.2 155.4-190-16.2-4.4-33.4-6.8-51-6.8-12.4 0-24.6 1.2-36.4 3.6 24.6-77 96.2-133 181-134.6-66.2-52-149.8-83-240.6-83-15.6 0-31 1-46.2 2.8 85.6-55.6 187.4-87.6 296.6-87.6 356.4 0 551.2 295.4 551.2 551.6 0 8.4-0.2 16.8-0.6 25 37.8 27.4 70.6 61.6 96.6 100.4z" />
-<glyph unicode="&#xe7b1;" d="M693.6 800c44.6 0 87.6-18.6 118-51.2l12.2-13 17.4 3.4c9 1.8 17.8 3.8 26.6 6.2-2-2.8-11.4-12.2-22-21.6-9-8-35.6-33-35.6-33s26-8.2 42.2-10 34.8 1.2 37.8 1.6c-5.6-4.6-15.6-11.6-21.6-15.8l-14-10.2 0.8-17.2c0.4-7.6 0.6-15.6 0.6-23.6 0-60.4-11.8-123.6-34-183-23.4-62.4-57-118.8-100-167.6-46-52.2-100.4-93-162.2-121.6-67.6-31.4-142.6-47.2-223-47.2-57.8 0-114.8 9.6-169 28.4 19.8 3.8 39.2 9.2 58.2 15.8 43.4 15.2 83.8 37.4 120.2 66l70.6 55.4-89.8 1.6c-52.2 1-99.4 26.8-128.6 67.8 14.6 1 29 3.6 43 7.4l121.4 40.4-123.4 21.8c-59.2 11.8-105.6 55.8-122.6 111.6 15.6-4 30.8-5.6 47.8-6.6 0 0 63.6-2.8 111.6 0.2-26 12.4-92.8 58.4-92.8 58.4-45 30.2-72 80.4-72 134.8 0 12.8 1.6 25.6 4.4 38 43.8-44.8 94-82.2 150.2-111 74-38.2 153.8-59.6 237.2-63.8l42.4-2.2-9.6 41.4c-2.8 11.8-4.2 24.2-4.2 37 0 88.8 72.6 161.4 161.8 161.4M693.6 832c-107 0-193.6-86.8-193.6-193.8 0-15.2 1.6-30 5-44.2-161 8-303.8 85.2-399.2 202.6-16.6-28.6-26.2-62-26.2-97.4 0-67.2 34.2-126.6 86.2-161.4-31.8 0.8-61.8 9.6-87.8 24.2 0-0.8 0-1.6 0-2.4 0-94 66.8-172.2 155.4-190-16.2-4.4-33.4-6.8-51-6.8-12.4 0-24.6 1.2-36.4 3.6 24.6-77 96.2-133 181-134.6-66.2-52-149.8-83-240.6-83-15.6 0-31 1-46.2 2.8 85.6-55.6 187.4-87.6 296.6-87.6 356.4 0 551.2 295.4 551.2 551.6 0 8.4-0.2 16.8-0.6 25 37.8 27.4 70.6 61.4 96.6 100.4-34.8-15.4-72-25.8-111.2-30.6 40 24 70.8 62 85.2 107.2-37.4-22.2-78.8-38.4-123-47-35.4 37.8-85.8 61.4-141.4 61.4v0z" />
-<glyph unicode="&#xe7b2;" d="M512 896c-247.4 0-448-200.6-448-448 0-183.4 110.4-341 268.2-410.4-1.2 31.2-0.2 68.8 7.8 102.8 8.6 36.4 57.6 244.2 57.6 244.2s-14.4 28.6-14.4 70.8c0 66.4 38.4 116 86.4 116 40.8 0 60.4-30.6 60.4-67.2 0-41-26.2-102.2-39.6-159-11.2-47.6 23.8-86.2 70.8-86.2 84.8 0 142 109 142 238.2 0 98.2-66.2 171.6-186.4 171.6-135.8 0-220.6-101.4-220.6-214.6 0-39 11.6-66.6 29.6-87.8 8.2-9.8 9.4-13.8 6.4-25-2.2-8.2-7-28-9.2-36-3-11.4-12.2-15.4-22.4-11.2-62.6 25.6-91.8 94-91.8 171.2 0 127.2 107.4 279.8 320.2 279.8 171 0 283.6-123.8 283.6-256.6 0-175.8-97.8-307-241.8-307-48.4 0-93.8 26.2-109.4 55.8 0 0-26-103.2-31.6-123.2-9.4-34.6-28-69-45-96 40.2-11.8 82.8-18.4 127-18.4 247.4 0 448 200.6 448 448 0.2 247.6-200.4 448.2-447.8 448.2z" />
-<glyph unicode="&#xe7b3;" d="M512 896c-247.4 0-448-200.6-448-448s200.6-448 448-448 448 200.6 448 448-200.6 448-448 448zM783.6 176.4c-72.6-72.4-169-112.4-271.6-112.4-32.4 0-64.2 4-94.8 11.8 5.6 12.6 10.4 25.6 14 38.6 5.6 20 31.6 123.2 31.6 123.2 15.6-29.6 61-55.8 109.4-55.8 144 0 241.8 131.2 241.8 307 0 132.8-112.6 256.6-283.6 256.6-212.8 0-320.2-152.6-320.2-279.8 0-77 29.2-145.6 91.8-171.2 10.2-4.2 19.4-0.2 22.4 11.2 2 7.8 7 27.8 9.2 36 3 11.2 1.8 15.2-6.4 25-18 21.4-29.6 48.8-29.6 87.8 0 113.2 84.6 214.6 220.6 214.6 120.2 0 186.4-73.4 186.4-171.6 0-129.2-57.2-238.2-142-238.2-46.8 0-82 38.8-70.8 86.2 13.4 56.8 39.6 118 39.6 159 0 36.6-19.6 67.2-60.4 67.2-48 0-86.4-49.6-86.4-116 0-42.2 14.4-70.8 14.4-70.8s-49-207.8-57.6-244.2c-2.6-11-4.4-22.2-5.8-33.6-34.6 18-66.6 41.2-94.8 69.6-72.8 72.4-112.8 168.8-112.8 271.4s40 199 112.4 271.6c72.6 72.4 169 112.4 271.6 112.4s199-40 271.6-112.4c72.4-72.6 112.4-169 112.4-271.6s-40-199-112.4-271.6z" />
-<glyph unicode="&#xe7b4;" d="M821 401.6c-10 23-25.4 43.2-56.2 60.2-16.4 9-32.2 15.6-50.8 20 10.8 5 20 10.8 32.6 22 15 13.2 26.2 31.4 31.2 46.6 5.2 15 8.2 36 7 56.4-2.2 33.6-8.8 66.2-26.4 89.6-17.6 23.4-42.4 41.4-75.2 54-25.2 9.6-51 15.6-91 17.8v127.8h-80v-128h-64v128h-82v-128h-174.2v-96h55.8c17.4 0 29.2-1.6 35.2-4.6 6.2-3 10.6-7 13-12 2.6-5 3.8-16.8 3.8-35v-346.4c0-18-1.2-29.6-3.8-34.8-2.6-5.2-4-9.8-10.2-12.6-6.2-2.8-6.4-2.6-23.6-2.6h-52.8l-17.4-96h174v-128h82v128h64v-128h80v128.8c52 2.6 89 9.4 118.8 20.6 38.6 14.4 68.2 35.4 89.4 63 21.2 27.6 29.8 69.8 31.6 102.4 1.4 29-1.8 66.4-10.8 86.8zM448 660h64v-148h-64v148zM448 236v180h64v-180h-64zM592 652.2c12-5 19.8-15 27.6-25.4 8.6-11.4 13-26.6 13-42.8 0-15.6-5.8-29-15-41-7.6-9.8-13.6-16.6-25.6-22.2v131.4zM649.6 278.8c-15.6-13.8-24.6-20.2-44.2-27.6-4-1.6-9.4-2.8-13.4-3.8v165.6c10-1.6 15.2-3.6 22.6-6.8 15.6-6.6 30.4-13.8 39.6-26.4 9.2-12.6 16-31.2 16-49.4 0-21.8-5.6-38.4-20.6-51.6z" />
-<glyph unicode="&#xe7b5;" d="M559.4 864v-94-30.2l30.2-1.6c33.8-1.8 57.6-6.6 81.4-15.8 27.6-10.6 48.4-25.2 62.2-43.4 11.4-15.2 18-38.8 20-72.4 1.2-17.6-2-34.2-5.2-44-3-8.8-10.6-22.6-22.2-32.8-10.8-9.6-17.2-13.4-24.6-16.8l-84.2-38.6 90-21.6c14.8-3.6 28-8.8 42.8-17 26.4-14.6 36-30.2 42.4-45 5.8-13.4 9.2-44.4 7.8-72.4-1.4-26.8-8.8-63-25.2-84.6-17.2-22.4-42.6-40.2-75.6-52.6-27.2-10.2-62.2-16.2-109-18.6l-30.4-1.4v-30.4-98.8h-16v96 32h-127.8v-32-96h-18v96 32h-166.4l6 32h25.6c17.2 0 24.2 0.8 35 6 0.4 0.2 0.8 0.4 1.4 0.6 16.2 7.4 22 21.2 24.4 27.2 0.2 0.6 0.6 1.4 0.6 1.6 5.8 11.8 6 26.2 6 48.8v356c0 23.4-0.2 27.2-6.2 39-5.8 11.6-14.6 20.2-26.8 26-11.8 5.6-26.4 6.8-49 6.8h-25.8v32h175.2v32 96h18v-96-32h127.6v32 96h15.8M591.4 896h-79.8v-128h-63.6v128h-81.8v-128h-174.2v-96h56.8c17.4 0 29-0.6 35.2-3.6s9.4-6.6 12-11.6c2.6-5 2.8-6.2 2.8-24.6v-356c0-18-0.2-29.4-1.8-35.2-2.4-5.4-4.4-10.4-10.6-13.2-6.2-2.8-5.8-3.8-23.2-3.8h-54.8l-16.4-96h174.2v-128h81.8v128h63.6v-128h79.8v130.8c52 2.6 88.8 9.4 118.6 20.6 38.6 14.4 68.6 35.4 89.8 63 21 27.6 30 69.8 31.8 102.4 1.6 29-1.4 66.4-10.4 86.8-10 23-25.4 43.2-56.2 60.2-16.2 9-32.2 15.6-50.8 20 10.8 5 19.8 10.8 32.6 22 15 13.2 26 31.4 31.2 46.6 5.2 15 8.2 36 7 56.4-2.2 33.6-8.8 66.2-26.4 89.6-17.6 23.4-43.4 41.4-76.2 54-25.2 9.6-51 15.6-91 17.8v125.8 0zM512 660h-64v-148h64v148zM512 416h-64v-180h64v180 0zM592 652.2v-131.2c12 5.8 19 13.6 26.6 23.4 9.2 12 14 25.8 14 41.4 0 16.2-4.8 30-13.4 41.6-7.8 10.2-15.2 19.8-27.2 24.8v0zM592 412.8v-165.6c4 1.2 7.6 1.6 11.6 3.2 19.6 7.6 31.6 15.8 47.2 29.4 15 13.2 19.4 31.8 19.4 53.2 0 18.2-6.6 33.8-15.8 46.4-9.2 12.6-23.4 19.8-38.8 26.4-7.4 3.4-13.6 5.4-23.6 7v0z" />
-</font></defs></svg> \ No newline at end of file
+<font id="Ionicons" horiz-adv-x="448" >
+ <font-face
+ font-family="Ionicons"
+ font-weight="500"
+ font-stretch="normal"
+ units-per-em="512"
+ panose-1="2 0 6 3 0 0 0 0 0 0"
+ ascent="448"
+ descent="-64"
+ bbox="-0.54049 -64 512.487 448"
+ underline-thickness="25.6"
+ underline-position="-51.2"
+ unicode-range="U+F100-F4F7"
+ />
+ <missing-glyph />
+ <glyph glyph-name="ion-alert-circled" unicode="&#xf100;"
+d="M445 26c3 -5 5 -13 2 -18s-8 -8 -14 -8h-418c-6 0 -11 3 -14 8s-1 13 2 18l207 349c3 5 8 9 14 9s11 -4 14 -9zM256 48v48h-64v-48h64zM256 128v144h-64v-144h64z" />
+ <glyph glyph-name="ion-alert" unicode="&#xf101;" horiz-adv-x="128"
+d="M128 -32h-128v96h128v-96zM112 128h-96l-16 288h128z" />
+ <glyph glyph-name="ion-android-add-circle" unicode="&#xf359;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM315 171v42h-86v86h-42v-86h-86v-42h86v-86h42v86h86z" />
+ <glyph glyph-name="ion-android-add" unicode="&#xf2c7;" horiz-adv-x="320"
+d="M320 171h-139v-139h-42v139h-139v42h139v139h42v-139h139v-42z" />
+ <glyph glyph-name="ion-android-alarm-clock" unicode="&#xf35a;" horiz-adv-x="428"
+d="M428 323l-28 -33l-98 82l28 33zM125 373l-97 -83l-28 33l97 83zM225 275v0v-111l85 -50l-16 -27l-101 61v127h32zM214 360c106 0 193 -86 193 -191s-87 -191 -193 -191c-107 0 -193 86 -193 191s86 191 193 191zM214 20c82 0 150 66 150 149c0 82 -68 149 -150 149
+s-150 -67 -150 -149s68 -149 150 -149z" />
+ <glyph glyph-name="ion-android-alert" unicode="&#xf35b;" horiz-adv-x="416"
+d="M208 400c114 0 208 -94 208 -208s-94 -208 -208 -208s-208 94 -208 208s94 208 208 208zM232 88v40h-48v-40h48zM232 176v128h-48v-128h48z" />
+ <glyph glyph-name="ion-android-apps" unicode="&#xf35c;" horiz-adv-x="320"
+d="M0 272v80h80v-80h-80zM120 32v80h80v-80h-80zM0 32v80h80v-80h-80zM0 152v80h80v-80h-80zM120 152v80h80v-80h-80zM240 352h80v-80h-80v80zM120 272v80h80v-80h-80zM240 152v80h80v-80h-80zM240 32v80h80v-80h-80z" />
+ <glyph glyph-name="ion-android-archive" unicode="&#xf2c9;" horiz-adv-x="416"
+d="M406 348c7 -7 10 -17 10 -29v-289c0 -25 -21 -46 -46 -46h-324c-25 0 -46 21 -46 46v289c0 12 3 22 10 29l33 39c6 8 16 13 26 13h278c10 0 20 -5 26 -13zM208 65l127 127h-81v46h-92v-46h-81zM49 354h317l-22 23h-277z" />
+ <glyph glyph-name="ion-android-arrow-back" unicode="&#xf2ca;" horiz-adv-x="342"
+d="M342 213v-42h-260l119 -120l-30 -30l-171 171l171 171l31 -30l-120 -120h260z" />
+ <glyph glyph-name="ion-android-arrow-down" unicode="&#xf35d;" horiz-adv-x="342"
+d="M192 363v-260l120 120l30 -31l-171 -171l-171 171l30 30l120 -119v260h42z" />
+ <glyph glyph-name="ion-android-arrow-dropdown-circle" unicode="&#xf35e;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 128l96 96h-192z" />
+ <glyph glyph-name="ion-android-arrow-dropdown" unicode="&#xf35f;" horiz-adv-x="256"
+d="M0 256h256l-128 -128z" />
+ <glyph glyph-name="ion-android-arrow-dropleft-circle" unicode="&#xf360;" horiz-adv-x="416"
+d="M416 192c0 -115 -93 -208 -208 -208s-208 93 -208 208s93 208 208 208s208 -93 208 -208zM144 192l96 -96v192z" />
+ <glyph glyph-name="ion-android-arrow-dropleft" unicode="&#xf361;" horiz-adv-x="128"
+d="M128 320v-256l-128 128z" />
+ <glyph glyph-name="ion-android-arrow-dropright-circle" unicode="&#xf362;" horiz-adv-x="416"
+d="M208 -16c-115 0 -208 93 -208 208s93 208 208 208s208 -93 208 -208s-93 -208 -208 -208zM176 96l96 96l-96 96v-192z" />
+ <glyph glyph-name="ion-android-arrow-dropright" unicode="&#xf363;" horiz-adv-x="128"
+d="M0 320l128 -128l-128 -128v256z" />
+ <glyph glyph-name="ion-android-arrow-dropup-circle" unicode="&#xf364;" horiz-adv-x="416"
+d="M416 192c0 -115 -93 -208 -208 -208s-208 93 -208 208s93 208 208 208s208 -93 208 -208zM304 160l-96 96l-96 -96h192z" />
+ <glyph glyph-name="ion-android-arrow-dropup" unicode="&#xf365;" horiz-adv-x="256"
+d="M0 128l128 128l128 -128h-256z" />
+ <glyph glyph-name="ion-android-arrow-forward" unicode="&#xf30f;" horiz-adv-x="342"
+d="M0 171v42h260l-119 120l30 30l171 -171l-171 -171l-31 30l120 120h-260z" />
+ <glyph glyph-name="ion-android-arrow-up" unicode="&#xf366;" horiz-adv-x="342"
+d="M192 21h-42v260l-120 -119l-30 30l171 171l171 -171l-30 -31l-120 120v-260z" />
+ <glyph glyph-name="ion-android-attach" unicode="&#xf367;" horiz-adv-x="235"
+d="M203 320h32v-235c0 -65 -53 -117 -118 -117s-117 52 -117 117v246c0 47 38 85 85 85s86 -38 86 -85v-246c0 -30 -24 -53 -54 -53s-53 23 -53 53v203h32v-203c0 -12 9 -21 21 -21s22 9 22 21v246c0 30 -24 53 -54 53s-53 -23 -53 -53v-246c0 -47 38 -85 85 -85
+s86 38 86 85v235z" />
+ <glyph glyph-name="ion-android-bar" unicode="&#xf368;" horiz-adv-x="384"
+d="M171 171l-171 170v43h384v-43l-171 -170v-131h107v-40h-256v40h107v131zM96 299h192l43 42h-278z" />
+ <glyph glyph-name="ion-android-bicycle" unicode="&#xf369;"
+d="M299 317c-19 0 -34 14 -34 33s15 34 34 34s33 -15 33 -34s-14 -33 -33 -33zM355 187c51 0 93 -43 93 -94s-42 -93 -93 -93s-94 42 -94 93s43 94 94 94zM355 28c36 0 65 29 65 65s-29 66 -65 66s-66 -30 -66 -66s30 -65 66 -65zM274 224l-30 45l-43 -45l39 -32v-112h-32
+v86l-61 38c-9 6 -19 15 -19 27c0 8 3 17 9 23l72 69c6 6 14 9 22 9c11 0 22 -7 28 -16l34 -60h59v-32h-78zM93 187c51 0 94 -43 94 -94s-43 -93 -94 -93s-93 42 -93 93s42 94 93 94zM93 28c36 0 66 29 66 65s-30 66 -66 66s-65 -30 -65 -66s29 -65 65 -65z" />
+ <glyph glyph-name="ion-android-boat" unicode="&#xf36a;"
+d="M52 35l-51 139c-2 6 -1 12 1 17s8 8 13 10l38 13v98c0 23 20 43 43 43h64l16 53h96l16 -53h64c23 0 43 -20 43 -43v-98l38 -13c5 -2 11 -5 13 -10s3 -12 1 -17l-51 -139h-1c-34 0 -65 20 -86 43c-21 -23 -51 -43 -85 -43s-64 19 -85 42c-21 -23 -52 -42 -86 -42h-1z
+M96 312v-84l128 41l128 -41v84h-256zM309 40c0 0 59 -64 107 -64h-21c-30 0 -59 12 -86 26c-53 -28 -117 -28 -170 0c-27 -14 -56 -26 -86 -26h-21c49 0 107 64 107 64c52 -36 118 -36 170 0z" />
+ <glyph glyph-name="ion-android-bookmark" unicode="&#xf36b;" horiz-adv-x="288"
+d="M248 384c22 0 40 -18 40 -40v-344l-144 64l-144 -64v344c0 22 18 40 40 40h208z" />
+ <glyph glyph-name="ion-android-bulb" unicode="&#xf36c;"
+d="M224 278c-25 0 -50 -10 -68 -28s-28 -43 -28 -68c0 -34 18 -66 48 -83l16 -10v-18v-71h64v71v18l16 10c15 8 27 20 35 34c9 15 13 31 13 49c0 25 -10 50 -28 68s-43 28 -68 28zM245 416v0v-64h-42v64h42zM374 362v0l30 -30l-38 -38l-30 30zM74 362v0l38 -38l-30 -30
+l-38 38zM224 310v0c70 0 128 -58 128 -128c0 -48 -26 -89 -64 -111v-103h-128v103c-38 22 -64 64 -64 111c0 70 58 128 128 128zM448 203v0v-42h-64v42h64zM64 203v0v-42h-64v42h64z" />
+ <glyph glyph-name="ion-android-bus" unicode="&#xf36d;" horiz-adv-x="352"
+d="M0 96v204c0 75 82 84 176 84s176 -9 176 -84v-204c0 -18 -14 -24 -27 -36v-39c0 -12 -9 -21 -21 -21h-21c-12 0 -22 9 -22 21v22h-170v-22c0 -12 -10 -21 -22 -21h-21c-12 0 -21 9 -21 21v39c-13 12 -27 17 -27 36zM80 80c18 0 32 14 32 32s-14 32 -32 32
+s-32 -14 -32 -32s14 -32 32 -32zM272 80c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM304 203v106h-256v-106h256z" />
+ <glyph glyph-name="ion-android-calendar" unicode="&#xf2d1;" horiz-adv-x="384"
+d="M304 176v-96h-96v96h96zM272 384h48v-32h24c22 0 40 -18 40 -40v-272c0 -22 -18 -40 -40 -40h-304c-22 0 -40 18 -40 40v272c0 22 18 40 40 40h24v32h48v-32h160v32zM344 40v212h-304v-212h304z" />
+ <glyph glyph-name="ion-android-call" unicode="&#xf2d2;" horiz-adv-x="384"
+d="M363 117c12 0 21 -9 21 -21v-75c0 -12 -9 -21 -21 -21c-201 0 -363 162 -363 363c0 12 9 21 21 21h75c12 0 21 -9 21 -21c0 -27 4 -52 13 -77c2 -7 0 -16 -5 -21l-47 -47c31 -61 80 -110 141 -141l47 47c5 6 14 7 21 5c23 -7 49 -12 76 -12z" />
+ <glyph glyph-name="ion-android-camera" unicode="&#xf2d3;"
+d="M161 168c0 42 21 63 63 63s63 -21 63 -63s-21 -63 -63 -63s-63 21 -63 63zM408 352c11 0 20 -4 28 -12s12 -17 12 -28v-272c0 -11 -4 -20 -12 -28s-17 -12 -28 -12h-368c-11 0 -20 4 -28 12s-12 17 -12 28v272c0 11 4 20 12 28s17 12 28 12h88l32 32h128l32 -32h88z
+M224 56c31 0 57 11 79 33s33 48 33 79s-11 57 -33 79s-48 33 -79 33s-57 -11 -79 -33s-33 -48 -33 -79s11 -57 33 -79s48 -33 79 -33z" />
+ <glyph glyph-name="ion-android-cancel" unicode="&#xf36e;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM312 117l-75 75l75 75l-29 29l-75 -75l-75 75l-29 -29l75 -75l-75 -75l29 -29l75 75l75 -75z" />
+ <glyph glyph-name="ion-android-car" unicode="&#xf36f;" horiz-adv-x="384"
+d="M339 331l45 -118v-160c0 -12 -9 -21 -21 -21h-22c-12 0 -21 9 -21 21v11h-256v-11c0 -12 -9 -21 -21 -21h-22c-12 0 -21 9 -21 21v160l45 118c4 13 16 21 30 21h234c14 0 26 -8 30 -21zM75 128c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM309 128
+c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM43 235h298l-32 85h-234z" />
+ <glyph glyph-name="ion-android-cart" unicode="&#xf370;" horiz-adv-x="416"
+d="M122 70c23 0 41 -18 41 -41s-18 -42 -41 -42s-42 19 -42 42s19 41 42 41zM0 397h68l19 -42h308c11 0 21 -9 21 -20c0 -4 -1 -8 -2 -10l-75 -129c-7 -14 -20 -22 -36 -22h-155l-21 -32s-2 -5 -2 -6c0 -3 2 -5 5 -5h238v-40h-243c-26 0 -45 14 -45 42c0 7 2 15 5 20l31 51
+l-74 151h-42v42zM326 70c23 0 42 -18 42 -41s-19 -42 -42 -42s-41 19 -41 42s18 41 41 41z" />
+ <glyph glyph-name="ion-android-chat" unicode="&#xf2d4;" horiz-adv-x="416"
+d="M344 384c4 0 7 -4 7 -8v-214c0 -4 -3 -9 -7 -9h-187l-90 -89v89h-57c-4 0 -10 5 -10 9v214c0 4 6 8 10 8h334zM408 321c4 0 8 -5 8 -9v-214c0 -4 -4 -9 -8 -9h-57v-89l-90 89h-130l39 39h181c18 0 25 10 25 26v167h32z" />
+ <glyph glyph-name="ion-android-checkbox-blank" unicode="&#xf371;" horiz-adv-x="384"
+d="M341 384c23 0 43 -20 43 -43v-298c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h298z" />
+ <glyph glyph-name="ion-android-checkbox-outline-blank" unicode="&#xf372;" horiz-adv-x="384"
+d="M341 341h-298v-298h298v298zM341 384v0c23 0 43 -20 43 -43v-298c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h298z" />
+ <glyph glyph-name="ion-android-checkbox-outline" unicode="&#xf373;" horiz-adv-x="384"
+d="M105 233l66 -66l183 183l30 -30l-213 -213l-96 96zM341 43v170h43v-170c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h213v-43h-213v-298h298z" />
+ <glyph glyph-name="ion-android-checkbox" unicode="&#xf374;" horiz-adv-x="384"
+d="M341 384c23 0 43 -20 43 -43v-298c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h298zM149 85l192 192l-30 30l-162 -162l-76 77l-30 -30z" />
+ <glyph glyph-name="ion-android-checkmark-circle" unicode="&#xf375;" horiz-adv-x="416"
+d="M123 232l64 -64l179 178l29 -29l-208 -208l-93 93zM374 192h42c0 -114 -94 -208 -208 -208s-208 94 -208 208s94 208 208 208c28 0 54 -6 78 -16l-32 -32c-15 4 -30 6 -46 6c-92 0 -166 -74 -166 -166s74 -166 166 -166s166 74 166 166z" />
+ <glyph glyph-name="ion-android-clipboard" unicode="&#xf376;" horiz-adv-x="384"
+d="M341 368c23 0 43 -20 43 -43v-314c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v314c0 23 20 43 43 43h87c7 28 32 48 62 48s55 -20 62 -48h87zM192 368c-12 0 -21 -9 -21 -21s9 -22 21 -22s21 10 21 22s-9 21 -21 21zM344 8v320h-40v-72h-224v72h-40v-320h304z" />
+ <glyph glyph-name="ion-android-close" unicode="&#xf2d7;" horiz-adv-x="298"
+d="M298 311l-119 -119l119 -119l-30 -30l-119 119l-119 -119l-30 30l119 119l-119 119l30 30l119 -119l119 119z" />
+ <glyph glyph-name="ion-android-cloud-circle" unicode="&#xf377;" horiz-adv-x="416"
+d="M208 400c114 0 208 -94 208 -208s-94 -208 -208 -208s-208 94 -208 208s94 208 208 208zM302 109c29 0 52 23 52 52s-23 52 -52 52h-11c0 46 -37 83 -83 83c-38 0 -71 -26 -80 -62h-3c-34 0 -63 -29 -63 -63s29 -62 63 -62h177z" />
+ <glyph glyph-name="ion-android-cloud-done" unicode="&#xf378;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121zM197 85l141 141l-30 30l-111 -111l-44 45l-30 -30z" />
+ <glyph glyph-name="ion-android-cloud-outline" unicode="&#xf379;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121zM380 72c33 0 60 27 60 60s-27 60 -60 60h-30v10c0 61 -49 110 -110 110c-51 0 -93 -34 -106 -80h-14
+c-44 0 -80 -36 -80 -80s36 -80 80 -80h260z" />
+ <glyph glyph-name="ion-android-cloud" unicode="&#xf37a;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121z" />
+ <glyph glyph-name="ion-android-color-palette" unicode="&#xf37b;" horiz-adv-x="384"
+d="M192 384c106 0 192 -77 192 -171c0 -59 -48 -106 -107 -106h-38c-18 0 -32 -14 -32 -32c0 -9 3 -17 8 -22s9 -12 9 -21c0 -18 -14 -32 -32 -32c-106 0 -192 86 -192 192s86 192 192 192zM75 192c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM139 277
+c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM245 277c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM309 192c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-android-compass" unicode="&#xf37c;"
+d="M224 217c13 0 25 -12 25 -25s-12 -25 -25 -25s-25 12 -25 25s12 25 25 25zM224 416c123 0 224 -101 224 -224s-101 -224 -224 -224s-224 101 -224 224s101 224 224 224zM273 143l85 183l-183 -85l-85 -183z" />
+ <glyph glyph-name="ion-android-contact" unicode="&#xf2d8;" horiz-adv-x="384"
+d="M267 110c59 -18 104 -58 117 -110h-384c13 52 58 92 117 110c22 -13 48 -20 75 -20s53 7 75 20zM192 384c73 0 132 -59 132 -132s-59 -132 -132 -132s-132 59 -132 132s59 132 132 132zM192 153c42 0 78 26 92 63h-184c14 -37 50 -63 92 -63z" />
+ <glyph glyph-name="ion-android-contacts" unicode="&#xf2d9;"
+d="M207 104c47 -14 76 -62 87 -104h-294c11 42 40 90 87 104c18 -10 38 -16 60 -16s42 6 60 16zM147 328c58 0 106 -48 106 -106s-48 -106 -106 -106s-106 48 -106 106s48 106 106 106zM147 141c34 0 62 23 74 51h-148c12 -28 40 -51 74 -51zM291 64c-13 20 -34 43 -60 53
+c11 9 21 23 28 35c13 -5 27 -8 42 -8c22 0 42 6 60 16c47 -14 76 -54 87 -96h-157zM275 248c-8 37 -31 69 -63 87c19 29 52 49 89 49c58 0 106 -48 106 -106s-48 -106 -106 -106c-11 0 -22 2 -32 5c3 8 6 16 7 25c8 -3 16 -4 25 -4c34 0 62 22 74 50h-100z" />
+ <glyph glyph-name="ion-android-contract" unicode="&#xf37d;" horiz-adv-x="384"
+d="M0 77v51h128v-128h-51v77h-77zM77 307v77h51v-128h-128v51h77zM256 0v128h128v-51h-77v-77h-51zM307 307h77v-51h-128v128h51v-77z" />
+ <glyph glyph-name="ion-android-create" unicode="&#xf37e;" horiz-adv-x="384"
+d="M0 80l236 236l80 -80l-236 -236h-80v80zM378 298l-40 -40l-80 80l40 40c9 9 20 9 29 0l51 -51c9 -9 9 -20 0 -29z" />
+ <glyph glyph-name="ion-android-delete" unicode="&#xf37f;" horiz-adv-x="320"
+d="M32 43v245h256v-245c0 -23 -20 -43 -43 -43h-170c-23 0 -43 20 -43 43zM320 352v-32h-320v32h80l27 32h106l27 -32h80z" />
+ <glyph glyph-name="ion-android-desktop" unicode="&#xf380;"
+d="M405 416c23 0 43 -20 43 -43v-282c0 -23 -20 -43 -43 -43h-138l42 -48v-32h-170v32l42 48h-138c-23 0 -43 20 -43 43v282c0 23 20 43 43 43h362zM405 128v245h-362v-245h362z" />
+ <glyph glyph-name="ion-android-document" unicode="&#xf381;" horiz-adv-x="320"
+d="M192 400l128 -128v-248c0 -22 -18 -40 -40 -40h-240c-22 0 -40 18 -40 40v336c0 22 18 40 40 40h152zM176 256h112l-112 112v-112z" />
+ <glyph glyph-name="ion-android-done-all" unicode="&#xf382;" horiz-adv-x="512"
+d="M388 308l-140 -139l-31 31l140 139zM481 339l31 -31l-264 -263l-122 123l30 31l92 -91zM0 168l32 31l122 -123l-31 -31z" />
+ <glyph glyph-name="ion-android-done" unicode="&#xf383;" horiz-adv-x="384"
+d="M122 108l230 230l32 -31l-262 -261l-122 122l32 31z" />
+ <glyph glyph-name="ion-android-download" unicode="&#xf2dd;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121zM208 180h-68l100 -100l100 100h-68v76h-64v-76z" />
+ <glyph glyph-name="ion-android-drafts" unicode="&#xf384;"
+d="M448 246v-203c0 -23 -20 -43 -43 -43h-362c-23 0 -43 20 -43 43v203c0 15 8 30 20 37l204 101l204 -101c13 -7 20 -22 20 -37zM224 144l171 112l-171 85l-171 -85z" />
+ <glyph glyph-name="ion-android-exit" unicode="&#xf385;" horiz-adv-x="384"
+d="M151 115l55 56h-206v42h207l-56 56l30 30l107 -107l-107 -107zM341 384c23 0 43 -20 43 -43v-298c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v85h43v-85h298v298h-298v-85h-43v85c0 23 20 43 43 43h298z" />
+ <glyph glyph-name="ion-android-expand" unicode="&#xf386;" horiz-adv-x="384"
+d="M333 51v77h51v-128h-128v51h77zM333 333h-77v51h128v-128h-51v77zM51 333v-77h-51v128h128v-51h-77zM51 51h77v-51h-128v128h51v-77z" />
+ <glyph glyph-name="ion-android-favorite-outline" unicode="&#xf387;" horiz-adv-x="416"
+d="M302 384c64 0 114 -50 114 -115c0 -80 -71 -144 -178 -242l-30 -27l-30 27c-107 98 -178 162 -178 242c0 65 50 115 114 115c36 0 71 -17 94 -44c23 27 58 44 94 44zM221 55c50 46 94 86 123 122c28 35 40 63 40 92c0 23 -9 44 -24 59s-35 24 -58 24
+c-26 0 -53 -13 -70 -33l-24 -29l-24 29c-17 20 -44 33 -70 33c-23 0 -43 -9 -58 -24s-24 -36 -24 -59c0 -29 12 -57 40 -92c29 -36 73 -76 123 -122l4 -4l9 -8l9 8z" />
+ <glyph glyph-name="ion-android-favorite" unicode="&#xf388;" horiz-adv-x="416"
+d="M208 0l-30 27c-107 98 -178 162 -178 242c0 65 50 115 114 115c36 0 71 -17 94 -44c23 27 58 44 94 44c64 0 114 -50 114 -115c0 -80 -71 -144 -178 -242z" />
+ <glyph glyph-name="ion-android-film" unicode="&#xf389;" horiz-adv-x="320"
+d="M280 384h40v-384h-40v43h-40v-43h-160v43h-40v-43h-40v384h40v-43h40v43h160v-43h40v43zM80 85v43h-40v-43h40zM80 171v42h-40v-42h40zM80 256v43h-40v-43h40zM280 85v43h-40v-43h40zM280 171v42h-40v-42h40zM280 256v43h-40v-43h40z" />
+ <glyph glyph-name="ion-android-folder-open" unicode="&#xf38a;"
+d="M405 304c23 0 43 -20 43 -43v-186c0 -23 -20 -43 -43 -43h-362c-23 0 -43 20 -43 43v234c0 23 20 43 43 43h138l43 -48h181zM416 75v186c0 6 -5 11 -11 11h-373v-197c0 -6 5 -11 11 -11h362c6 0 11 5 11 11z" />
+ <glyph glyph-name="ion-android-folder" unicode="&#xf2e0;"
+d="M181 352l43 -48h181c23 0 43 -20 43 -43v-186c0 -23 -20 -43 -43 -43h-362c-23 0 -43 20 -43 43v234c0 23 20 43 43 43h138z" />
+ <glyph glyph-name="ion-android-funnel" unicode="&#xf38b;"
+d="M176 48v48h96v-48h-96zM0 336h448v-48h-448v48zM80 167v50h288v-50h-288z" />
+ <glyph glyph-name="ion-android-globe" unicode="&#xf38c;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM186 15c6 15 21 29 8 39c-8 7 -16 14 -23 21c-2 2 -11 20 -9 23c5 9 6 14 8 24c3 12 -3 16 -13 22c-15 10 -29 23 -43 34c-7 5 -17 10 -20 19s-5 20 -10 28c-14 20 -12 34 -10 58
+c0 7 -1 16 -2 25c-28 -32 -42 -73 -42 -116c0 -48 18 -92 52 -126c29 -29 65 -46 104 -51zM334 66c23 23 39 51 47 82c-8 -1 -19 2 -19 2s-21 24 -23 45c-2 22 0 39 -3 57c-3 16 -20 31 -27 46c-7 14 -13 28 -20 42c2 -1 5 -2 7 -3c5 1 10 2 14 2c-23 16 -49 25 -76 29v-8
+l4 -9l-14 -13l-9 3l-10 10l-10 12l-14 5c-16 -2 -31 -7 -45 -13v-7c7 3 16 5 23 8c3 1 13 -7 16 -9c-4 -5 -21 -15 -22 -21c0 -2 7 -6 7 -10c0 -6 -1 -11 -1 -17c3 3 20 21 22 21c13 3 35 -19 37 -26s-22 -24 -33 -34c-8 -8 -25 -12 -20 -24c2 -4 10 -20 5 -24
+c-6 -5 -14 9 -17 12c-8 10 -26 7 -38 7c0 -17 -1 -31 15 -43c15 -11 30 -25 47 -33c13 -6 36 7 47 -1c16 -11 29 -21 47 -29c8 -3 33 -20 26 -31c-5 -8 -10 -15 -14 -23s-13 -20 -20 -25c-8 -6 -16 -17 -21 -29c35 7 66 23 92 49z" />
+ <glyph glyph-name="ion-android-hand" unicode="&#xf2e3;" horiz-adv-x="414"
+d="M401 174c15 -15 18 -36 3 -51c0 0 -96 -103 -126 -121v0c-28 -21 -65 -34 -100 -34c-55 0 -101 36 -117 85v0v1c0 1 -1 2 -1 3l-58 189c-5 15 2 32 17 37s30 -3 35 -18l34 -88c1 -4 2 -2 2 1l-22 161c-3 15 7 30 22 33s30 -8 33 -23l25 -138c0 -2 2 -2 2 0v177
+c0 15 13 28 28 28s28 -13 28 -28l8 -175c0 -5 3 -4 4 -1l23 135c2 15 16 27 31 25s27 -17 25 -32l-21 -172c-1 -12 -3 -30 2 -36c8 -9 20 -9 31 2l42 42c15 15 35 13 50 -2z" />
+ <glyph glyph-name="ion-android-hangout" unicode="&#xf38d;" horiz-adv-x="352"
+d="M176 400c97 0 176 -77 176 -172c0 -91 -76 -196 -176 -244v71c-97 0 -176 78 -176 173s79 172 176 172zM166 217v61h-62v-61h31l-21 -40h31zM248 217v61h-62v-61h31l-20 -40h31z" />
+ <glyph glyph-name="ion-android-happy" unicode="&#xf38e;" horiz-adv-x="416"
+d="M208 400c114 0 208 -94 208 -208s-93 -208 -208 -208s-208 94 -208 208s93 208 208 208zM208 26c92 0 166 74 166 166s-74 166 -166 166s-166 -74 -166 -166s74 -166 166 -166zM281 213c-18 0 -31 13 -31 31s13 31 31 31s31 -13 31 -31s-13 -31 -31 -31zM135 213
+c-18 0 -31 13 -31 31s13 31 31 31s31 -13 31 -31s-13 -31 -31 -31zM208 78c-49 0 -89 29 -106 72h212c-17 -43 -57 -72 -106 -72z" />
+ <glyph glyph-name="ion-android-home" unicode="&#xf38f;" horiz-adv-x="416"
+d="M160 0h-98v192h-62l208 192l208 -192h-62v-192h-98v128h-96v-128z" />
+ <glyph glyph-name="ion-android-image" unicode="&#xf2e4;" horiz-adv-x="384"
+d="M384 43c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h298c23 0 43 -20 43 -43v-298zM117 160l-74 -96h298l-96 128l-74 -96z" />
+ <glyph glyph-name="ion-android-laptop" unicode="&#xf390;" horiz-adv-x="512"
+d="M437 32h75c0 -23 -64 -32 -96 -32h-320c-32 0 -96 9 -96 32h75c-23 0 -43 20 -43 43v266c0 23 20 43 43 43h362c23 0 43 -20 43 -43v-266c0 -23 -20 -43 -43 -43zM75 341v-272h362v272h-362zM256 13c12 0 21 10 21 22s-9 21 -21 21s-21 -9 -21 -21s9 -22 21 -22z" />
+ <glyph glyph-name="ion-android-list" unicode="&#xf391;" horiz-adv-x="384"
+d="M344 384c22 0 40 -18 40 -40v-304c0 -22 -18 -40 -40 -40h-304c-22 0 -40 18 -40 40v304c0 22 18 40 40 40h304zM240 80v48h-160v-48h160zM304 168v48h-224v-48h224zM304 256v48h-224v-48h224z" />
+ <glyph glyph-name="ion-android-locate" unicode="&#xf2e9;"
+d="M224 272c44 0 80 -36 80 -80s-36 -80 -80 -80s-80 36 -80 80s36 80 80 80zM415 213h33v-42h-33c-10 -89 -81 -160 -170 -170v-33h-42v33c-89 10 -160 81 -170 170h-33v42h33c10 89 81 160 170 170v33h42v-33c89 -10 160 -81 170 -170zM224 43c82 0 149 67 149 149
+s-67 149 -149 149s-149 -67 -149 -149s67 -149 149 -149z" />
+ <glyph glyph-name="ion-android-lock" unicode="&#xf392;" horiz-adv-x="320"
+d="M280 262c22 0 40 -18 40 -40v-200c0 -22 -18 -40 -40 -40h-240c-22 0 -40 18 -40 40v200c0 22 18 40 40 40h20v40c0 55 45 100 100 100s100 -45 100 -100v-40h20zM160 80c22 0 40 18 40 40s-18 40 -40 40s-40 -18 -40 -40s18 -40 40 -40zM222 262v40c0 34 -28 62 -62 62
+s-62 -28 -62 -62v-40h124z" />
+ <glyph glyph-name="ion-android-mail" unicode="&#xf2eb;"
+d="M405 368c23 0 43 -20 43 -43v-266c0 -23 -20 -43 -43 -43h-362c-23 0 -43 20 -43 43v266c0 23 20 43 43 43h362zM400 277v43l-176 -117l-176 117v-43l176 -117z" />
+ <glyph glyph-name="ion-android-map" unicode="&#xf393;" horiz-adv-x="384"
+d="M373 384c6 0 11 -5 11 -11v-322c0 -5 -3 -9 -7 -10l-121 -41l-128 45s-105 -41 -108 -42s-7 -3 -9 -3c-6 0 -11 5 -11 11v322c0 5 3 9 7 10l121 41l128 -45s103 40 108 42s7 3 9 3zM256 43v254l-128 44v-254z" />
+ <glyph glyph-name="ion-android-menu" unicode="&#xf394;" horiz-adv-x="384"
+d="M0 64v43h384v-43h-384zM0 171v42h384v-42h-384zM0 320h384v-43h-384v43z" />
+ <glyph glyph-name="ion-android-microphone-off" unicode="&#xf395;" horiz-adv-x="408"
+d="M316 93l58 -58l-58 58l58 -58l34 -33l-24 -24l-95 95c-19 -11 -40 -20 -62 -23v-82h-46v82c-75 10 -137 76 -137 153h39c0 -68 58 -117 121 -117c20 0 40 5 57 14l-32 33c-8 -3 -16 -5 -25 -5c-38 0 -69 31 -69 69v29l-135 134l24 24l111 -110v0l140 -140l5 -5l9 -9z
+M273 197c0 -4 0 -8 -1 -12l-137 137v25c0 38 31 69 69 69s69 -31 69 -69v-150zM365 203c0 -31 -10 -60 -27 -84l-27 28c9 17 15 36 15 56h39zM408 2v0l-34 33z" />
+ <glyph glyph-name="ion-android-microphone" unicode="&#xf2ec;" horiz-adv-x="320"
+d="M160 128c-38 0 -69 31 -69 69v150c0 38 31 69 69 69s69 -31 69 -69v-150c0 -38 -31 -69 -69 -69zM281 203h39c0 -78 -62 -142 -137 -153v-82h-46v82c-75 10 -137 75 -137 153h39c0 -69 58 -116 121 -116s121 47 121 116z" />
+ <glyph glyph-name="ion-android-more-horizontal" unicode="&#xf396;" horiz-adv-x="320"
+d="M40 232c22 0 40 -18 40 -40s-18 -40 -40 -40s-40 18 -40 40s18 40 40 40zM280 232c22 0 40 -18 40 -40s-18 -40 -40 -40s-40 18 -40 40s18 40 40 40zM160 232c22 0 40 -18 40 -40s-18 -40 -40 -40s-40 18 -40 40s18 40 40 40z" />
+ <glyph glyph-name="ion-android-more-vertical" unicode="&#xf397;" horiz-adv-x="80"
+d="M80 312c0 -22 -18 -40 -40 -40s-40 18 -40 40s18 40 40 40s40 -18 40 -40zM80 72c0 -22 -18 -40 -40 -40s-40 18 -40 40s18 40 40 40s40 -18 40 -40zM80 192c0 -22 -18 -40 -40 -40s-40 18 -40 40s18 40 40 40s40 -18 40 -40z" />
+ <glyph glyph-name="ion-android-navigate" unicode="&#xf398;" horiz-adv-x="320"
+d="M160 384l160 -369l-15 -15l-145 64l-145 -64l-15 15z" />
+ <glyph glyph-name="ion-android-notifications-none" unicode="&#xf399;" horiz-adv-x="352"
+d="M177 328h-2c-6 0 -24 -5 -24 -5c-46 -10 -78 -53 -78 -100v-114v-13l-9 -10l-8 -8h240l-8 8l-9 10v13v114c0 47 -32 90 -78 100c0 0 -17 5 -24 5zM176 400v0c18 0 31 -13 31 -31v-15c59 -14 104 -68 104 -131v-114l41 -42v-21h-352v21l41 42v114c0 63 45 117 104 131v15
+c0 18 13 31 31 31zM217 26v0c0 -23 -18 -42 -41 -42s-41 19 -41 42h82z" />
+ <glyph glyph-name="ion-android-notifications-off" unicode="&#xf39a;" horiz-adv-x="364"
+d="M182 -16c-23 0 -41 19 -41 42h82c0 -23 -18 -42 -41 -42zM57 341l295 -295v0l12 -12l-24 -24l-36 36h-298v21l41 41v115c0 23 6 44 16 63l-63 64l24 24l33 -33v0zM317 223v-94l-208 207c13 8 27 15 42 18v15c0 18 13 31 31 31s31 -13 31 -31v-15c59 -14 104 -67 104 -131
+z" />
+ <glyph glyph-name="ion-android-notifications" unicode="&#xf39b;" horiz-adv-x="352"
+d="M176 -16c-23 0 -41 19 -41 42h82c0 -23 -18 -42 -41 -42zM311 109l41 -42v-21h-352v21l41 42v114c0 63 45 117 104 131v15c0 18 13 31 31 31s31 -13 31 -31v-15c59 -14 104 -68 104 -131v-114z" />
+ <glyph glyph-name="ion-android-open" unicode="&#xf39c;" horiz-adv-x="384"
+d="M341 43v133h43v-133c0 -23 -20 -43 -43 -43h-298c-23 0 -43 20 -43 43v298c0 23 20 43 43 43h133v-43h-133v-298h298zM224 384h160v-160h-43v87l-215 -215l-30 30l215 215h-87v43z" />
+ <glyph glyph-name="ion-android-options" unicode="&#xf39d;"
+d="M0 32v32h272v-32h-272zM368 32v32h80v-32h-80zM352 0c0 -18 -14 -32 -32 -32v0c-18 0 -32 14 -32 32v96c0 18 14 32 32 32v0c18 0 32 -14 32 -32v-96zM0 176v32h80v-32h-80zM176 176v32h272v-32h-272zM160 144c0 -18 -14 -32 -32 -32v0c-18 0 -32 14 -32 32v96
+c0 18 14 32 32 32v0c18 0 32 -14 32 -32v-96zM0 320v32h272v-32h-272zM368 320v32h80v-32h-80zM352 288c0 -18 -14 -32 -32 -32v0c-18 0 -32 14 -32 32v96c0 18 14 32 32 32v0c18 0 32 -14 32 -32v-96z" />
+ <glyph glyph-name="ion-android-people" unicode="&#xf39e;"
+d="M305 216c-34 0 -61 27 -61 60s27 60 61 60s62 -27 62 -60s-28 -60 -62 -60zM143 216c-34 0 -62 27 -62 60s28 60 62 60s61 -27 61 -60s-27 -60 -61 -60zM143 172c48 0 145 -23 145 -70v-54h-288v54c0 47 95 70 143 70zM305 161c48 0 143 -12 143 -59v-54h-128v54
+c0 30 -9 41 -32 58c7 1 11 1 17 1z" />
+ <glyph glyph-name="ion-android-person-add" unicode="&#xf39f;" horiz-adv-x="480"
+d="M288 192c-53 0 -96 43 -96 96s43 96 96 96s96 -43 96 -96s-43 -96 -96 -96zM288 144c64 0 192 -32 192 -96v-48h-384v48c0 64 128 96 192 96zM96 224h64v-32h-64v-64h-32v64h-64v32h64v64h32v-64z" />
+ <glyph glyph-name="ion-android-person" unicode="&#xf3a0;" horiz-adv-x="384"
+d="M192 192c-53 0 -96 43 -96 96s43 96 96 96s96 -43 96 -96s-43 -96 -96 -96zM192 144c64 0 192 -32 192 -96v-48h-384v48c0 64 128 96 192 96z" />
+ <glyph glyph-name="ion-android-phone-landscape" unicode="&#xf3a1;"
+d="M448 89c0 -23 -19 -41 -41 -41h-366c-22 0 -41 18 -41 41v206c0 23 19 41 41 41h366c22 0 41 -18 41 -41v-206zM80 84h288v216h-288v-216z" />
+ <glyph glyph-name="ion-android-phone-portrait" unicode="&#xf3a2;" horiz-adv-x="288"
+d="M247 416c23 0 41 -19 41 -41v-366c0 -22 -18 -41 -41 -41h-206c-23 0 -41 19 -41 41v366c0 22 18 41 41 41h206zM252 48v288h-216v-288h216z" />
+ <glyph glyph-name="ion-android-pin" unicode="&#xf3a3;" horiz-adv-x="320"
+d="M160 416c88 0 160 -71 160 -157c0 -118 -160 -291 -160 -291s-160 173 -160 291c0 86 72 157 160 157zM160 203c32 0 57 25 57 56s-25 56 -57 56s-57 -25 -57 -56s25 -56 57 -56z" />
+ <glyph glyph-name="ion-android-plane" unicode="&#xf3a4;" horiz-adv-x="384"
+d="M384 112l-160 48v-114l48 -31v-31l-80 16l-80 -16v31l48 31v114l-160 -48v40l160 104v113c0 18 15 31 32 31s32 -13 32 -31v-113l160 -104v-40z" />
+ <glyph glyph-name="ion-android-playstore" unicode="&#xf2f0;" horiz-adv-x="416"
+d="M416 296c-19 -214 -13 -312 -13 -312h-390s6 96 -13 312h104c0 57 47 104 104 104s104 -47 104 -104h104zM208 374c-43 0 -78 -35 -78 -78h156c0 43 -35 78 -78 78zM156 50l143 85l-143 84v-169z" />
+ <glyph glyph-name="ion-android-print" unicode="&#xf3a5;" horiz-adv-x="416"
+d="M352 288c35 0 64 -29 64 -64v-139h-80v-85h-256v85h-80v139c0 35 29 64 64 64h288zM304 32v128h-192v-128h192zM336 384v0v-80h-256v80h256z" />
+ <glyph glyph-name="ion-android-radio-button-off" unicode="&#xf3a6;" horiz-adv-x="416"
+d="M208 400c114 0 208 -94 208 -208s-94 -208 -208 -208s-208 94 -208 208s94 208 208 208zM208 26c92 0 166 74 166 166s-74 166 -166 166s-166 -74 -166 -166s74 -166 166 -166z" />
+ <glyph glyph-name="ion-android-radio-button-on" unicode="&#xf3a7;" horiz-adv-x="416"
+d="M208 296c57 0 104 -47 104 -104s-47 -104 -104 -104s-104 47 -104 104s47 104 104 104zM208 400c114 0 208 -94 208 -208s-94 -208 -208 -208s-208 94 -208 208s94 208 208 208zM208 26c92 0 166 74 166 166s-74 166 -166 166s-166 -74 -166 -166s74 -166 166 -166z" />
+ <glyph glyph-name="ion-android-refresh" unicode="&#xf3a8;" horiz-adv-x="352"
+d="M176 60c56 0 104 34 123 84h46c-21 -74 -88 -128 -169 -128c-98 0 -176 79 -176 176s79 176 176 176c48 0 92 -20 124 -52l52 52v-154h-154l70 70c-23 24 -56 40 -92 40c-73 0 -132 -59 -132 -132s59 -132 132 -132z" />
+ <glyph glyph-name="ion-android-remove-circle" unicode="&#xf3a9;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM315 171v42h-214v-42h214z" />
+ <glyph glyph-name="ion-android-remove" unicode="&#xf2f4;" horiz-adv-x="320"
+d="M0 171v42h320v-42h-320z" />
+ <glyph glyph-name="ion-android-restaurant" unicode="&#xf3aa;" horiz-adv-x="415"
+d="M116 168l-91 89c-34 33 -34 86 0 119l153 -148zM264 206l-33 -31l150 -145l-30 -30l-150 146l-150 -146l-30 30s163 159 211 207c-15 32 -4 77 31 111c41 40 101 49 132 17c33 -31 24 -89 -17 -129c-34 -34 -80 -45 -114 -30z" />
+ <glyph glyph-name="ion-android-sad" unicode="&#xf3ab;" horiz-adv-x="416"
+d="M208 160c45 0 83 -26 102 -64h-204c19 38 57 64 102 64zM208 400c114 0 208 -94 208 -208s-93 -208 -208 -208s-208 94 -208 208s93 208 208 208zM208 26c92 0 166 74 166 166s-74 166 -166 166s-166 -74 -166 -166s74 -166 166 -166zM281 213c-18 0 -31 13 -31 31
+s13 31 31 31s31 -13 31 -31s-13 -31 -31 -31zM135 213c-18 0 -31 13 -31 31s13 31 31 31s31 -13 31 -31s-13 -31 -31 -31z" />
+ <glyph glyph-name="ion-android-search" unicode="&#xf2f5;" horiz-adv-x="384"
+d="M274 143l110 -110l-33 -33l-109 110v17l-7 6c-25 -21 -58 -34 -93 -34c-79 0 -142 63 -142 142s63 143 141 143c79 0 142 -64 142 -143c0 -36 -13 -68 -34 -93l7 -5h18zM142 143c55 0 99 43 99 98s-44 99 -99 99s-98 -44 -98 -99s43 -98 98 -98z" />
+ <glyph glyph-name="ion-android-send" unicode="&#xf2f6;" horiz-adv-x="416"
+d="M0 0v149l298 43l-298 43v149l416 -192z" />
+ <glyph glyph-name="ion-android-settings" unicode="&#xf2f7;" horiz-adv-x="416"
+d="M366 171l47 -34c3 -3 4 -10 2 -14l-43 -71c-2 -4 -7 -7 -12 -5l-54 21c-12 -8 -23 -16 -36 -21l-8 -55c-1 -4 -6 -8 -11 -8h-85c-5 0 -10 3 -11 8l-8 55c-13 5 -25 13 -36 21l-54 -21c-4 -2 -10 1 -12 5l-43 71c-3 5 -2 11 2 14l45 34c0 7 -1 14 -1 21s1 14 1 21l-46 34
+c-3 3 -4 10 -2 14l43 71c2 4 7 7 12 5l54 -21c12 8 23 16 36 21l8 55c1 4 6 8 11 8h85c5 0 10 -4 11 -8l7 -55c13 -5 25 -13 36 -21l53 21c4 2 11 -1 13 -5l43 -71c3 -5 2 -11 -2 -14l-45 -34c0 -7 1 -14 1 -21s0 -15 -1 -21zM207 119c41 0 75 32 75 73s-34 73 -75 73
+s-74 -32 -74 -73s33 -73 74 -73z" />
+ <glyph glyph-name="ion-android-share-alt" unicode="&#xf3ac;" horiz-adv-x="384"
+d="M320 104c34 0 62 -28 62 -62s-28 -62 -62 -62s-62 28 -62 62c0 5 1 10 2 14l-152 88c-12 -11 -27 -17 -44 -17c-35 0 -64 29 -64 64s28 64 63 64c17 0 32 -6 44 -17l151 87c-1 5 -2 10 -2 15c0 35 29 64 64 64s64 -29 64 -64s-29 -64 -64 -64c-17 0 -32 6 -44 17
+l-151 -87c1 -5 2 -10 2 -15s-1 -10 -2 -15l153 -88c11 11 26 16 42 16z" />
+ <glyph glyph-name="ion-android-share" unicode="&#xf2f8;" horiz-adv-x="384"
+d="M384 200l-160 -147v88c-107 0 -171 -34 -224 -109c21 107 75 214 224 235v85z" />
+ <glyph glyph-name="ion-android-star-half" unicode="&#xf3ad;" horiz-adv-x="404"
+d="M404 238l-110 -96l33 -142l-125 75l-125 -75l33 142l-110 96l145 12l57 134l57 -134zM219 103l60 -36l-16 68l-5 19l15 12l53 46l-70 6l-19 2l-8 18l-27 64v-189z" />
+ <glyph glyph-name="ion-android-star-outline" unicode="&#xf3ae;" horiz-adv-x="404"
+d="M404 238l-110 -96l33 -142l-125 75l-125 -75l33 142l-110 96l145 12l57 134l57 -134zM219 103l60 -36l-16 68l-5 19l15 12l53 46l-70 6l-19 2l-8 18l-27 64l-27 -64l-8 -18l-19 -2l-70 -6l53 -46l15 -12l-5 -19l-16 -68l60 36l17 10z" />
+ <glyph glyph-name="ion-android-star" unicode="&#xf2fc;" horiz-adv-x="404"
+d="M202 75l-125 -75l33 142l-110 96l145 12l57 134l57 -134l145 -12l-110 -96l33 -142z" />
+ <glyph glyph-name="ion-android-stopwatch" unicode="&#xf2fd;" horiz-adv-x="384"
+d="M168 141v131h48v-131h-48zM344 278c25 -33 40 -74 40 -118c0 -106 -86 -192 -192 -192s-192 86 -192 192s86 192 192 192c44 0 85 -15 118 -40l31 30l33 -33zM298 54c28 28 44 66 44 106s-16 78 -44 106s-66 44 -106 44s-78 -16 -106 -44s-44 -66 -44 -106
+s16 -78 44 -106s66 -44 106 -44s78 16 106 44zM128 368v48h128v-48h-128z" />
+ <glyph glyph-name="ion-android-subway" unicode="&#xf3af;" horiz-adv-x="352"
+d="M176 400c94 0 176 -10 176 -85v-214c0 -42 -33 -74 -75 -74l27 -27v-16h-256v16l27 27c-42 0 -75 32 -75 74v214c0 75 82 85 176 85zM80 64c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM160 208v96h-112v-96h112zM272 64c18 0 32 14 32 32
+s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM304 208v96h-112v-96h112z" />
+ <glyph glyph-name="ion-android-sunny" unicode="&#xf3b0;"
+d="M224 288c-25 0 -50 -10 -68 -28s-28 -43 -28 -68s10 -50 28 -68s43 -28 68 -28s50 10 68 28s28 43 28 68s-10 50 -28 68s-43 28 -68 28zM245 416v0v-64h-42v64h42zM374 372v0l30 -30l-38 -38l-30 30zM74 372v0l38 -38l-30 -30l-38 38zM224 320v0c70 0 128 -58 128 -128
+s-58 -128 -128 -128s-128 58 -128 128s58 128 128 128zM448 213v0v-42h-64v42h64zM64 213v0v-42h-64v42h64zM366 80v0l38 -38l-30 -30l-38 38zM82 80v0l30 -30l-38 -38l-30 30zM245 32v0v-64h-42v64h42z" />
+ <glyph glyph-name="ion-android-sync" unicode="&#xf3b1;" horiz-adv-x="320"
+d="M160 355c88 0 160 -73 160 -163c0 -32 -9 -62 -25 -87l-29 30c9 17 14 37 14 57c0 67 -54 122 -120 122v-61l-80 82l80 81v-61zM160 70v61l80 -82l-80 -81v61c-88 0 -160 73 -160 163c0 32 9 63 25 87l29 -30c-9 -17 -14 -37 -14 -57c0 -67 54 -122 120 -122z" />
+ <glyph glyph-name="ion-android-textsms" unicode="&#xf3b2;" horiz-adv-x="384"
+d="M344 384c22 0 40 -18 40 -40v-240c0 -22 -18 -40 -40 -40h-280l-64 -64v344c0 22 10 40 32 40h312zM134 206v40h-38v-40h38zM211 206v40h-38v-40h38zM288 206v40h-38v-40h38z" />
+ <glyph glyph-name="ion-android-time" unicode="&#xf3b3;" horiz-adv-x="426"
+d="M213 405c117 0 213 -96 213 -213s-95 -213 -213 -213s-213 96 -213 213s95 213 213 213zM213 22c94 0 170 76 170 170s-76 170 -170 170s-170 -76 -170 -170s76 -170 170 -170zM224 298v-111l96 -57l-16 -26l-112 67v127h32z" />
+ <glyph glyph-name="ion-android-train" unicode="&#xf3b4;" horiz-adv-x="352"
+d="M0 101v214c0 75 82 85 176 85s176 -10 176 -85v-214c0 -42 -33 -74 -75 -74l27 -27v-16h-256v16l27 27c-42 0 -75 32 -75 74zM176 72c22 0 40 18 40 40s-18 40 -40 40s-40 -18 -40 -40s18 -40 40 -40zM304 224v96h-256v-96h256z" />
+ <glyph glyph-name="ion-android-unlock" unicode="&#xf3b5;" horiz-adv-x="320"
+d="M280 262c22 0 40 -18 40 -40v-200c0 -22 -18 -40 -40 -40h-240c-22 0 -40 18 -40 40v200c0 22 18 40 40 40h182v40v0c0 34 -28 62 -62 62s-62 -28 -62 -62h-38c0 55 45 100 100 100s100 -45 100 -100v-40h20zM160 80c22 0 40 18 40 40s-18 40 -40 40s-40 -18 -40 -40
+s18 -40 40 -40z" />
+ <glyph glyph-name="ion-android-upload" unicode="&#xf3b6;" horiz-adv-x="480"
+d="M387 231c52 -3 93 -46 93 -99c0 -55 -45 -100 -100 -100h-260c-66 0 -120 54 -120 120c0 62 47 113 107 119c25 48 75 81 133 81c73 0 133 -52 147 -121zM272 172h68l-100 100l-100 -100h68v-76h64v76z" />
+ <glyph glyph-name="ion-android-volume-down" unicode="&#xf3b7;" horiz-adv-x="288"
+d="M0 256h85l107 112v-352l-107 112h-85v128zM288 192c0 -38 -21 -73 -53 -88v177c32 -16 53 -51 53 -89z" />
+ <glyph glyph-name="ion-android-volume-mute" unicode="&#xf3b8;" horiz-adv-x="192"
+d="M0 256h85l107 112v-352l-107 112h-85v128z" />
+ <glyph glyph-name="ion-android-volume-off" unicode="&#xf3b9;" horiz-adv-x="384"
+d="M342 192c0 69 -45 128 -107 147v45c85 -20 149 -99 149 -192c0 -35 -8 -68 -24 -96l-32 32c9 19 14 41 14 64zM192 368v-104l-51 51zM357 51v0l24 -24l-24 -24l-40 40c-23 -21 -51 -36 -82 -43v45c19 6 37 15 52 28l-95 95v-152l-107 112h-85v128h85l9 10l-91 91l24 24z
+M288 192c0 -7 0 -15 -2 -22l-51 51v60c32 -16 53 -51 53 -89z" />
+ <glyph glyph-name="ion-android-volume-up" unicode="&#xf3ba;" horiz-adv-x="384"
+d="M0 256h85l107 112v-352l-107 112h-85v128zM288 192c0 -38 -21 -73 -53 -88v177c32 -16 53 -51 53 -89zM235 384c85 -20 149 -99 149 -192s-64 -172 -149 -192v45c62 19 106 78 106 147s-44 128 -106 147v45z" />
+ <glyph glyph-name="ion-android-walk" unicode="&#xf3bb;" horiz-adv-x="272"
+d="M168 336c-22 0 -40 18 -40 40s18 40 40 40s40 -18 40 -40s-18 -40 -40 -40zM168 216l-20 38l-20 -62l57 -96v-128h-38v96l-50 68l-57 -164h-40l81 320l-41 -16v-80h-40v112l111 38c4 1 10 1 13 1c13 0 23 -6 31 -18l45 -69h72v-40h-104z" />
+ <glyph glyph-name="ion-android-warning" unicode="&#xf3bc;"
+d="M0 -16l224 416l224 -416h-448zM248 48v48h-48v-48h48zM248 128v96h-48v-96h48z" />
+ <glyph glyph-name="ion-android-watch" unicode="&#xf3bd;" horiz-adv-x="320"
+d="M320 192c0 -51 -24 -96 -61 -125l-19 -115h-160l-19 115c-37 29 -61 74 -61 125s24 96 61 125l19 115h160l19 -115c37 -29 61 -74 61 -125zM40 192c0 -66 54 -120 120 -120s120 54 120 120s-54 120 -120 120s-120 -54 -120 -120z" />
+ <glyph glyph-name="ion-android-wifi" unicode="&#xf305;" horiz-adv-x="416"
+d="M208 219c23 0 42 -18 42 -41s-19 -41 -42 -41s-42 18 -42 41s19 41 42 41zM333 178c0 -45 -26 -85 -63 -107l-20 36c25 14 41 40 41 71c0 45 -37 82 -83 82s-83 -37 -83 -82c0 -31 16 -57 41 -71l-20 -36c-37 22 -63 62 -63 107c0 68 56 124 125 124s125 -56 125 -124z
+M208 384c114 0 208 -93 208 -206c0 -76 -42 -142 -104 -178l-21 36c50 28 83 81 83 142c0 91 -74 165 -166 165s-166 -74 -166 -165c0 -61 33 -113 83 -142l-21 -36c-62 36 -104 102 -104 178c0 113 94 206 208 206z" />
+ <glyph glyph-name="ion-aperture" unicode="&#xf313;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56s100 20 136 56zM168 342l56 -86h-147
+c17 40 50 71 91 86zM381 160h-102l72 129c21 -27 33 -60 33 -97c0 -11 -1 -22 -3 -32zM328 314l-49 -90l-78 126c8 1 15 2 23 2c40 0 76 -14 104 -38zM67 224h102l-72 -129c-21 27 -33 60 -33 97c0 11 1 22 3 32zM280 42l-56 86h147c-17 -40 -50 -71 -91 -86zM120 70l49 90
+l78 -126c-8 -1 -15 -2 -23 -2c-40 0 -76 14 -104 38z" />
+ <glyph glyph-name="ion-archive" unicode="&#xf102;"
+d="M224 140l-128 116h80v96h96v-96h80zM433 151c11 -6 17 -19 15 -32l-9 -67c-2 -13 -9 -20 -28 -20h-374c-18 0 -26 7 -28 20l-9 67c-2 13 3 26 14 32l72 55h42l-62 -62h50c2 0 5 -1 6 -3l18 -45h168l18 45c1 2 3 3 5 3h51l-62 62h42z" />
+ <glyph glyph-name="ion-arrow-down-a" unicode="&#xf103;" horiz-adv-x="384"
+d="M192 -0l-192 192h112v192h160v-192h112z" />
+ <glyph glyph-name="ion-arrow-down-b" unicode="&#xf104;" horiz-adv-x="320"
+d="M3 263c-2 2 -3 6 -3 9c0 9 8 16 17 16v0h286v0c9 0 17 -7 17 -16c0 -3 -1 -6 -3 -8l-2 -3l-136 -156c-5 -5 -11 -9 -19 -9s-14 4 -19 9l-136 156z" />
+ <glyph glyph-name="ion-arrow-down-c" unicode="&#xf105;" horiz-adv-x="274"
+d="M265 125l-105 -100c-6 -6 -14 -9 -23 -9s-16 3 -22 9l-106 100c-12 12 -12 31 0 43s34 12 46 0l50 -48v217c0 17 14 31 32 31s32 -14 32 -31v-217l50 48c12 12 34 12 46 0s12 -31 0 -43z" />
+ <glyph glyph-name="ion-arrow-expand" unicode="&#xf25e;" horiz-adv-x="320"
+d="M178 238l64 64l-50 50h128v-128l-50 50l-64 -64zM178 146l28 28l64 -64l50 50v-128h-128l50 50zM142 146l-64 -64l50 -50h-128v128l50 -50l64 64zM142 238l-28 -28l-64 64l-50 -50v128h128l-50 -50z" />
+ <glyph glyph-name="ion-arrow-graph-down-left" unicode="&#xf25f;"
+d="M0 64v160l61 -61l131 141l107 -112l149 128l-149 -203l-107 107l-94 -98l62 -62h-160z" />
+ <glyph glyph-name="ion-arrow-graph-down-right" unicode="&#xf260;"
+d="M288 64l62 62l-94 98l-107 -107l-149 203l149 -128l107 112l131 -141l61 61v-160h-160z" />
+ <glyph glyph-name="ion-arrow-graph-up-left" unicode="&#xf261;"
+d="M160 320l-62 -62l94 -98l107 107l149 -203l-149 128l-107 -112l-131 141l-61 -61v160h160z" />
+ <glyph glyph-name="ion-arrow-graph-up-right" unicode="&#xf262;"
+d="M288 320h160v-160l-61 61l-131 -141l-107 112l-149 -128l149 203l107 -107l94 98z" />
+ <glyph glyph-name="ion-arrow-left-a" unicode="&#xf106;" horiz-adv-x="384"
+d="M0 192l192 192v-112h192v-160h-192v-112z" />
+ <glyph glyph-name="ion-arrow-left-b" unicode="&#xf107;" horiz-adv-x="192"
+d="M167 349c2 2 6 3 9 3c9 0 16 -8 16 -17v0v-286v0c0 -9 -7 -17 -16 -17c-3 0 -7 1 -9 3l-2 2l-156 136c-5 5 -9 11 -9 19s4 14 9 19l156 136z" />
+ <glyph glyph-name="ion-arrow-left-c" unicode="&#xf108;" horiz-adv-x="352"
+d="M109 320c12 12 32 12 44 0s12 -34 0 -46l-49 -50h217c17 0 31 -14 31 -32s-14 -32 -31 -32h-217l48 -50c12 -12 12 -34 0 -46s-31 -12 -43 0l-100 106c-6 6 -9 13 -9 22s3 17 9 23z" />
+ <glyph glyph-name="ion-arrow-move" unicode="&#xf263;"
+d="M448 192l-96 -96v76h-109l1 -108h76l-96 -96l-96 96h76v108h-108v-76l-96 96l96 96v-76h108v108h-76l96 96l96 -96h-76v-108h108v76z" />
+ <glyph glyph-name="ion-arrow-resize" unicode="&#xf264;" horiz-adv-x="320"
+d="M192 352h128v-128l-50 50l-9 -9l-183 -183l50 -50h-128v128l50 -50l128 128v0l64 64z" />
+ <glyph glyph-name="ion-arrow-return-left" unicode="&#xf265;" horiz-adv-x="384"
+d="M128 352v-64h248c4 0 8 -4 8 -8v-240c0 -4 -4 -8 -8 -8h-304c-4 0 -8 4 -8 8v48c0 4 4 8 8 8h248v128h-192v-64l-128 96z" />
+ <glyph glyph-name="ion-arrow-return-right" unicode="&#xf266;" horiz-adv-x="384"
+d="M384 256l-128 -96v64h-192v-128h248c4 0 8 -4 8 -8v-48c0 -4 -4 -8 -8 -8h-304c-4 0 -8 4 -8 8v240c0 4 4 8 8 8h248v64z" />
+ <glyph glyph-name="ion-arrow-right-a" unicode="&#xf109;" horiz-adv-x="384"
+d="M384 192l-192 -192v112h-192v160h192v112z" />
+ <glyph glyph-name="ion-arrow-right-b" unicode="&#xf10a;" horiz-adv-x="192"
+d="M25 35c-2 -2 -6 -3 -9 -3c-9 0 -16 8 -16 17v0v286v0c0 9 7 17 16 17c3 0 6 -1 8 -3l3 -2l156 -136c5 -5 9 -11 9 -19s-4 -14 -9 -19l-156 -136z" />
+ <glyph glyph-name="ion-arrow-right-c" unicode="&#xf10b;" horiz-adv-x="352"
+d="M243 320l100 -105c6 -6 9 -14 9 -23s-3 -16 -9 -22l-100 -106c-12 -12 -31 -12 -43 0s-12 34 0 46l48 50h-217c-17 0 -31 14 -31 32s14 32 31 32h217l-49 50c-12 12 -12 34 0 46s32 12 44 0z" />
+ <glyph glyph-name="ion-arrow-shrink" unicode="&#xf267;" horiz-adv-x="384"
+d="M384 356l-82 -82l50 -50h-128v128l50 -50l82 82zM384 28l-28 -28l-82 82l-50 -50v128h128l-50 -50zM0 28l82 82l-50 50h128v-128l-50 50l-82 -82zM0 356l28 28l82 -82l50 50v-128h-128l50 50z" />
+ <glyph glyph-name="ion-arrow-swap" unicode="&#xf268;" horiz-adv-x="384"
+d="M0 120c0 4 4 8 8 8h248v64l128 -96l-128 -96v64h-248c-4 0 -8 4 -8 8v48zM384 264c0 -4 -4 -8 -8 -8h-248v-64l-128 96l128 96v-64h248c4 0 8 -4 8 -8v-48z" />
+ <glyph glyph-name="ion-arrow-up-a" unicode="&#xf10c;" horiz-adv-x="384"
+d="M192 384l192 -192h-112v-192h-160v192h-112z" />
+ <glyph glyph-name="ion-arrow-up-b" unicode="&#xf10d;" horiz-adv-x="320"
+d="M317 121c2 -2 3 -6 3 -9c0 -9 -8 -16 -17 -16v0h-286v0c-9 0 -17 7 -17 16c0 3 1 6 3 8l2 3l136 156c5 5 11 9 19 9s14 -4 19 -9l136 -156z" />
+ <glyph glyph-name="ion-arrow-up-c" unicode="&#xf10e;" horiz-adv-x="274"
+d="M9 259l105 100c6 6 14 9 23 9s16 -3 22 -9l106 -100c12 -12 12 -31 0 -43s-34 -12 -46 0l-50 48v-217c0 -17 -14 -31 -32 -31s-32 14 -32 31v217l-50 -49c-12 -12 -34 -12 -46 0s-12 32 0 44z" />
+ <glyph glyph-name="ion-asterisk" unicode="&#xf314;"
+d="M448 224v-64l-186 10l104 -170l-56 -32l-86 176l-86 -176l-56 32l104 170l-186 -10v64l187 -7l-109 167l60 32l86 -176l86 176l60 -32l-109 -167z" />
+ <glyph glyph-name="ion-at" unicode="&#xf10f;"
+d="M422 41c-24 -25 -52 -43 -85 -55s-69 -18 -105 -18c-35 0 -66 6 -95 17s-53 26 -73 46s-36 43 -47 71s-17 58 -17 90s6 62 18 89s29 51 50 71s46 35 74 47c28 11 58 17 90 17c28 0 55 -4 81 -12s49 -20 69 -36s36 -36 48 -60s18 -53 18 -85c0 -24 -3 -46 -10 -64
+s-16 -34 -27 -46s-24 -22 -38 -28s-29 -10 -45 -10s-29 4 -39 12s-15 17 -15 29h-3c-6 -10 -15 -19 -28 -28s-28 -13 -46 -13c-28 0 -49 9 -64 27s-23 42 -23 71c0 17 3 34 9 50s14 31 24 44s23 23 38 31s31 12 49 12c15 0 27 -4 38 -10c10 -6 18 -15 21 -24h1l5 24h54
+l-24 -113c-1 -6 -2 -12 -3 -19s-2 -13 -2 -19c0 -7 1 -13 4 -18s7 -7 15 -7c16 0 29 9 39 26s16 40 16 68c0 24 -4 45 -12 64s-20 34 -34 47s-32 23 -52 29s-41 9 -65 9c-26 0 -49 -4 -70 -13s-39 -22 -54 -38s-27 -34 -35 -56c-8 -21 -13 -44 -13 -69c0 -26 4 -51 13 -72
+s21 -39 37 -54s35 -27 57 -35s46 -12 72 -12c33 0 61 6 85 16s45 25 65 43zM231 260c-10 0 -18 -2 -25 -8s-14 -13 -19 -22s-8 -18 -11 -28s-4 -20 -4 -30c0 -5 0 -10 1 -16c1 -5 3 -10 6 -15s7 -8 12 -11s11 -5 19 -5c11 0 20 3 28 8s14 13 19 21s9 16 11 26s3 19 3 27
+c0 6 0 13 -1 19s-4 12 -7 17s-7 9 -12 12s-12 5 -20 5z" />
+ <glyph glyph-name="ion-backspace-outline" unicode="&#xf3be;" horiz-adv-x="512"
+d="M413 116c2 -2 3 -4 3 -6s-1 -4 -3 -6l-21 -22c-2 -2 -4 -2 -6 -2s-4 0 -6 2l-76 77l-76 -77c-2 -2 -4 -2 -6 -2s-4 0 -6 2l-21 22c-2 2 -3 4 -3 6s1 4 3 6l76 76l-77 76c-3 3 -3 9 0 12l22 22c2 2 4 2 6 2s4 0 6 -2l76 -76l76 76c2 2 4 2 6 2s4 0 6 -2l22 -22
+c3 -3 3 -9 0 -12l-77 -76zM499 354c9 -9 13 -20 13 -33v-256c0 -27 -20 -49 -46 -49h-298c-13 0 -24 3 -34 9c-9 5 -16 11 -23 20v0l-1 1l-110 146l110 148c14 19 34 28 58 28h298c13 0 24 -5 33 -14zM480 65v256c0 9 -5 15 -14 15h-298c-11 0 -22 -3 -32 -16l-96 -128
+l96 -128c8 -10 17 -16 32 -16h298c9 0 14 8 14 17z" />
+ <glyph glyph-name="ion-backspace" unicode="&#xf3bf;" horiz-adv-x="512"
+d="M499 354c9 -9 13 -20 13 -33v-256c0 -27 -20 -49 -46 -49h-298c-13 0 -24 3 -34 9c-9 5 -16 11 -23 20v0l-1 1l-110 146l110 148c14 19 34 28 58 28h298c13 0 24 -5 33 -14zM413 116l-76 76l77 76c3 3 3 9 0 12l-22 22c-2 2 -4 2 -6 2s-4 0 -6 -2l-76 -76l-76 76
+c-2 2 -4 2 -6 2s-4 0 -6 -2l-22 -22c-3 -3 -3 -9 0 -12l77 -76l-76 -76c-2 -2 -3 -4 -3 -6s1 -4 3 -6l21 -22c2 -2 4 -2 6 -2s4 0 6 2l76 77l76 -77c2 -2 4 -2 6 -2s4 0 6 2l21 22c2 2 3 4 3 6s-1 4 -3 6z" />
+ <glyph glyph-name="ion-bag" unicode="&#xf110;"
+d="M416 288l32 -320h-448l32 320h64v4c0 68 56 124 124 124h8c68 0 124 -56 124 -124v-4h64zM128 292v-4h192v4c0 51 -41 92 -92 92v0h-8c-51 0 -92 -41 -92 -92zM36 0h376l-25 256h-35v-36c10 -6 16 -16 16 -28c0 -18 -14 -32 -32 -32s-32 14 -32 32c0 12 6 22 16 28v36
+h-192v-36c10 -6 16 -16 16 -28c0 -18 -14 -32 -32 -32s-32 14 -32 32c0 12 6 22 16 28v36h-35z" />
+ <glyph glyph-name="ion-battery-charging" unicode="&#xf111;"
+d="M10 64c-6 0 -10 4 -10 10v236c0 6 4 10 10 10h381c6 0 10 -4 10 -10v-54h37c6 0 10 -4 10 -10v-108c0 -6 -4 -10 -10 -10h-37v-54c0 -6 -4 -10 -10 -10h-381zM225 288l-100 -111h61l-27 -81l100 111h-61z" />
+ <glyph glyph-name="ion-battery-empty" unicode="&#xf112;"
+d="M438 256c6 0 10 -4 10 -10v-108c0 -6 -4 -10 -10 -10h-37v-54c0 -6 -4 -10 -10 -10h-381c-6 0 -10 4 -10 10v236c0 6 4 10 10 10h381c6 0 10 -4 10 -10v-54h37zM416 160v64h-15h-32v32v32h-337v-192h337v32v32h32h15z" />
+ <glyph glyph-name="ion-battery-full" unicode="&#xf113;"
+d="M438 256c6 0 10 -4 10 -10v-108c0 -6 -4 -10 -10 -10h-37v-54c0 -6 -4 -10 -10 -10h-381c-6 0 -10 4 -10 10v236c0 6 4 10 10 10h381c6 0 10 -4 10 -10v-54h37z" />
+ <glyph glyph-name="ion-battery-half" unicode="&#xf114;"
+d="M438 256c6 0 10 -4 10 -10v-108c0 -6 -4 -10 -10 -10h-37v-54c0 -6 -4 -10 -10 -10h-381c-6 0 -10 4 -10 10v236c0 6 4 10 10 10h381c6 0 10 -4 10 -10v-54h37zM416 160v64h-15h-32v32v32h-81l32 -192h49v32v32h32h15z" />
+ <glyph glyph-name="ion-battery-low" unicode="&#xf115;"
+d="M10 64c-6 0 -10 4 -10 10v236c0 6 4 10 10 10h381c6 0 10 -4 10 -10v-54h37c6 0 10 -4 10 -10v-108c0 -6 -4 -10 -10 -10h-37v-54c0 -6 -4 -10 -10 -10h-381zM369 288h-209l32 -192h177v32v32h32h15v64h-15h-32v32v32z" />
+ <glyph glyph-name="ion-beaker" unicode="&#xf269;" horiz-adv-x="384"
+d="M80 256h240v-224c0 -9 -7 -16 -16 -16h-208c-9 0 -16 7 -16 16v224zM296 104v48c0 4 -4 8 -8 8s-8 -4 -8 -8v-48c0 -4 4 -8 8 -8s8 4 8 8zM288 176c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM381 416c3 0 3 -2 3 -3s-2 -3 -3 -5s-13 -20 -13 -40v-336
+c0 -35 -29 -64 -64 -64h-208c-35 0 -64 29 -64 64v307c0 32 -2 33 -32 37c0 12 11 40 65 40h316zM336 368c0 5 0 16 1 16h-273c-1 0 -3 0 -4 -1c5 -7 4 -32 4 -44v-307c0 -18 14 -32 32 -32h210c17 0 30 14 30 32v336z" />
+ <glyph glyph-name="ion-beer" unicode="&#xf26a;"
+d="M384 288c35 0 64 -29 64 -64v-96c0 -35 -29 -64 -64 -64h-32v-80c0 -9 -7 -16 -16 -16h-256c-9 0 -16 7 -16 16v223c-26 0 -48 22 -48 48v54v1c-10 11 -16 26 -16 42c0 35 29 64 64 64c18 0 34 -8 46 -20c10 12 26 20 43 20c14 0 27 -6 37 -14c12 9 26 14 42 14
+c17 0 34 -6 46 -16c11 10 26 16 42 16c35 0 64 -29 64 -64c0 -24 -18 -44 -32 -48v-16h32zM296 144c4 0 8 3 8 8v0v48c0 4 -4 8 -8 8s-8 -4 -8 -8v-48c0 -3 2 -6 4 -7c1 -1 2 -1 4 -1zM303 220c1 2 1 4 1 6s-1 4 -3 5s-4 1 -6 1s-4 -2 -5 -4s-2 -4 -2 -6s2 -4 4 -5
+s4 -1 6 -1s4 2 5 4zM320 288v32h-20c-3 -8 -7 -16 -13 -23c-13 -16 -33 -25 -55 -25c-26 0 -48 13 -61 33c-6 -2 -12 -3 -18 -3c-12 0 -23 4 -32 10c-2 1 -3 3 -5 4c-1 -2 -2 -3 -3 -5c-5 -6 -11 -10 -17 -14v-32v-9h80c0 4 4 8 8 8s8 -4 8 -8h128v32zM351 343c1 3 1 6 1 9
+c0 18 -14 32 -32 32c-9 0 -17 -4 -23 -10c-2 -2 -6 -5 -16 -6h-8c-6 1 -12 3 -14 5c-7 7 -16 11 -27 11c-9 0 -18 -4 -25 -9l-7 -7c0 -1 0 -1 -1 -2c-3 -3 -7 -5 -11 -5c-5 0 -8 3 -11 6c-1 2 -2 3 -3 5s-3 4 -5 6c-4 4 -10 6 -16 6c-10 0 -18 -9 -25 -16
+c-7 -8 -27 -8 -34 0s-18 16 -30 16c-18 0 -32 -14 -32 -32c0 -2 1 -5 1 -7c2 -9 7 -17 15 -21v-34v-35c0 -9 7 -16 16 -16v26v23v32c10 0 18 4 24 11c2 2 3 4 4 6c0 0 6 10 12 11s20 6 30 -5c4 -5 11 -9 19 -9c3 0 5 1 7 2c3 1 7 2 9 4v0c3 2 6 4 10 4c7 0 12 -4 14 -10
+c0 0 1 -1 1 -2c1 -3 1 -5 3 -8c7 -12 20 -20 35 -20c13 0 25 6 32 16c5 7 8 15 8 24s9 8 9 8h7h48c6 0 13 -3 15 -9zM416 128v96c0 18 -14 32 -32 32h-32v-160h32c18 0 32 14 32 32zM128 280c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM288 280c0 5 3 8 8 8s8 -3 8 -8
+s-3 -8 -8 -8s-8 3 -8 8z" />
+ <glyph glyph-name="ion-bluetooth" unicode="&#xf116;" horiz-adv-x="256"
+d="M12 304c16 16 18 13 19 12l68 -65v0v0c2 -2 10 -10 10 -3v156v0v2c0 6 6 10 12 10c4 0 7 -2 9 -4v0s117 -113 122 -117s5 -10 1 -14l-84 -81s-4 -4 -4 -8s4 -8 4 -8l84 -81c4 -4 4 -10 -1 -14s-122 -117 -122 -117v0c-2 -2 -5 -4 -9 -4c-6 0 -12 4 -12 10v2v0v156
+s-8 -1 -10 -3v0v-1l-68 -64c-1 -1 -3 -4 -19 12s-12 17 -11 18s90 86 90 86s4 3 4 8v0c0 5 -4 8 -4 8s-89 85 -90 86s-5 2 11 18zM152 328v-79c0 -8 8 -1 10 1l30 30s3 5 3 7s-1 5 -3 7l-30 30c-2 2 -10 11 -10 4zM152 135v-79s8 2 10 4l30 30c2 2 3 5 3 7s-1 5 -3 7l-30 30
+c-2 2 -10 9 -10 1z" />
+ <glyph glyph-name="ion-bonfire" unicode="&#xf315;" horiz-adv-x="384"
+d="M207 97l15 -89c1 -3 1 -5 1 -8c0 -18 -14 -32 -32 -32s-32 14 -32 32c0 2 0 5 1 7l15 92v0c2 7 8 13 16 13s15 -7 16 -15zM242 93v0v0v0zM329 58c9 -8 10 -25 0 -35s-27 -9 -35 0c-1 1 -2 3 -3 4l-49 66c-3 5 -2 11 2 15c5 5 10 5 16 1l64 -47c2 -1 3 -3 5 -4zM309 113v0
+v0v0zM371 126c9 -1 13 -7 13 -19c0 -9 -10 -14 -18 -12l-57 18v0v0c-3 2 -6 5 -5 9s4 7 8 6zM75 113v0v0v0zM75 113v0l-58 -18c-8 -2 -17 3 -17 12c0 12 3 18 12 19l60 2c4 1 7 -2 8 -6s-2 -7 -5 -9v0zM124 109c5 4 11 4 16 -1c4 -4 5 -10 2 -15l-49 -66c-1 -1 -2 -3 -3 -4
+c-10 -10 -25 -10 -35 0s-10 25 0 35c2 2 3 3 5 4zM288 320c0 -32 -9 -58 -50 -86c-37 -26 -94 -46 -110 -106c0 0 -58 24 -48 96s124 106 112 192c24 0 96 -35 96 -96zM288 192c-16 -50 -44 -64 -80 -64c-15 0 -32 9 -43 26c12 15 28 26 47 37c9 5 20 10 29 16
+c21 14 38 31 47 49c5 -15 5 -48 0 -64zM88 288c-6 4 -9 14 -8 27c2 22 34 39 32 69c14 2 31 -3 42 -24c-5 -11 -15 -21 -28 -34s-26 -22 -38 -38z" />
+ <glyph glyph-name="ion-bookmark" unicode="&#xf26b;" horiz-adv-x="192"
+d="M184 384c4 0 8 -4 8 -8v-56h-192v56c0 4 4 8 8 8h176zM0 0v304h192v-304l-96 96z" />
+ <glyph glyph-name="ion-bowtie" unicode="&#xf3c0;"
+d="M192 236c0 0 8 5 20 7c21 4 39 5 47 -9c10 -17 19 -53 17 -85c-1 -17 -5 -22 -5 -22s-15 -10 -47 -7c-35 3 -40 15 -40 15s5 12 8 43s0 58 0 58zM152 163c-17 -4 -38 -10 -38 -10s45 4 64 9c-4 -21 -10 -34 -10 -34s-83 -80 -116 -80c-28 0 -52 68 -52 144s26 144 52 144
+c35 0 106 -57 128 -97c0 0 3 -16 2 -32c-10 5 -24 10 -44 14c-28 6 -42 3 -42 3s18 -4 57 -17c15 -5 22 -8 29 -10c0 -3 -1 -7 -1 -10c0 -5 0 -10 -1 -15c-5 -2 -15 -6 -28 -9zM396 336c26 0 52 -68 52 -144s-24 -144 -52 -144c-37 0 -104 68 -112 79c0 0 4 5 5 22v9
+c16 -7 70 -13 70 -13s-21 6 -40 11c-13 4 -25 8 -30 10c-1 11 -2 23 -4 33c17 11 69 34 69 34s-15 -2 -35 -9c-14 -5 -29 -11 -37 -14c-3 10 -7 18 -10 24c0 1 -1 4 -1 4v1c22 40 89 97 125 97z" />
+ <glyph glyph-name="ion-briefcase" unicode="&#xf26c;"
+d="M240 176v8h208v-176c0 -4 -4 -8 -8 -8h-432c-4 0 -8 4 -8 8v176h208v-8h32zM440 304c4 0 8 -4 8 -8v-96h-208v8h-32v-8h-208v96c0 4 4 8 8 8h120v31c1 28 22 49 51 49h90c30 0 50 -21 51 -49v-31h120zM288 332v1c0 10 -9 19 -19 19h-90c-10 0 -19 -9 -19 -19v-1v-1v-27
+h128v27v1z" />
+ <glyph glyph-name="ion-bug" unicode="&#xf2be;"
+d="M343 321c-6 -16 -16 -31 -28 -43c-24 -24 -57 -37 -91 -37s-67 13 -91 37c-12 12 -22 27 -28 43c29 39 72 63 119 63s90 -24 119 -63zM95 305c22 -45 68 -77 121 -80v-225c-40 2 -77 22 -104 54c-7 -6 -10 -9 -13 -15c8 -9 7 -22 -1 -31c-9 -10 -24 -11 -34 -2
+s-11 24 -2 34l3 3s2 1 2 1c4 13 13 25 27 36c-15 26 -26 57 -29 90c-7 0 -12 -2 -17 -3c-1 -13 -11 -23 -24 -23s-24 11 -24 24s11 24 24 24h3c4 2 8 5 12 6c7 2 14 4 25 4c1 23 6 45 13 65c-6 4 -11 7 -15 11c-6 5 -11 13 -14 19c-1 0 -3 1 -4 2c-12 6 -15 21 -9 33
+s21 15 33 9c11 -6 15 -20 10 -31c2 -3 3 -7 4 -8c2 -2 5 -3 8 -5c2 3 3 5 5 8zM424 192c13 0 24 -11 24 -24s-11 -24 -24 -24s-23 10 -24 23c-5 1 -10 3 -17 3c-3 -33 -14 -64 -29 -90c14 -11 23 -23 27 -36c0 0 1 0 2 -1l3 -3c9 -10 8 -25 -2 -34s-25 -8 -34 2
+c-8 9 -9 22 -1 31c-3 6 -6 9 -13 15c-27 -32 -64 -52 -104 -54v225c53 3 99 35 121 80c2 -3 3 -5 5 -8c3 2 6 3 8 5c1 1 2 5 4 8c-5 11 -1 25 10 31c12 6 27 3 33 -9s3 -27 -9 -33c-1 -1 -3 -2 -4 -2c-3 -6 -8 -14 -14 -19c-4 -4 -9 -7 -15 -11c7 -20 12 -42 13 -65
+c11 0 18 -2 25 -4c4 -1 8 -4 12 -6h3z" />
+ <glyph glyph-name="ion-calculator" unicode="&#xf26d;" horiz-adv-x="320"
+d="M304 416c9 0 16 -7 16 -16v-416c0 -9 -7 -16 -16 -16h-288c-9 0 -16 7 -16 16v416c0 9 7 16 16 16h288zM48 240v-32h32v32h-32zM48 176v-32h32v32h-32zM48 112v-32h32v32h-32zM144 16v32h-96v-32h96zM144 80v32h-32v-32h32zM144 144v32h-32v-32h32zM144 208v32h-32v-32
+h32zM208 16v32h-32v-32h32zM208 80v32h-32v-32h32zM208 144v32h-32v-32h32zM208 208v32h-32v-32h32zM272 16v96h-32v-96h32zM272 144v32h-32v-32h32zM272 208v32h-32v-32h32zM272 288v80h-224v-80h224z" />
+ <glyph glyph-name="ion-calendar" unicode="&#xf117;"
+d="M112 320c-18 0 -32 14 -32 32v32c0 18 14 32 32 32s32 -14 32 -32v-32c0 -18 -14 -32 -32 -32zM336 320c-18 0 -32 14 -32 32v32c0 18 14 32 32 32s32 -14 32 -32v-32c0 -18 -14 -32 -32 -32zM440 384c4 0 8 -4 8 -8v-400c0 -4 -4 -8 -8 -8h-432c-4 0 -8 4 -8 8v400
+c0 4 4 8 8 8h56v-41c0 -22 24 -39 48 -39s48 17 48 39v41h128v-41c0 -22 25 -39 49 -39s47 17 47 39v41h56zM400 16v256h-352v-256h352z" />
+ <glyph glyph-name="ion-camera" unicode="&#xf118;" horiz-adv-x="416"
+d="M382 301c18 0 34 -14 34 -33v-202c0 -19 -16 -34 -34 -34h-348c-19 0 -34 15 -34 34v202c0 19 15 33 34 33h69l39 40v0c6 7 15 11 25 11h84c9 0 17 -4 23 -10v0v0v0l41 -41h67zM208 82c51 0 92 42 92 93s-41 93 -92 93s-92 -42 -92 -93s41 -93 92 -93zM376 248
+c8 0 14 6 14 14s-6 14 -14 14s-14 -6 -14 -14s6 -14 14 -14zM208 245c38 0 70 -31 70 -70s-32 -70 -70 -70c-39 0 -70 31 -70 70s31 70 70 70z" />
+ <glyph glyph-name="ion-card" unicode="&#xf119;"
+d="M420 352c16 0 28 -12 28 -28v0v-264v0c0 -16 -12 -28 -28 -28h-392c-16 0 -28 12 -28 28v0v0v264v0v0c0 16 12 28 28 28h392zM45 320c-7 0 -12 -5 -13 -12v-20h384v20c-1 7 -6 12 -13 12h-358zM403 64c7 0 12 5 13 12v116h-384v-116c1 -7 6 -12 13 -12h358zM64 128v16
+h192v-16h-192zM64 96v16h96v-16h-96zM320 96v48h64v-48h-64z" />
+ <glyph glyph-name="ion-cash" unicode="&#xf316;" horiz-adv-x="512"
+d="M0 352h512v-256h-512v256zM193 128c-20 23 -33 58 -33 96s13 73 33 96h-97c0 -35 -29 -64 -64 -64v-80c27 0 48 -21 48 -48h113zM298 187c3 4 4 9 4 15c0 3 0 5 -1 8s-2 6 -4 8s-4 4 -7 6s-6 4 -10 5c-1 0 -4 1 -7 2s-5 0 -8 1v31c2 -1 5 -2 7 -3c4 -3 6 -7 7 -13h20
+c0 5 -2 9 -4 13s-5 8 -9 11s-9 5 -14 6c-2 1 -5 2 -7 2v9h-18v-9c-2 0 -4 -1 -6 -2c-5 -1 -10 -2 -14 -5s-7 -6 -9 -10s-4 -9 -4 -14c0 -3 0 -5 1 -8s2 -5 4 -7s5 -5 8 -7s7 -4 12 -5c3 -1 6 0 8 -1v-35c-3 1 -6 2 -9 4s-5 4 -6 7s-2 6 -2 9h-20c0 -5 2 -11 4 -16
+c3 -5 6 -8 10 -11s9 -6 15 -7c3 -1 5 -2 8 -2v-9h18v9c3 0 6 1 9 2c5 1 10 2 14 5s7 7 10 11zM480 176v80c-35 0 -64 29 -64 64h-97c20 -23 33 -58 33 -96s-13 -73 -33 -96h113c0 27 22 48 48 48zM64 224c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32z
+M384 224c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32zM273 213c2 -1 4 -2 6 -4s3 -5 3 -9c0 -2 0 -4 -1 -6s-2 -4 -4 -5s-5 -3 -8 -4c-1 0 -2 -1 -4 -1v31c3 -1 6 -1 8 -2zM236 257c1 2 3 3 5 4s4 2 6 2v-26c-4 1 -7 3 -9 5s-4 4 -4 8c0 3 1 5 2 7zM0 32
+v32h512v-32h-512z" />
+ <glyph glyph-name="ion-chatbox-working" unicode="&#xf11a;" horiz-adv-x="416"
+d="M76 48c-42 0 -76 31 -76 71v209c0 40 34 72 76 72h264c42 0 76 -32 76 -72v-209c0 -40 -34 -71 -76 -71h-4v-64s-79 54 -86 59s-7 5 -21 5h-153zM304 256c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM208 256c-18 0 -32 -14 -32 -32s14 -32 32 -32
+s32 14 32 32s-14 32 -32 32zM112 256c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32z" />
+ <glyph glyph-name="ion-chatbox" unicode="&#xf11b;" horiz-adv-x="416"
+d="M76 48c-42 0 -76 31 -76 71v209c0 40 34 72 76 72h264c42 0 76 -32 76 -72v-209c0 -40 -34 -71 -76 -71h-4v-64s-79 54 -86 59s-7 5 -21 5h-153z" />
+ <glyph glyph-name="ion-chatboxes" unicode="&#xf11c;" horiz-adv-x="416"
+d="M246 82l26 -18c-4 -21 -29 -32 -52 -32h-90c-8 0 -11 -2 -13 -3l-53 -45v48h-16c-26 0 -48 16 -48 41v129c0 25 20 45 46 45h2v-101c0 -33 29 -59 64 -59h117c10 0 14 -3 17 -5zM353 400c35 0 63 -27 63 -60v-168c0 -33 -28 -60 -63 -60h-17v-64l-75 60c-2 2 -7 4 -17 4
+h-101c-35 0 -63 27 -63 60v98v70c0 33 21 60 56 60h217z" />
+ <glyph glyph-name="ion-chatbubble-working" unicode="&#xf11d;" horiz-adv-x="416"
+d="M208 -1c-115 0 -208 89 -208 200s93 201 208 201s208 -90 208 -201c0 -40 -12 -77 -33 -108c-1 -1 -2 -3 -3 -4v0c-2 -4 -4 -10 -4 -15l22 -88l-84 31c-4 2 -8 2 -12 2s-7 -1 -11 -2v0c-1 0 -1 -1 -2 -1c-25 -10 -52 -15 -81 -15zM304 224c-18 0 -32 -14 -32 -32
+s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM208 224c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM112 224c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32z" />
+ <glyph glyph-name="ion-chatbubble" unicode="&#xf11e;" horiz-adv-x="416"
+d="M208 -1c-115 0 -208 89 -208 200s93 201 208 201s208 -90 208 -201c0 -40 -12 -77 -33 -108c-1 -1 -2 -3 -3 -4v0c-2 -4 -4 -10 -4 -15l22 -88l-84 31c-4 2 -8 2 -12 2s-7 -1 -11 -2v0c-1 0 -1 -1 -2 -1c-25 -10 -52 -15 -81 -15z" />
+ <glyph glyph-name="ion-chatbubbles" unicode="&#xf11f;" horiz-adv-x="416"
+d="M25 57c-1 1 0 2 -1 3c-15 22 -24 49 -24 77c0 42 19 80 49 106c-2 -11 -4 -22 -4 -34c0 -92 78 -168 174 -168c15 0 30 2 44 6c-27 -32 -69 -53 -115 -53c-20 0 -40 5 -58 12h-1v0c-2 1 -5 2 -8 2s-6 -1 -9 -2l-56 -22l12 63c0 4 -1 7 -3 10v0zM242 400
+c96 0 174 -76 174 -168c0 -33 -11 -64 -28 -90c-1 -1 -1 -2 -2 -3v0c-2 -4 -3 -8 -3 -12l17 -74l-69 26c-3 1 -6 2 -10 2c-3 0 -6 -1 -9 -2v0l-2 -1c-8 -3 -16 -5 -24 -7c-14 -4 -29 -6 -44 -6c-96 0 -173 75 -173 167c0 12 1 24 3 35c16 76 86 133 170 133z" />
+ <glyph glyph-name="ion-checkmark-circled" unicode="&#xf120;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM339 267c1 1 1 2 1 3s0 3 -1 4l-31 24c-1 1 -3 1 -4 1s-2 0 -3 -1l-111 -143s-44 42 -45 43s-4 3 -6 3s-3 -2 -4 -3l-25 -25l-1 -1c-1 -1 -1 -3 -1 -4s0 -2 1 -3l2 -1
+s78 -75 79 -76s3 -3 5 -3s4 2 5 3z" />
+ <glyph glyph-name="ion-checkmark-round" unicode="&#xf121;" horiz-adv-x="416"
+d="M400 376c17 -13 22 -39 9 -57l-207 -302c-13 -18 -37 -22 -54 -9s-137 147 -137 147c-15 16 -15 42 1 58s40 15 55 -2l99 -107l180 263c13 18 37 22 54 9z" />
+ <glyph glyph-name="ion-checkmark" unicode="&#xf122;" horiz-adv-x="416"
+d="M414 338c1 -2 2 -4 2 -6s-1 -4 -2 -6l-249 -320c-2 -2 -5 -6 -9 -6s-8 3 -10 5s-141 136 -141 136l-3 3c-1 2 -2 4 -2 6s1 3 2 5l2 2c14 15 42 44 44 46s4 6 8 6s8 -4 10 -6s80 -78 80 -78l200 257c2 2 4 2 6 2s5 -1 7 -2z" />
+ <glyph glyph-name="ion-chevron-down" unicode="&#xf123;"
+d="M224 150v0v0l174 167c4 4 12 4 16 0l31 -30c4 -4 4 -12 0 -16l-213 -204c-2 -2 -5 -3 -8 -3s-6 1 -8 3l-213 204c-4 4 -4 12 0 16l31 30c4 4 12 4 16 0z" />
+ <glyph glyph-name="ion-chevron-left" unicode="&#xf124;" horiz-adv-x="256"
+d="M86 192l167 -174c4 -4 4 -12 0 -16l-30 -31c-4 -4 -12 -4 -16 0l-204 213c-2 2 -3 5 -3 8s1 6 3 8l204 213c4 4 12 3 16 -1l30 -30c4 -4 4 -12 0 -16l-167 -174v0v0z" />
+ <glyph glyph-name="ion-chevron-right" unicode="&#xf125;" horiz-adv-x="256"
+d="M170 192v0v0l-167 174c-4 4 -4 12 0 16l30 30c4 4 12 5 16 1l204 -213c2 -2 3 -5 3 -8s-1 -6 -3 -8l-204 -213c-4 -4 -12 -4 -16 0l-30 31c-4 4 -4 12 0 16z" />
+ <glyph glyph-name="ion-chevron-up" unicode="&#xf126;"
+d="M224 234l-174 -167c-4 -4 -12 -4 -16 0l-31 30c-4 4 -4 12 0 16l213 204c2 2 5 3 8 3s6 -1 8 -3l213 -204c4 -4 4 -12 0 -16l-31 -30c-4 -4 -12 -4 -16 0l-174 167v0v0z" />
+ <glyph glyph-name="ion-clipboard" unicode="&#xf127;" horiz-adv-x="352"
+d="M80 288c2 20 10 35 28 40l1 1c12 3 21 7 21 20v21c0 26 21 46 46 46s46 -20 46 -46v-21c0 -13 9 -18 21 -21h2c18 -5 25 -20 27 -40h-192zM176 384c-8 0 -13 -6 -13 -14s5 -14 13 -14s14 6 14 14s-6 14 -14 14zM325 384c15 0 27 -12 27 -28v-360c0 -16 -12 -28 -27 -28
+h-149h-148c-15 0 -28 12 -28 28v360c0 16 13 28 28 28h73v-13c0 -11 -9 -19 -19 -19h-37c-7 0 -12 -6 -12 -13v-327c0 -6 5 -12 11 -12h265c6 0 11 6 11 12v327c0 7 -5 13 -12 13h-37c-10 0 -20 8 -20 19v13h74zM64 224v32h112v-32h-112zM64 32v32h160v-32h-160zM64 96v32
+h129v-32h-129zM64 160v32h208v-32h-208z" />
+ <glyph glyph-name="ion-clock" unicode="&#xf26e;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c10 10 19 21 26 33l-27 16l8 14l27 -16c13 25 21 52 22 81h-32v16h32c-1 29 -9 56 -22 81l-27 -16l-8 14l27 16c-7 12 -16 23 -26 33s-21 19 -33 26l-16 -27l-14 8
+l16 27c-25 13 -52 21 -81 22v-32h-16v32c-29 -1 -56 -9 -81 -22l16 -27l-14 -8l-16 27c-12 -7 -23 -16 -33 -26s-19 -21 -26 -33l27 -16l-8 -14l-27 16c-13 -25 -21 -52 -22 -81h32v-16h-32c1 -29 9 -56 22 -81l27 16l8 -14l-27 -16c7 -12 16 -23 26 -33s21 -19 33 -26
+l16 27l14 -8l-16 -27c25 -13 52 -21 81 -22v32h16v-32c29 1 56 9 81 22l-16 27l14 8l16 -27c12 7 23 16 33 26zM368 207v-32h-117c-6 -9 -16 -15 -27 -15c-18 0 -32 14 -32 32c0 12 6 22 16 28v68h32v-68c5 -3 9 -8 12 -13h116z" />
+ <glyph glyph-name="ion-close-circled" unicode="&#xf128;"
+d="M224 415c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM332 116l-75 75l76 75c3 3 3 9 0 12l-22 21c-2 2 -4 3 -6 3s-3 -1 -5 -3l-76 -74l-76 74c-2 2 -3 3 -5 3s-4 -1 -6 -3l-21 -21c-3 -3 -3 -9 0 -12l76 -75l-76 -76
+c-2 -1 -2 -3 -2 -5s0 -4 2 -6l21 -22c2 -2 4 -2 6 -2s4 0 6 2l75 76l76 -75c2 -2 3 -3 5 -3s4 1 6 3l21 21c2 1 3 4 3 6s-1 4 -3 6z" />
+ <glyph glyph-name="ion-close-round" unicode="&#xf129;" horiz-adv-x="384"
+d="M374 61c14 -14 14 -37 0 -51s-37 -14 -51 0l-131 131l-131 -131c-14 -14 -36 -14 -50 0s-14 37 0 51l130 131l-130 131c-14 14 -14 37 0 51s36 14 50 0l131 -131l131 131c14 14 37 14 51 0s14 -37 0 -51l-131 -131z" />
+ <glyph glyph-name="ion-close" unicode="&#xf12a;" horiz-adv-x="384"
+d="M380 61c3 -3 4 -6 4 -10s-1 -7 -4 -10l-38 -37c-3 -3 -5 -4 -9 -4s-7 1 -10 4l-131 131l-131 -131c-3 -3 -5 -4 -9 -4s-7 1 -10 4l-38 37c-3 3 -4 6 -4 10s1 7 4 10l132 131l-132 130c-5 5 -5 15 0 20l37 38c3 2 6 4 10 4s7 -1 10 -4l131 -130l131 130c3 2 6 4 10 4
+s7 -1 10 -4l37 -38c5 -5 5 -14 0 -19l-132 -130z" />
+ <glyph glyph-name="ion-closed-captioning" unicode="&#xf317;" horiz-adv-x="512"
+d="M0 384h512v-384h-512v384zM464 192c0 27 0 44 -4 80s-23 56 -59 60s-91 4 -138 4h-7h-7c-47 0 -102 0 -138 -4s-55 -24 -59 -60s-4 -53 -4 -80s2 -47 4 -80s19 -56 59 -60s96 -4 145 -4s105 0 145 4s57 27 59 60s4 53 4 80zM372 164v4h53c0 -27 -7 -48 -19 -62
+s-32 -21 -61 -21c-14 0 -26 2 -36 5s-18 9 -25 17s-12 19 -15 33s-5 30 -5 51s3 39 7 53s9 25 17 33s17 14 27 17s22 5 34 5c25 0 44 -7 57 -21s19 -37 19 -62h-52v1c0 20 -12 33 -27 33s-25 -11 -28 -30c0 0 -2 -11 -2 -29s2 -28 2 -28c1 -17 12 -29 27 -29s27 10 27 29v1z
+M195 164v4h53c0 -27 -7 -48 -19 -62s-32 -21 -61 -21c-14 0 -26 2 -36 5s-18 9 -25 17s-12 19 -15 33s-5 30 -5 51s3 39 7 53s9 25 17 33s17 14 27 17s22 5 34 5c25 0 44 -7 57 -21s19 -37 19 -62h-52v1c0 20 -12 33 -27 33s-25 -11 -28 -30c0 0 -2 -11 -2 -29s2 -28 2 -28
+c1 -17 12 -29 27 -29s27 10 27 29v1z" />
+ <glyph glyph-name="ion-cloud" unicode="&#xf12b;"
+d="M366 215c45 0 82 -38 82 -84s-37 -83 -82 -83v0h-276c-49 0 -90 41 -90 91c0 40 26 74 61 86c5 29 29 51 59 51c10 0 18 -3 26 -7c19 40 59 67 105 67c64 0 115 -53 115 -118v-3z" />
+ <glyph glyph-name="ion-code-download" unicode="&#xf26f;"
+d="M299 164l-63 -63v0l-1 -1v0l-2 -1v0l-1 -1v0l-2 -1v0h-1v0h-1c-1 0 -3 -1 -4 -1s-3 1 -4 1h-1v0h-1v0l-2 1v0l-1 1v0c-1 1 -2 1 -3 2v0l-63 63c-6 6 -6 17 0 23s18 6 24 0l35 -34v118c0 9 7 17 16 17s16 -8 16 -17v-118l35 34c6 6 18 6 24 0s6 -17 0 -23zM136 56
+c-6 0 -12 2 -17 7l-112 112c-9 9 -9 25 0 34l112 112c9 9 25 9 34 0s9 -25 0 -34l-95 -95l95 -95c9 -9 9 -25 0 -34c-5 -5 -11 -7 -17 -7zM312 56c-6 0 -12 2 -17 7c-9 9 -9 25 0 34l95 95l-95 95c-9 9 -9 25 0 34s25 9 34 0l112 -112c9 -9 9 -25 0 -34l-112 -112
+c-5 -5 -11 -7 -17 -7z" />
+ <glyph glyph-name="ion-code-working" unicode="&#xf270;"
+d="M128 192c0 16 8 24 24 24s24 -8 24 -24s-8 -24 -24 -24s-24 8 -24 24zM200 192c0 16 8 24 24 24s24 -8 24 -24s-8 -24 -24 -24s-24 8 -24 24zM272 192c0 16 8 24 24 24s24 -8 24 -24s-8 -24 -24 -24s-24 8 -24 24zM136 56c-7 0 -12 2 -17 7l-112 112c-5 5 -7 10 -7 17
+s2 12 7 17l112 112c5 5 10 7 17 7s12 -2 17 -7s7 -10 7 -17s-2 -12 -7 -17l-95 -95l95 -95c5 -5 7 -10 7 -17s-2 -12 -7 -17s-10 -7 -17 -7zM312 56c-7 0 -12 2 -17 7s-7 10 -7 17s2 12 7 17l95 95l-95 95c-5 5 -7 10 -7 17s2 12 7 17s10 7 17 7s12 -2 17 -7l112 -112
+c5 -5 7 -10 7 -17s-2 -12 -7 -17l-112 -112c-5 -5 -10 -7 -17 -7z" />
+ <glyph glyph-name="ion-code" unicode="&#xf271;"
+d="M136 56c-6 0 -12 2 -17 7l-112 112c-9 9 -9 25 0 34l112 112c9 9 25 9 34 0s9 -25 0 -34l-95 -95l95 -95c9 -9 9 -25 0 -34c-5 -5 -11 -7 -17 -7zM312 56c-6 0 -12 2 -17 7c-9 9 -9 25 0 34l95 95l-95 95c-9 9 -9 25 0 34s25 9 34 0l112 -112c9 -9 9 -25 0 -34l-112 -112
+c-5 -5 -11 -7 -17 -7z" />
+ <glyph glyph-name="ion-coffee" unicode="&#xf272;" horiz-adv-x="384"
+d="M319 191c37 -7 65 -40 65 -79c0 -20 -8 -39 -21 -54c-15 -17 -37 -26 -61 -26c-8 0 -17 1 -25 3c-6 1 -10 3 -15 5c-11 -15 -23 -25 -32 -33v0c-5 -5 -12 -7 -19 -7h-102c-7 0 -14 2 -19 7v0c-17 15 -41 36 -62 86s-28 91 -28 111s3 20 16 20h101c-5 17 -37 19 -37 46
+c0 17 15 32 28 37c-2 -8 -3 -14 -3 -21c0 -19 39 -30 39 -53c0 -3 0 -6 -1 -9h56c1 5 2 10 2 14c0 36 -56 36 -56 84c0 28 21 55 47 62c-4 -14 -9 -23 -9 -35c0 -32 57 -50 57 -88c0 -13 -5 -25 -12 -37h76c13 0 16 0 16 -20c0 -4 0 -8 -1 -13zM302 64c33 0 50 25 50 48
+s-17 43 -39 47c-4 -19 -11 -42 -21 -66c-4 -9 -8 -17 -12 -25c6 -3 13 -4 22 -4z" />
+ <glyph glyph-name="ion-compass" unicode="&#xf273;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224c0 39 10 76 27 108c-16 12 -27 30 -27 52c0 35 29 64 64 64c22 0 40 -11 52 -27c32 17 69 27 108 27zM32 352c0 -10 5 -20 13 -26c13 17 28 32 45 45c-6 8 -16 13 -26 13c-18 0 -32 -14 -32 -32z
+M360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56s100 20 136 56zM320 320c0 0 -54 -130 -72 -152s-120 -104 -120 -104s54 132 72 152s120 104 120 104z" />
+ <glyph glyph-name="ion-compose" unicode="&#xf12c;" horiz-adv-x="384"
+d="M379 348c7 -7 7 -18 0 -25l-32 -31l-55 55l31 32c7 7 18 7 25 0zM282 338l55 -55l-177 -173l-64 -14l14 64zM320 192l32 32v-201c0 -13 -10 -23 -23 -23h-306c-13 0 -23 10 -23 23v306c0 13 10 23 23 23h201l-32 -32h-149c-6 0 -11 -5 -11 -10v-268s4 -10 10 -10h269
+s9 5 9 10v150z" />
+ <glyph glyph-name="ion-connection-bars" unicode="&#xf274;" horiz-adv-x="352"
+d="M0 32v64h64v-64h-64zM96 32v128h64v-128h-64zM192 32v224h64v-224h-64zM288 32v320h64v-320h-64z" />
+ <glyph glyph-name="ion-contrast" unicode="&#xf275;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56v-384c51 0 100 20 136 56z" />
+ <glyph glyph-name="ion-crop" unicode="&#xf3c1;"
+d="M320 -32v48h64v-48h-64zM384 96h64v-64h-384v256h-64v64h64v64h64v-320h192v192h-176v64h240v-256z" />
+ <glyph glyph-name="ion-cube" unicode="&#xf318;"
+d="M435 280c7 0 13 -6 13 -12v-183c0 -9 -6 -17 -14 -22v-1l-175 -92v-1c-2 -1 -4 -1 -6 -1c-7 0 -13 6 -13 12v185c0 9 5 17 13 22v0l3 2l172 89l2 1c2 1 3 1 5 1zM422 329c0 0 8 -3 8 -9c0 -7 -8 -11 -8 -11l-183 -97l-2 -1c-4 -2 -8 -3 -13 -3s-9 1 -13 3l-2 1l-183 96
+s-8 5 -8 12c0 6 8 9 8 9l181 82s11 5 17 5s17 -5 17 -5zM195 187c8 -5 13 -13 13 -22v-185c0 -6 -6 -12 -13 -12c-2 0 -4 1 -6 2v0l-175 92v1c-8 5 -14 13 -14 22v183c0 6 6 12 13 12c2 0 4 0 5 -1l2 -1l171 -89z" />
+ <glyph glyph-name="ion-disc" unicode="&#xf12d;"
+d="M224 289c54 0 97 -43 97 -97s-43 -97 -97 -97s-97 43 -97 97s43 97 97 97zM224 148c24 0 44 20 44 44s-20 44 -44 44s-44 -20 -44 -44s20 -44 44 -44zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM224 69
+c68 0 123 55 123 123s-55 123 -123 123s-123 -55 -123 -123s55 -123 123 -123z" />
+ <glyph glyph-name="ion-document-text" unicode="&#xf12e;" horiz-adv-x="288"
+d="M286 279c1 -3 2 -6 2 -10v-245c0 -13 -10 -24 -22 -24h-243c-12 0 -23 11 -23 24v336c0 13 11 24 23 24h160c3 0 6 0 9 -2c2 -1 5 -3 7 -5l84 -92c2 -2 2 -4 3 -6zM48 269v-10c0 -1 1 -3 3 -3h71c2 0 3 2 3 3v10c0 2 -1 3 -3 3h-71c-2 0 -3 -1 -3 -3zM48 141v-10
+c0 -1 1 -3 3 -3h123c2 0 2 2 2 3v10c0 2 0 3 -2 3h-123c-2 0 -3 -1 -3 -3zM208 67v10c0 2 0 3 -2 3h-155c-2 0 -3 -1 -3 -3v-10c0 -1 1 -3 3 -3h155c2 0 2 2 2 3zM240 195v10c0 2 0 3 -2 3h-187c-2 0 -3 -1 -3 -3v-10c0 -1 1 -3 3 -3h187c2 0 2 2 2 3zM193 270h60l-71 78
+v-66c0 -6 5 -12 11 -12z" />
+ <glyph glyph-name="ion-document" unicode="&#xf12f;" horiz-adv-x="288"
+d="M287 279c1 -3 1 -5 1 -9v-244c0 -13 -9 -26 -21 -26h-243c-12 0 -24 13 -24 26v335c0 13 12 23 24 23h160c3 0 6 0 9 -2c2 -1 5 -2 7 -4l83 -92c2 -2 3 -4 4 -7zM193 337v-63h58zM32 32h224v210h-67c-15 0 -28 13 -28 28v82h-129v-320z" />
+ <glyph glyph-name="ion-drag" unicode="&#xf130;" horiz-adv-x="512"
+d="M0 272v32h512v-32h-512zM0 176v32h512v-32h-512zM0 80v32h512v-32h-512z" />
+ <glyph glyph-name="ion-earth" unicode="&#xf276;"
+d="M325 322c2 -4 7 -12 3 -15c-3 -2 -10 -2 -13 5s0 11 -5 9s-7 3 -6 4c1 2 3 3 5 4c0 2 -4 8 2 7c4 -1 12 -10 14 -14zM344 277v0v0zM403 251c0 0 -2 0 0 0v0zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM141 19l8 -4
+c3 -1 6 -2 10 -3c14 -5 28 -8 43 -10c28 -3 56 -1 83 8c15 5 30 11 43 20c6 4 6 16 10 24c8 16 -2 33 12 47c12 14 4 19 4 34c0 10 8 18 4 29c-1 4 -7 -3 -9 1c-5 7 -21 1 -28 2c-13 2 -24 14 -33 23c-5 5 0 20 1 26c4 15 0 33 19 38c5 1 5 9 10 11c5 1 10 3 15 4
+c9 1 17 -2 26 -2c10 0 14 -5 22 -11c7 -6 13 -3 22 -5c7 0 0 5 -2 8c-3 2 -6 2 -8 2c-16 4 -23 22 -36 30c-6 3 -9 2 -11 0c-1 -1 1 -12 1 -12c-1 -3 -10 -4 -13 -5c-9 -2 -29 17 -15 22c4 1 27 5 24 15c-3 6 2 13 -5 14c-8 1 -7 7 -15 8c-5 1 -5 11 -5 14c0 9 2 6 9 7
+c-17 11 -37 19 -57 24c-1 -3 -5 -12 -8 -12c-5 -1 -6 0 -9 -3c-9 -10 -16 -28 -25 -7c-4 11 5 19 2 28h-6h-3c6 -12 -5 -18 -8 -19c-8 0 -10 5 -17 4c-4 -1 -7 4 -11 2s-13 -8 -14 -12c-3 -12 6 -13 14 -6c6 6 17 12 25 6c6 -5 5 -9 5 -14s-1 -18 -9 -16c-4 1 -7 6 -11 3
+c-8 -7 -18 -6 -29 -9c-10 -2 -16 -6 -25 -9c-8 -3 -11 -4 -12 -12c0 -2 0 -14 -3 -15c-5 -2 -8 22 -22 20c-12 -1 -30 -13 -25 -28c2 -5 28 -3 10 -14c-2 -1 2 -17 2 -20c1 -8 13 -18 21 -10c6 6 6 5 14 2c15 -8 33 -15 45 -27c6 -6 9 -24 17 -28c9 -5 19 -5 26 -14
+c6 -7 -2 -19 -8 -23c-4 -2 -12 -24 -16 -29c-2 -4 -12 -6 -16 -7c-3 0 -7 -9 -9 -11c-7 -7 -8 -13 -17 -19c-18 -12 -22 -23 -18 -44c2 -8 5 -13 11 -16zM100 46l2 -2c7 -6 15 -11 23 -16c-21 21 -23 49 -21 78l3 24c1 3 -4 7 -4 11c0 10 0 5 -8 13c-4 4 -10 11 -12 17
+c-7 16 1 30 10 43c9 14 -7 20 -10 32c-1 6 -7 6 -6 12c1 7 -4 5 -9 9c-12 8 -1 20 -7 26c-43 -70 -36 -162 16 -224c1 -1 0 -1 1 -2h1c3 -4 6 -8 9 -11s7 -6 10 -9z" />
+ <glyph glyph-name="ion-easel" unicode="&#xf3c2;"
+d="M48 112v192h352v-192h-352zM432 352c9 0 16 -7 16 -16v-256c0 -9 -7 -16 -16 -16h-416c-9 0 -16 7 -16 16v256c0 9 7 16 16 16h416zM416 96v224h-384v-224h384zM48 -32l29 80h31l-28 -80h-32zM239 416l17 -48h-64l17 48h30zM340 48h31l29 -80h-32zM208 0v48h32v-48h-32z
+" />
+ <glyph glyph-name="ion-edit" unicode="&#xf2bf;"
+d="M381 259l-250 -251l-91 91l251 250zM440 360c12 -12 11 -32 -2 -45l-45 -45l-91 91l45 45c13 13 33 14 45 2zM32 85l85 -85l-117 -32z" />
+ <glyph glyph-name="ion-egg" unicode="&#xf277;" horiz-adv-x="320"
+d="M160 416c64 0 160 -133 160 -257s-64 -191 -160 -191s-160 67 -160 191s96 257 160 257z" />
+ <glyph glyph-name="ion-eject" unicode="&#xf131;" horiz-adv-x="320"
+d="M303 128h-286v0c-10 0 -17 7 -17 16c0 3 1 5 3 8l138 191c5 5 11 9 19 9s14 -4 19 -9l138 -190c2 -3 3 -6 3 -9c0 -9 -7 -16 -17 -16v0zM308 96c7 0 12 -5 12 -12v-40c0 -7 -5 -12 -12 -12h-296c-7 0 -12 5 -12 12v40c0 7 5 12 12 12h296z" />
+ <glyph glyph-name="ion-email-unread" unicode="&#xf3c3;" horiz-adv-x="480"
+d="M352 288c0 43 21 64 64 64s64 -21 64 -64s-21 -64 -64 -64s-64 21 -64 64zM209 288h127c0 -17 5 -33 15 -47c-6 -3 -14 -8 -22 -12s-16 -8 -23 -12s-14 -8 -22 -12s-15 -8 -21 -11s-11 -6 -16 -9s-9 -5 -12 -7s-4 -3 -5 -3c-6 -3 -13 -4 -21 -4s-15 1 -21 4
+c-1 1 -15 8 -42 23s-54 29 -81 44s-43 23 -46 25c-7 4 -12 8 -13 11c-1 4 -1 6 1 8s6 2 11 2h191zM277 175c18 11 45 30 83 56c16 -15 34 -23 56 -23v-155c0 -2 -1 -4 -2 -7s-3 -5 -5 -7s-4 -4 -7 -5s-6 -2 -8 -2h-185h-185c-5 0 -11 2 -16 7s-8 9 -8 14v205c0 6 3 8 9 5
+c2 -1 11 -7 26 -17s32 -22 53 -36s39 -26 53 -35l-83 -93c-2 -2 -2 -4 -1 -5c2 -1 4 -1 6 1l98 83c16 -10 25 -16 27 -17c6 -3 13 -4 21 -4s15 1 21 4c2 1 11 7 27 17l98 -83c2 -2 5 -2 6 -1s0 3 -2 5z" />
+ <glyph glyph-name="ion-email" unicode="&#xf132;" horiz-adv-x="416"
+d="M19 299c-4 2 -11 7 -13 11c-3 8 1 10 12 10h191h191c11 0 15 -2 12 -10c-2 -4 -9 -9 -13 -11c-11 -6 -163 -89 -169 -92s-12 -4 -21 -4s-15 1 -21 4s-158 86 -169 92zM408 295c9 4 8 -1 8 -5v-205c0 -9 -12 -21 -22 -21h-185h-185c-10 0 -24 12 -24 21v205s0 9 9 5
+c8 -4 83 -56 132 -88l-83 -93c-2 -2 -2 -4 -1 -5s4 -1 6 1l98 83c15 -10 25 -16 27 -17c8 -4 14 -4 21 -4s13 0 21 4c2 1 12 7 27 17l98 -83c2 -2 5 -2 6 -1s0 3 -2 5l-82 93c49 32 123 84 131 88z" />
+ <glyph glyph-name="ion-erlenmeyer-flask-bubbles" unicode="&#xf3c4;" horiz-adv-x="384"
+d="M382 21c2 -4 3 -10 0 -14s-8 -7 -13 -7h-177h-178c-5 0 -9 3 -12 7s-2 10 0 14l118 199v150c0 8 6 14 14 14s15 -6 15 -14v-80c4 3 10 5 16 5c15 0 27 -12 27 -27s-12 -26 -27 -26c-6 0 -12 2 -16 5v-31c0 -2 -1 -4 -2 -6l-35 -59h72c-15 6 -26 20 -26 37
+c0 23 19 42 43 42c15 0 27 -8 35 -19c-1 2 -1 3 -1 5v154c0 8 6 14 14 14s15 -6 15 -14v-150zM218 151h53l-31 54c2 -5 3 -11 3 -17c0 -17 -10 -31 -25 -37zM201 319c-12 0 -22 9 -22 21s10 21 22 21s22 -9 22 -21s-10 -21 -22 -21z" />
+ <glyph glyph-name="ion-erlenmeyer-flask" unicode="&#xf3c5;" horiz-adv-x="384"
+d="M375 52c6 -9 9 -20 9 -32c0 -28 -16 -52 -63 -52h-258c-47 0 -63 24 -63 52c0 12 3 23 9 32l49 73l49 77c13 20 21 44 21 70v92s-14 34 -16 43c-2 8 1 9 17 9h126c16 0 18 -1 16 -9c-2 -9 -15 -22 -15 -42v-93c0 -26 6 -50 19 -70zM345 7c3 3 7 8 7 14c0 5 -2 10 -4 14
+l-101 150c-16 26 -23 56 -23 87v112h-64v-112c0 -32 -9 -62 -25 -87l-99 -150c-2 -4 -4 -9 -4 -14c0 -6 3 -11 6 -14c4 -4 12 -7 25 -7h258c13 0 20 3 24 7zM325 37c1 -2 3 -6 3 -8c0 -7 -6 -15 -14 -15h-244c-7 0 -14 6 -14 14c0 3 1 6 3 8l81 124h103l82 -124v1zM238 106
+c2 -1 4 -2 6 -2s3 0 5 2c1 2 3 4 3 6s-1 4 -3 6c-1 2 -3 2 -5 2s-4 0 -6 -2c-1 -2 -2 -4 -2 -6s0 -4 2 -6zM285 47c4 2 4 7 2 11l-23 36c-1 2 -4 4 -7 4c-2 0 -3 0 -4 -1c-4 -2 -4 -7 -2 -11l23 -36c1 -2 5 -4 7 -4c1 0 3 0 4 1z" />
+ <glyph glyph-name="ion-eye-disabled" unicode="&#xf306;"
+d="M344 290c41 -27 76 -66 104 -100c-51 -54 -124 -135 -224 -135c-36 0 -65 8 -92 22l-77 -77l-23 23l71 71c-36 25 -68 61 -103 98c78 85 142 137 224 137c34 0 64 -9 92 -23l77 78l23 -23zM134 192c0 -19 6 -36 16 -51l27 27c-4 7 -5 15 -5 24c0 29 23 53 52 53h8
+c-5 -6 -8 -13 -8 -21c0 -3 0 -5 1 -8l51 50c-15 11 -33 17 -52 17c-49 0 -90 -41 -90 -91zM224 101c49 0 90 41 90 91c0 19 -6 37 -16 52l-50 -51c3 -1 5 -1 8 -1c8 0 14 3 20 7v-7c0 -29 -23 -53 -52 -53c-9 0 -17 2 -24 6l-28 -27c15 -11 33 -17 52 -17z" />
+ <glyph glyph-name="ion-eye" unicode="&#xf133;"
+d="M224 320c99 0 172 -70 224 -129c-51 -50 -124 -127 -224 -127s-157 60 -224 128c78 79 142 128 224 128zM224 101c49 0 90 41 90 91s-41 91 -90 91s-90 -41 -90 -91s41 -91 90 -91zM224 224c0 -18 14 -32 32 -32c8 0 14 3 20 7v-7c0 -29 -23 -53 -52 -53s-52 24 -52 53
+s23 53 52 53h8c-5 -6 -8 -13 -8 -21z" />
+ <glyph glyph-name="ion-female" unicode="&#xf278;" horiz-adv-x="256"
+d="M160 164v-68h64v-64h-64v-64h-64v64h-64v64h64v68c-55 14 -96 64 -96 124c0 71 57 128 128 128s128 -57 128 -128c0 -60 -41 -110 -96 -124zM128 208c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80z" />
+ <glyph glyph-name="ion-filing" unicode="&#xf134;" horiz-adv-x="384"
+d="M317 319c12 0 19 0 19 -20v-28h-288v28c0 20 8 20 20 20h249zM269 352c13 0 19 -1 19 -19h-192c0 18 7 19 20 19h153zM368 278c13 -8 17 -17 15 -41l-17 -184c-4 -21 -16 -21 -24 -21h-300c-8 0 -20 0 -24 21l-17 185c-3 26 1 31 15 40l15 10v-32h321v32z" />
+ <glyph glyph-name="ion-film-marker" unicode="&#xf135;" horiz-adv-x="416"
+d="M400 240c9 0 16 -7 16 -15v-210c0 -8 -7 -15 -16 -15h-384c-9 0 -16 7 -16 15v210c0 8 6 14 13 15c-2 2 -3 4 -4 7l-9 45c-2 8 5 16 13 18l370 74c8 2 16 -4 18 -12l9 -46c2 -8 -4 -16 -12 -18l-342 -68h344zM257 46l-20 58l51 36h-62l-20 58l-19 -58h-63l51 -36l-19 -58
+l50 36z" />
+ <glyph glyph-name="ion-fireball" unicode="&#xf319;" horiz-adv-x="320"
+d="M297 210c14 -24 23 -52 23 -82c0 -33 -10 -63 -26 -88v0v0c-29 -43 -78 -72 -134 -72c-17 0 -32 1 -46 7s-25 13 -33 25c-11 16 -17 28 -21 52c-6 -25 2 -48 9 -60c-43 26 -69 71 -69 125v4c5 78 65 109 90 151c8 14 13 30 10 48c11 -9 15 -25 15 -39
+c0 -16 -3 -29 -3 -29c4 8 7 18 9 31c6 35 2 85 -37 132l-1 1s7 0 18 -3c95 -16 169 -91 184 -186c2 -12 3 -23 3 -35c0 -16 -2 -32 -5 -47c10 23 13 43 14 55v10z" />
+ <glyph glyph-name="ion-flag" unicode="&#xf279;" horiz-adv-x="384"
+d="M362 266c0 0 12 2 22 6c0 -16 -7 -32 -9 -36c-28 -50 -99 -123 -181 -84c-65 31 -92 30 -117 24c-1 0 -2 -1 -3 -1c-3 -1 -15 -5 -26 -1v197c0 16 14 31 33 35c39 7 106 5 148 -74c39 -74 97 -72 133 -66zM24 416c4 0 8 -4 8 -8v-432c0 -4 -4 -8 -8 -8h-16
+c-4 0 -8 4 -8 8v432c0 4 4 8 8 8h16z" />
+ <glyph glyph-name="ion-flame" unicode="&#xf31a;" horiz-adv-x="256"
+d="M1 128c-11 109 72 224 159 288c-26 -145 97 -142 96 -288c-1 -120 -105 -160 -128 -160s-114 26 -127 160zM88 80c0 -44 40 -80 40 -80s41 36 41 80s-41 80 -41 80s-40 -36 -40 -80z" />
+ <glyph glyph-name="ion-flash-off" unicode="&#xf136;"
+d="M115 -4c-69 38 -115 112 -115 196c0 124 100 224 224 224c24 0 47 -4 68 -11c2 -1 3 -1 5 -2c12 -4 24 -9 35 -15v0c69 -38 116 -112 116 -196c0 -124 -100 -224 -224 -224c-24 0 -47 4 -68 11c-2 1 -3 1 -5 2c-12 4 -24 8 -35 14zM86 291c-20 -28 -32 -62 -32 -99
+c0 -65 36 -121 90 -150c6 -3 13 -7 19 -9c2 -1 3 -1 5 -2c9 -3 19 -5 29 -7c9 -2 18 -2 27 -2c37 0 71 12 99 32l-52 53l36 40l55 -54c20 28 32 62 32 99c0 66 -37 123 -91 151c-6 3 -12 6 -18 8c-2 1 -3 1 -5 2c-9 3 -19 5 -29 7c-9 2 -18 2 -27 2c-37 0 -72 -12 -100 -32
+l53 -52l-36 -41zM178 58l38 113h-85l139 155l-38 -113h85z" />
+ <glyph glyph-name="ion-flash" unicode="&#xf137;" horiz-adv-x="320"
+d="M0 160l224 256l-51 -192h147l-224 -256l51 192h-147z" />
+ <glyph glyph-name="ion-folder" unicode="&#xf139;" horiz-adv-x="384"
+d="M366 256c18 0 19 -7 18 -18l-12 -186c-1 -11 -3 -20 -21 -20h-317c-18 0 -20 9 -21 20l-13 184c-1 11 0 20 18 20h348zM362 305l2 -33h-344c0 6 4 46 6 63c2 18 8 17 25 17h75c28 0 23 0 37 -15c16 -18 19 -17 41 -17h143c11 0 15 -3 15 -15z" />
+ <glyph glyph-name="ion-fork-repo" unicode="&#xf2c0;" horiz-adv-x="320"
+d="M320 368v-64h-48v-48h-64v48h-48v64h48v48h64v-48h48zM208 208h64v-5v0c0 -43 -7 -70 -38 -95c-23 -19 -51 -20 -75 -22c-9 -1 -18 -2 -26 -3c-6 -1 -13 -5 -20 -10c9 -11 15 -25 15 -41c0 -35 -29 -64 -64 -64s-64 29 -64 64c0 24 13 44 32 55v210c-19 11 -32 31 -32 55
+c0 35 29 64 64 64s64 -29 64 -64c0 -24 -13 -44 -32 -55v-160c8 4 18 7 27 9c11 2 21 2 31 3c17 1 33 3 40 9c10 8 14 11 14 50zM64 384c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM64 0c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32
+s14 -32 32 -32z" />
+ <glyph glyph-name="ion-fork" unicode="&#xf27a;" horiz-adv-x="128"
+d="M78 299v0v0v0zM128 282c0 -26 -15 -48 -37 -58c-12 -6 -11 -11 -11 -11s16 -200 16 -213s-3 -18 -9 -24s-15 -8 -23 -8v0v0c-8 0 -16 2 -22 8s-10 13 -10 24s16 213 16 213s0 6 -11 11c-22 10 -37 32 -37 58c0 43 15 93 24 134h8v-117c0 -6 3 -11 9 -11s9 4 10 10v1
+l9 117h8l10 -117v-1c1 -6 3 -10 9 -10s9 5 9 11v117h8v0c9 -40 24 -91 24 -134z" />
+ <glyph glyph-name="ion-forward" unicode="&#xf13a;" horiz-adv-x="384"
+d="M224 150c-102 0 -171 -9 -224 -102c0 0 37 208 224 208v80l160 -144l-160 -134v92z" />
+ <glyph glyph-name="ion-funnel" unicode="&#xf31b;"
+d="M224 416c124 0 224 -36 224 -80c0 -8 -3 -15 -9 -22v0c-35 -43 -151 -179 -151 -218v-4v-83v0c0 -23 -29 -41 -64 -41s-64 18 -64 41v0v87c0 39 -117 177 -149 216v0c-7 8 -11 16 -11 24c0 44 100 80 224 80zM224 288c92 0 176 22 176 48s-83 48 -176 48
+s-176 -22 -176 -48s84 -48 176 -48z" />
+ <glyph glyph-name="ion-gear-a" unicode="&#xf13d;" horiz-adv-x="384"
+d="M347 192c0 -24 15 -43 37 -56c-4 -13 -10 -26 -16 -38c-25 6 -45 -3 -62 -20s-22 -37 -16 -62c-12 -6 -25 -12 -38 -16c-13 22 -36 37 -60 37s-47 -15 -60 -37c-13 4 -27 10 -39 16c6 25 2 45 -15 62s-37 21 -62 15c-6 12 -12 26 -16 39c22 13 37 36 37 60s-15 43 -37 56
+c4 13 9 26 16 38c25 -6 45 3 62 20s21 37 15 62c12 6 26 12 39 16c13 -22 36 -37 60 -37s47 15 60 37c13 -4 27 -10 39 -16c-6 -25 -2 -45 15 -62s37 -26 62 -20c6 -12 12 -25 16 -38c-22 -13 -37 -32 -37 -56zM192 94c54 0 98 44 98 98s-44 98 -98 98s-98 -44 -98 -98
+s44 -98 98 -98z" />
+ <glyph glyph-name="ion-gear-b" unicode="&#xf13e;" horiz-adv-x="384"
+d="M384 154h-44c-4 -14 -10 -27 -17 -39l32 -32l-54 -54l-33 32c-12 -7 -24 -11 -38 -15v-46h-76v46c-13 4 -26 8 -38 15l-33 -32l-54 54l32 32c-7 12 -13 25 -17 39h-44v76h43c4 14 9 29 16 41l-30 30l54 54l29 -29c13 8 27 13 42 17v41h76v-41c15 -4 29 -9 42 -17l29 29
+l54 -54l-30 -30c7 -12 13 -27 16 -41h43v-76zM192 138c30 0 54 24 54 54s-24 54 -54 54s-54 -24 -54 -54s24 -54 54 -54z" />
+ <glyph glyph-name="ion-grid" unicode="&#xf13f;" horiz-adv-x="320"
+d="M64 295c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM192 295c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM320 295c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM64 167
+c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM192 167c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM320 167c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM64 39
+c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM192 39c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50zM320 39c0 -4 -3 -7 -7 -7h-50c-4 0 -7 3 -7 7v50c0 4 3 7 7 7h50c4 0 7 -3 7 -7v-50z" />
+ <glyph glyph-name="ion-hammer" unicode="&#xf27b;" horiz-adv-x="320"
+d="M314 416c3 0 6 -3 6 -6v-84c0 -3 -3 -6 -6 -6h-52c-3 0 -6 3 -6 6v14c-6 5 -16 9 -22 7c-7 -2 -23 -13 -30 -25s-6 -28 -6 -66l8 -2c5 -1 7 -6 7 -9v-70c0 -95 11 -201 11 -201c0 -3 -3 -6 -6 -6h-84c-3 0 -6 3 -6 6c0 0 11 106 11 201v70c0 3 3 8 7 9l7 2
+c0 43 -5 58 -22 74c-18 16 -41 19 -63 17s-51 -35 -58 -45s-10 2 -10 11c1 16 22 60 72 81s91 22 102 22s27 -1 38 -3s16 -18 26 -18c7 0 14 5 18 9v6c0 3 3 6 6 6h52z" />
+ <glyph glyph-name="ion-happy-outline" unicode="&#xf3c6;"
+d="M355 158c8 -4 11 -13 7 -21c-24 -46 -78 -73 -138 -73c-62 0 -118 29 -139 74c-4 8 0 17 8 21c2 1 5 1 7 1c6 0 11 -3 14 -9c16 -34 60 -55 110 -55c49 0 92 21 110 56c3 5 8 8 14 8c3 0 5 -1 7 -2zM381 217c5 -7 4 -17 -4 -22c-3 -2 -6 -3 -10 -3c-5 0 -11 2 -14 6
+s-7 10 -17 10s-14 -6 -17 -10s-9 -6 -14 -6c-4 0 -7 1 -10 3c-8 6 -9 15 -3 22c11 14 23 23 44 23s35 -9 45 -23zM157 217c5 -7 4 -17 -4 -22c-3 -2 -6 -3 -10 -3c-5 0 -11 2 -14 6s-7 10 -17 10s-14 -6 -17 -10s-9 -6 -14 -6c-4 0 -7 1 -10 3c-8 6 -9 15 -3 22
+c11 14 23 23 44 23s35 -9 45 -23zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56
+s100 20 136 56z" />
+ <glyph glyph-name="ion-happy" unicode="&#xf31c;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM71 195c3 -2 6 -3 10 -3c5 0 11 2 14 6s7 10 17 10s14 -6 17 -10s9 -6 14 -6c4 0 7 1 10 3c8 5 9 15 4 22c-10 14 -24 23 -45 23s-33 -9 -44 -23c-6 -7 -5 -16 3 -22zM362 137
+c4 8 1 17 -7 21c-2 1 -4 2 -7 2c-6 0 -11 -3 -14 -8c-18 -35 -61 -56 -110 -56c-50 0 -94 21 -110 55c-3 6 -8 9 -14 9c-2 0 -5 0 -7 -1c-8 -4 -12 -13 -8 -21c21 -45 77 -74 139 -74c60 0 114 27 138 73zM377 195c8 5 9 15 4 22c-10 14 -24 23 -45 23s-33 -9 -44 -23
+c-6 -7 -5 -16 3 -22c3 -2 6 -3 10 -3c5 0 11 2 14 6s7 10 17 10s14 -6 17 -10s9 -6 14 -6c4 0 7 1 10 3z" />
+ <glyph glyph-name="ion-headphone" unicode="&#xf140;" horiz-adv-x="384"
+d="M383 210c3 -51 -3 -130 -13 -162c-20 -67 -40 -80 -72 -80s-58 27 -58 59v106c0 33 23 59 53 59c18 0 34 -9 44 -24c0 0 11 7 13 22s4 34 -5 64s-21 19 -36 38c-2 3 -5 7 -8 10l-10 10c-2 2 -3 3 -5 4c-11 9 -21 17 -34 23c-19 9 -39 13 -60 13s-42 -4 -61 -13
+c-13 -6 -22 -14 -33 -23c-2 -1 -3 -2 -5 -4l-10 -10s-6 -7 -8 -10c-15 -19 -27 -8 -36 -38c-9 -31 -7 -49 -5 -64s13 -22 13 -22c10 15 26 24 44 24c30 0 53 -27 53 -59v-106c0 -32 -26 -59 -58 -59s-52 13 -72 80c-10 32 -16 111 -13 162c3 60 22 108 56 145v0
+c8 8 15 16 24 23s19 13 29 18c25 13 53 20 82 20s57 -7 82 -20c10 -5 19 -11 28 -18s17 -15 25 -23v0c34 -37 53 -85 56 -145z" />
+ <glyph glyph-name="ion-heart-broken" unicode="&#xf31d;" horiz-adv-x="416"
+d="M181 160c0 -36 -2 -71 4 -107c2 -10 2 -20 2 -31l-153 159c-45 47 -45 124 0 171c40 41 103 43 144 3c-2 -15 -3 -31 -3 -46c-18 -14 -40 -21 -56 -39l11 7c17 11 15 8 35 14c3 1 8 3 11 5c0 -1 -1 -5 -1 -6c1 -20 11 -39 15 -60c0 -5 1 -10 -1 -15c-8 -17 -7 -37 -8 -55
+zM274 147c8 -18 23 -29 38 -39l-104 -108l-17 18c0 13 -4 26 -4 38c-2 48 10 94 21 142v0c1 -1 2 -1 3 -1c30 -6 52 -24 63 -50zM382 352c46 -47 46 -124 0 -171l-68 -70c-28 24 -42 54 -65 81c-12 13 -26 23 -41 32c-3 13 -8 26 -11 39c-3 12 14 21 16 31c3 12 3 26 3 39
+l19 19c40 42 107 42 147 0z" />
+ <glyph glyph-name="ion-heart" unicode="&#xf141;" horiz-adv-x="416"
+d="M382 352c46 -47 46 -124 0 -171l-174 -181l-174 181c-46 47 -46 124 0 171c40 42 107 42 147 0l27 -28l28 28c40 42 106 42 146 0z" />
+ <glyph glyph-name="ion-help-buoy" unicode="&#xf27c;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM402 264c-10 24 -23 45 -42 64s-41 32 -65 42l-19 -61c14 -6 27 -15 38 -26s21 -24 27 -38zM224 96c53 0 96 43 96 96s-43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96zM88 328
+c-19 -19 -32 -41 -42 -65l61 -19c6 14 15 27 26 38s24 21 38 27l-19 61c-24 -10 -45 -23 -64 -42zM46 120c10 -24 23 -45 42 -64s41 -32 65 -42l19 61c-14 6 -27 15 -38 26s-21 24 -27 38zM360 56c19 19 32 41 42 65l-61 19c-6 -14 -15 -27 -26 -38s-24 -21 -38 -27l19 -61
+c24 10 45 23 64 42z" />
+ <glyph glyph-name="ion-help-circled" unicode="&#xf142;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM244 89c1 18 -12 31 -29 31c-16 0 -30 -11 -30 -29s12 -30 28 -30c17 0 31 10 31 28zM293 217c7 10 12 22 12 36c0 23 -9 40 -25 52c-17 13 -37 18 -62 18
+c-19 0 -34 -4 -47 -13c-19 -13 -28 -34 -28 -68h49c0 9 -1 19 4 27s13 15 26 15s19 -3 25 -11c5 -7 8 -15 8 -23c0 -7 -4 -14 -8 -20c-2 -4 -6 -7 -10 -10c0 0 -26 -15 -35 -30c-7 -11 -9 -24 -10 -41c0 -1 0 -4 4 -4h39s5 3 5 4c0 6 1 15 2 19c2 7 6 12 12 17l14 9
+c12 9 21 17 25 23z" />
+ <glyph glyph-name="ion-help" unicode="&#xf143;" horiz-adv-x="256"
+d="M217 371c25 -19 39 -46 39 -83c0 -22 -8 -42 -19 -57c-7 -9 -21 -21 -40 -36l-21 -14c-10 -8 -17 -18 -20 -28c-2 -6 -3 -19 -3 -29c0 -2 -1 -6 -7 -6h-62c-7 0 -7 3 -7 5c1 26 4 49 15 66c15 23 57 48 57 48c6 5 11 9 15 15c7 10 12 21 12 32c0 13 -3 26 -11 36
+c-10 12 -21 18 -41 18s-32 -11 -40 -24s-7 -29 -7 -43h-77c0 54 14 88 44 108c20 14 45 20 75 20c39 0 70 -7 98 -28zM114 78c27 -1 47 -20 46 -48s-22 -46 -49 -45c-26 1 -46 19 -45 47s22 47 48 46z" />
+ <glyph glyph-name="ion-home" unicode="&#xf144;" horiz-adv-x="384"
+d="M384 160h-48v-160h-96v128h-96v-128h-96v160h-48l192 224z" />
+ <glyph glyph-name="ion-icecream" unicode="&#xf27d;" horiz-adv-x="320"
+d="M32 192h256l-128 -224zM307 275c8 -5 13 -13 13 -23c0 -16 -14 -28 -30 -28h-4h-252h-4c-16 0 -30 13 -30 28c0 10 6 18 14 23c1 0 1 2 2 2c4 3 7 7 8 12v1c-2 6 -2 12 -2 18c0 42 34 76 76 76c8 0 16 -2 23 -4c-3 -12 -4 -31 -4 -31c2 15 11 29 11 29c18 23 46 38 77 38
+c53 0 96 -43 96 -96c0 -11 -2 -21 -5 -30v-1c0 -4 4 -9 8 -12c1 0 2 -2 3 -2z" />
+ <glyph glyph-name="ion-image" unicode="&#xf147;"
+d="M336 224c-26 0 -48 22 -48 48s22 48 48 48s48 -22 48 -48s-22 -48 -48 -48zM420 384c16 0 28 -12 28 -28v-328c0 -16 -12 -28 -28 -28h-392c-16 0 -28 12 -28 28v328c0 16 12 28 28 28h392zM317 186l99 -106v260c0 7 -6 12 -13 12h-358c-7 0 -12 -5 -13 -12v-260l126 152
+c4 4 10 8 17 8s13 -2 17 -7l54 -59l4 -4c3 -2 7 -4 11 -4s8 2 12 5l18 16c4 3 8 5 13 5s10 -2 13 -6z" />
+ <glyph glyph-name="ion-images" unicode="&#xf148;"
+d="M426 308c13 -1 23 -12 22 -24l-14 -263c-1 -13 -12 -22 -25 -21l-330 16c-13 1 -23 10 -22 23l2 46l-15 -1c-12 -1 -22 7 -23 18l-21 236c-1 11 7 21 19 22l296 24c12 1 22 -7 23 -18l5 -54zM71 302c1 12 11 22 24 22l219 -11l-2 31h-1v1c-1 5 -5 8 -10 8l-261 -22
+c-5 0 -10 -4 -10 -9v0v-1l16 -178l18 25zM405 66l10 198v1v0c0 6 -5 10 -11 10l-58 3l-29 2l-204 9c-6 0 -11 -4 -12 -9v0v-1l-3 -63l-7 -128v-7l6 7l102 109c4 4 8 6 14 6s11 -3 14 -7l43 -49l3 -3c2 -2 6 -4 10 -4s5 1 9 3l17 12c4 3 7 4 11 4s9 -2 11 -5l27 -33zM341 186
+c-20 0 -35 15 -35 35s16 35 35 35c20 0 35 -16 35 -35s-16 -35 -35 -35z" />
+ <glyph glyph-name="ion-information-circled" unicode="&#xf149;"
+d="M448 195c2 -124 -97 -225 -221 -227s-225 97 -227 221s97 225 221 227s225 -97 227 -221zM224 336c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM268 53v11h-22v172h-66v-12h22v-160h-22v-11h88z" />
+ <glyph glyph-name="ion-information" unicode="&#xf14a;" horiz-adv-x="128"
+d="M96 0h32v-16h-128v16h32v240h-32v16h96v-256zM64 304c-27 0 -48 21 -48 48s21 48 48 48s48 -21 48 -48s-21 -48 -48 -48z" />
+ <glyph glyph-name="ion-ionic" unicode="&#xf14b;" horiz-adv-x="416"
+d="M376 315c25 -34 40 -77 40 -123c0 -115 -93 -208 -208 -208s-208 93 -208 208s93 208 208 208c46 0 89 -15 123 -40c5 3 11 5 18 5c18 0 32 -14 32 -32c0 -7 -2 -13 -5 -18zM344 56c18 18 31 38 41 61c10 24 15 49 15 75s-5 51 -15 75c-6 13 -13 26 -21 38
+c-4 -2 -10 -4 -15 -4c-18 0 -32 14 -32 32c0 5 2 11 4 15c-12 8 -25 15 -38 21c-24 10 -49 15 -75 15s-51 -5 -75 -15c-23 -10 -43 -23 -61 -41s-31 -38 -41 -61c-10 -24 -15 -49 -15 -75s5 -51 15 -75c10 -23 23 -43 41 -61s38 -31 61 -41c24 -10 49 -15 75 -15s51 5 75 15
+c23 10 43 23 61 41zM112 192c0 64 32 96 96 96s96 -32 96 -96s-32 -96 -96 -96s-96 32 -96 96z" />
+ <glyph glyph-name="ion-ios-alarm-outline" unicode="&#xf3c7;" horiz-adv-x="404"
+d="M384 256l-54 52l-9 -9c35 -32 57 -79 57 -130c0 -44 -16 -83 -43 -114l36 -45l-12 -10l-35 43c-32 -30 -75 -49 -122 -49v0v0c-47 0 -90 19 -122 49l-35 -43l-12 10l36 45c-27 31 -43 71 -43 115c0 51 22 97 57 129l-9 9l-54 -52c-12 14 -20 32 -20 52c0 44 35 80 80 82
+h5c20 0 39 -7 54 -18l-54 -52l11 -11c26 19 56 32 90 35v0c0 8 8 16 16 16s15 -8 15 -16v0c34 -3 65 -16 91 -35l11 11l-54 52c15 11 34 18 54 18h5c45 -2 80 -38 80 -82c0 -20 -8 -38 -20 -52zM22 280l91 89c-9 5 -19 7 -32 6c-37 -2 -65 -32 -65 -67c0 -10 2 -19 6 -28z
+M362 172c0 88 -72 158 -160 158s-160 -70 -160 -158s72 -158 160 -158s160 70 160 158zM291 369l91 -89c4 9 6 18 6 28c0 35 -28 65 -65 67c-13 1 -23 -1 -32 -6zM202 288h16v-144h-112v16h96v128z" />
+ <glyph glyph-name="ion-ios-alarm" unicode="&#xf3c8;" horiz-adv-x="404"
+d="M385 256l-55 52l-9 -9c35 -32 57 -79 57 -130c0 -44 -16 -83 -43 -114l37 -45l-13 -10l-35 43c-32 -30 -75 -49 -122 -49v0v0c-47 0 -90 19 -122 49l-35 -43l-12 10l36 45c-27 31 -43 70 -43 114c0 51 22 98 57 130l-9 9l-54 -52c-12 14 -20 32 -20 52c0 44 35 80 80 82
+h5c20 0 39 -7 54 -18l-54 -53l11 -10c26 19 56 32 90 35v0c0 8 8 16 16 16s15 -8 15 -16v0c34 -3 65 -16 91 -35l11 11l-54 52c15 11 34 18 54 18h5c45 -2 80 -38 80 -82c0 -20 -7 -38 -19 -52zM218 144v144h-16v-128h-96v-16h112z" />
+ <glyph glyph-name="ion-ios-albums-outline" unicode="&#xf3c9;"
+d="M432 304h-416v-288h416v288zM448 320v0v-320h-448v320h448zM40 336v16h368v-16h-368zM72 368v16h304v-16h-304z" />
+ <glyph glyph-name="ion-ios-albums" unicode="&#xf3ca;"
+d="M448 320v0v-320h-448v320h448zM40 336v16h368v-16h-368zM72 368v16h304v-16h-304z" />
+ <glyph glyph-name="ion-ios-americanfootball-outline" unicode="&#xf3cb;" horiz-adv-x="416"
+d="M331 315c112 -112 81 -327 81 -327s-26 -4 -65 -4c-73 0 -189 12 -262 85c-112 112 -81 327 -81 327s26 4 65 4c73 0 189 -12 262 -85zM17 383c-2 -19 -5 -60 0 -107c1 -8 2 -16 3 -23l127 127c-25 3 -51 5 -78 5v0v0c-22 0 -41 -1 -52 -2zM96 80c30 -30 72 -53 124 -66
+c10 -3 20 -5 31 -7l142 142c-4 22 -10 44 -17 63c-14 37 -32 68 -56 92c-30 30 -72 53 -124 66c-10 3 -20 5 -31 7l-142 -142c4 -22 10 -44 17 -63c14 -37 32 -68 56 -92zM399 1c2 19 5 60 0 107c-1 8 -2 16 -3 23l-127 -127c25 -3 51 -5 78 -5c22 0 41 1 52 2zM259 130
+l-28 -29l-12 12l29 28l-23 23l-28 -29l-12 12l29 28l-23 23l-28 -29l-12 12l29 28l-23 23l-28 -29l-12 12l29 28l-22 23l-29 -29l-11 12l67 67l12 -11l-29 -29l23 -22l28 29l12 -12l-29 -28l23 -23l28 29l12 -12l-29 -28l23 -23l28 29l12 -12l-29 -28l22 -23l29 29l12 -12
+l-29 -28l22 -23l29 29l11 -12l-67 -67l-12 11l29 29z" />
+ <glyph glyph-name="ion-ios-americanfootball" unicode="&#xf3cc;" horiz-adv-x="416"
+d="M331 315c112 -112 81 -327 81 -327s-26 -4 -65 -4c-73 0 -189 12 -262 85c-112 112 -81 327 -81 327s26 4 65 4c73 0 189 -12 262 -85zM20 253l3 -18l142 142l-18 3zM219 113l12 -12l28 29l23 -22l-29 -29l12 -11l67 67l-11 12l-29 -29l-22 23l29 28l-12 12l-28 -29
+l-23 23l29 28l-12 12l-28 -29l-23 23l29 28l-12 12l-28 -29l-23 23l29 28l-12 12l-28 -29l-23 22l29 29l-12 11l-67 -67l11 -12l29 29l22 -23l-29 -28l12 -12l28 29l23 -23l-29 -28l12 -12l28 29l23 -23l-29 -28l12 -12l28 29l23 -23zM269 4l127 127l-3 18l-142 -142z" />
+ <glyph glyph-name="ion-ios-analytics-outline" unicode="&#xf3cd;"
+d="M224 400c-28 0 -55 -5 -81 -16c-25 -10 -47 -26 -66 -45s-35 -41 -45 -66c-11 -26 -16 -53 -16 -81s5 -55 16 -81c10 -25 26 -47 45 -66s41 -35 66 -45c26 -11 53 -16 81 -16s55 5 81 16c25 10 47 26 66 45s35 41 45 66c11 26 16 53 16 81s-5 55 -16 81
+c-10 25 -26 47 -45 66s-41 35 -66 45c-26 11 -53 16 -81 16zM224 416v0c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM76 128c-25 0 -41 18 -42 19c-3 3 -2 9 1 12s8 2 11 -1c1 -1 15 -17 36 -14c12 2 27 26 38 42c4 6 9 12 12 16
+c17 21 34 23 45 21c24 -3 45 -28 54 -50c7 -18 18 -28 32 -29c15 -1 31 11 43 30c1 2 3 4 4 7c9 17 24 43 52 43c31 0 52 -35 53 -36c2 -4 1 -9 -3 -11s-9 -1 -11 3c0 0 -5 8 -12 15c-6 6 -16 13 -27 13c-18 0 -29 -19 -38 -35c-1 -3 -3 -5 -4 -7c-15 -25 -36 -40 -58 -38
+c-20 1 -36 15 -46 39s-28 39 -41 41c-11 1 -21 -4 -31 -16c-3 -4 -6 -9 -10 -15c-14 -20 -31 -45 -50 -48c-3 0 -5 -1 -8 -1z" />
+ <glyph glyph-name="ion-ios-analytics" unicode="&#xf3ce;"
+d="M224 416c124 0 224 -100 224 -224c0 -13 -1 -25 -3 -37c-1 -6 -2 -12 -3 -17c-24 -98 -113 -170 -218 -170c-122 0 -221 98 -224 219v5c0 9 1 17 2 26c13 111 107 198 222 198zM431 168c1 8 1 16 1 24c0 28 -5 55 -16 81c-10 25 -26 47 -45 66s-41 35 -66 45
+c-26 11 -53 16 -81 16s-55 -5 -81 -16c-25 -10 -47 -26 -66 -45s-35 -41 -45 -66c-11 -26 -16 -53 -16 -81v0c14 -21 29 -34 29 -34h1v-1c1 -1 15 -16 36 -13c12 2 27 26 38 42c4 6 9 12 12 16c17 21 34 23 45 21c24 -3 45 -27 54 -50c7 -18 18 -28 32 -29c15 -1 31 9 43 29
+c1 2 3 4 4 7c9 17 24 44 52 44c31 0 52 -35 53 -36c3 -4 9 -12 16 -20z" />
+ <glyph glyph-name="ion-ios-arrow-back" unicode="&#xf3cf;" horiz-adv-x="192"
+d="M192 320l-127 -128l127 -128l-32 -32l-160 160v0v0l160 160z" />
+ <glyph glyph-name="ion-ios-arrow-down" unicode="&#xf3d0;" horiz-adv-x="320"
+d="M301 288l19 -21l-160 -171l-160 171l19 21l141 -150z" />
+ <glyph glyph-name="ion-ios-arrow-forward" unicode="&#xf3d1;" horiz-adv-x="192"
+d="M0 320l32 32l160 -160v0v0l-160 -160l-32 32l127 128z" />
+ <glyph glyph-name="ion-ios-arrow-left" unicode="&#xf3d2;" horiz-adv-x="192"
+d="M192 333l-150 -141l150 -141l-21 -19l-171 160l171 160z" />
+ <glyph glyph-name="ion-ios-arrow-right" unicode="&#xf3d3;" horiz-adv-x="192"
+d="M0 333l21 19l171 -160l-171 -160l-21 19l150 141z" />
+ <glyph glyph-name="ion-ios-arrow-thin-down" unicode="&#xf3d4;" horiz-adv-x="192"
+d="M190 126c2 -2 2 -4 2 -6s0 -4 -2 -6c0 0 -87 -79 -88 -80s-3 -2 -6 -2s-5 1 -6 2s-88 80 -88 80c-3 3 -3 9 0 12s9 3 12 0l74 -67v285c0 4 4 8 8 8s8 -4 8 -8v-285l74 67c3 3 9 3 12 0z" />
+ <glyph glyph-name="ion-ios-arrow-thin-left" unicode="&#xf3d5;" horiz-adv-x="320"
+d="M94 98c-2 -2 -4 -2 -6 -2s-4 0 -6 2c0 0 -79 87 -80 88s-2 3 -2 6s1 5 2 6s80 88 80 88c3 3 9 3 12 0s3 -9 0 -12l-67 -74h285c4 0 8 -4 8 -8s-4 -8 -8 -8h-285l67 -74c3 -3 3 -9 0 -12z" />
+ <glyph glyph-name="ion-ios-arrow-thin-right" unicode="&#xf3d6;" horiz-adv-x="320"
+d="M226 98c-3 3 -3 9 0 12l67 74h-285c-4 0 -8 4 -8 8s4 8 8 8h285l-67 74c-3 3 -3 9 0 12s9 3 12 0c0 0 79 -87 80 -88s2 -3 2 -6s-1 -5 -2 -6s-80 -88 -80 -88c-2 -2 -4 -2 -6 -2s-4 0 -6 2z" />
+ <glyph glyph-name="ion-ios-arrow-thin-up" unicode="&#xf3d7;" horiz-adv-x="192"
+d="M190 258c-3 -3 -9 -3 -12 0l-74 67v-285c0 -4 -4 -8 -8 -8s-8 4 -8 8v285l-74 -67c-3 -3 -9 -3 -12 0s-3 9 0 12c0 0 87 79 88 80s3 2 6 2s5 -1 6 -2s88 -80 88 -80c2 -2 2 -4 2 -6s0 -4 -2 -6z" />
+ <glyph glyph-name="ion-ios-arrow-up" unicode="&#xf3d8;" horiz-adv-x="320"
+d="M301 96l-141 150l-141 -150l-19 21l160 171l160 -171z" />
+ <glyph glyph-name="ion-ios-at-outline" unicode="&#xf3d9;" horiz-adv-x="255"
+d="M236 127v1h19l-3 -6c-3 -6 -13 -19 -22 -27s-18 -14 -28 -20s-21 -10 -32 -13s-23 -5 -34 -5c-16 0 -33 3 -49 8s-30 13 -43 24c-12 11 -26 29 -34 46c-7 16 -10 33 -10 58c0 18 4 38 11 55c7 16 17 30 29 42s27 21 43 28c15 6 33 9 53 9c16 0 32 -3 46 -8
+c15 -5 28 -12 39 -22s17 -21 24 -35c6 -13 8 -26 8 -44c0 -14 -2 -28 -7 -40s-9 -20 -17 -30c-8 -9 -13 -15 -23 -21c-11 -6 -20 -9 -29 -9c-8 0 -15 2 -20 7c-3 2 -5 6 -6 9c-6 -6 -11 -10 -17 -12c-10 -3 -18 -4 -26 -4s-15 1 -21 4s-12 7 -17 12s-8 11 -11 18
+s-5 14 -5 22c0 12 3 24 7 36v2c4 11 5 16 13 26c8 11 17 19 28 26s24 11 38 11c12 0 21 -3 31 -9c7 -4 12 -10 16 -16l6 17h18l-38 -102c-2 -5 -4 -10 -5 -14s-1 -7 -1 -10c0 -2 1 -4 3 -5s4 -2 8 -2c6 0 11 2 20 7c8 4 12 9 19 17c6 8 10 14 14 25s6 23 6 35
+c0 15 -2 25 -7 36c-6 13 -10 22 -19 30s-20 15 -33 20s-27 7 -42 7c-19 0 -35 -3 -48 -9c-15 -6 -27 -14 -37 -24c-11 -10 -19 -23 -25 -37c-6 -15 -10 -32 -10 -48c0 -22 2 -36 8 -49c6 -15 17 -31 28 -41s24 -18 38 -23s30 -7 46 -7c10 0 20 1 30 4s18 6 27 11
+s17 11 24 18s14 13 19 21zM147 154c4 5 8 12 11 20l21 57c-2 5 -4 10 -7 13c-3 4 -6 6 -10 8c-1 0 -1 1 -2 1c-3 2 -5 3 -9 4c-5 1 -9 2 -13 2c-10 0 -19 -3 -28 -9s-17 -13 -23 -22c-5 -8 -7 -11 -10 -20c0 -1 -1 -3 -1 -4c-4 -11 -5 -20 -5 -30c0 -6 1 -11 3 -16
+s5 -9 8 -13s7 -6 12 -8s9 -3 15 -3c4 0 9 1 14 2c4 1 8 2 12 5s8 7 12 13z" />
+ <glyph glyph-name="ion-ios-at" unicode="&#xf3da;" horiz-adv-x="256"
+d="M228 128v0h28c-1 -1 -2 -4 -3 -6c-4 -6 -14 -19 -23 -27s-18 -14 -28 -20s-20 -10 -32 -13c-11 -3 -23 -5 -34 -5c-16 0 -33 3 -49 8s-30 13 -43 24c-12 10 -26 28 -34 46c-7 16 -10 33 -10 58c0 19 4 39 11 55s17 30 29 42s28 21 44 28c15 6 32 9 52 9c16 0 31 -3 46 -8
+s28 -12 39 -22s18 -22 25 -36c6 -14 8 -26 8 -44c0 -14 -2 -28 -7 -40c-4 -11 -9 -20 -17 -30c-7 -9 -14 -16 -24 -22c-12 -6 -21 -9 -30 -9s-16 2 -22 8c-2 1 -3 3 -4 5c-4 -4 -9 -6 -14 -8c-10 -3 -18 -5 -27 -5c-8 0 -16 2 -23 5s-12 7 -17 12s-9 12 -12 19s-4 14 -4 22
+c0 12 2 25 6 37l1 1c4 10 5 17 13 27c8 11 17 20 28 27c12 7 24 10 38 10c12 0 22 -3 33 -9c5 -3 8 -6 12 -10l5 12h25l-39 -104c-2 -5 -3 -9 -4 -13c-1 -3 -1 -7 -1 -9s0 -3 1 -3c0 0 1 -1 5 -1c5 0 11 2 19 7c7 4 10 8 16 16s9 13 13 23s6 20 6 32c0 14 -1 24 -6 34
+c-5 12 -10 21 -18 28c-9 8 -19 14 -31 18s-26 7 -40 7c-18 0 -32 -3 -44 -8c-14 -6 -25 -13 -35 -23s-18 -22 -24 -35c-6 -14 -9 -30 -9 -45c0 -21 3 -34 8 -46c6 -14 16 -30 26 -39s22 -16 35 -21c14 -5 28 -7 43 -7c10 0 20 2 29 4s18 6 26 11s28 20 38 33zM144 157
+c4 5 7 12 10 19l20 55c-1 4 -3 7 -5 9c-3 3 -6 6 -9 8h-1h-1v1c-3 2 -5 2 -8 3c-4 1 -8 1 -12 1c-9 0 -17 -2 -25 -7c-10 -6 -17 -14 -21 -21c-5 -8 -6 -11 -9 -19c0 -1 -1 -2 -1 -3c-3 -10 -6 -19 -6 -28c0 -5 1 -10 3 -14s4 -8 7 -11s7 -6 11 -8s8 -2 13 -2c4 0 8 0 12 1
+v0c4 1 7 2 11 5c3 2 7 5 11 11z" />
+ <glyph glyph-name="ion-ios-barcode-outline" unicode="&#xf3db;" horiz-adv-x="416"
+d="M0 64v256h80v-16h-64v-224h64v-16h-80zM336 320h80v-256h-80v16h64v224h-64v16zM64 128v128h16v-128h-16zM336 128v128h16v-128h-16zM272 96v192h16v-192h-16zM128 96v192h16v-192h-16zM199 112v160h16v-160h-16z" />
+ <glyph glyph-name="ion-ios-barcode" unicode="&#xf3dc;" horiz-adv-x="416"
+d="M0 320h416v-256h-416v256zM80 128v128h-16v-128h16zM144 96v192h-16v-192h16zM215 112v160h-16v-160h16zM288 96v192h-16v-192h16zM352 128v128h-16v-128h16z" />
+ <glyph glyph-name="ion-ios-baseball-outline" unicode="&#xf3dd;" horiz-adv-x="416"
+d="M415 169v-1v0c-11 -97 -90 -174 -187 -183v0h-2c-2 0 -3 -1 -5 -1h-1h-3h-1h-8c-115 0 -208 93 -208 208v8v1v3v1c0 2 1 3 1 5v2v0c9 97 86 176 183 187v0v0c8 1 16 1 24 1c115 0 208 -93 208 -208c0 -7 0 -14 -1 -20v0v-3zM399 192c0 105 -86 191 -191 191
+c-3 0 -5 -1 -8 -1c0 -11 2 -21 4 -31l20 6l5 -15l-21 -7c2 -7 4 -14 7 -21c2 -5 5 -11 8 -16l17 12l9 -13l-19 -13c7 -12 16 -23 26 -33l14 15l12 -12l-15 -15c11 -10 22 -18 34 -25l12 18l14 -9l-12 -17c5 -2 10 -5 15 -7c7 -3 14 -5 22 -7l7 20l15 -5l-6 -19
+c10 -2 20 -4 30 -4c0 3 1 5 1 8zM17 192c0 -105 86 -191 191 -191h4c-1 9 -1 17 -3 26l-22 -7l-5 16l23 7c-2 8 -5 16 -8 24c-2 5 -4 9 -6 14l-20 -13l-9 13l21 14c-7 12 -16 24 -26 35l-17 -17l-11 11l17 17c-10 10 -22 18 -34 25l-14 -21l-14 9l14 20c-5 2 -10 5 -15 7
+c-7 3 -15 6 -23 8l-8 -24l-15 5l7 23c-9 2 -18 2 -27 3v-4zM228 2c88 9 158 78 169 166c-11 1 -23 3 -34 5l-9 -27l-15 5l8 25c-14 4 -28 10 -41 17l-15 -23l-13 9l14 21c-13 8 -26 17 -37 28l-19 -19l-11 11l19 19c-10 11 -19 23 -27 36l-21 -14l-9 13l22 15
+c-7 13 -12 27 -16 41l-25 -8l-5 16l26 8c-2 12 -4 23 -5 35c-88 -11 -157 -81 -166 -169c10 -1 21 -2 31 -4l8 23l15 -5l-7 -22c14 -4 28 -9 42 -16l13 19l14 -9l-13 -18c13 -8 25 -17 36 -28l17 17l11 -11l-17 -17c11 -12 20 -24 28 -37l19 13l9 -14l-20 -13
+c7 -14 12 -28 16 -42l23 7l5 -15l-24 -8c2 -10 3 -20 4 -30z" />
+ <glyph glyph-name="ion-ios-baseball" unicode="&#xf3de;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208c0 -8 0 -16 -1 -24v0v0c-12 -104 -100 -184 -207 -184c-115 0 -208 93 -208 208c0 107 80 195 184 207v0v0c8 1 16 1 24 1zM212 1c5 0 11 0 16 1c-1 10 -2 20 -4 30l24 8l-5 15l-23 -7c-4 14 -9 28 -16 42l20 13l-9 14l-19 -13
+c-8 13 -17 25 -28 37l17 17l-11 11l-17 -17c-11 11 -23 20 -36 28l13 18l-14 9l-13 -19c-14 7 -28 12 -42 16l7 22l-15 5l-8 -23c-10 2 -21 3 -31 4c-1 -5 -1 -11 -1 -16c9 -1 18 -1 27 -3l-7 -23l15 -5l8 24c8 -2 16 -5 23 -8c5 -2 10 -5 15 -7l-14 -20l14 -9l14 21
+c12 -7 24 -15 34 -25l-17 -17l11 -11l17 17c10 -11 19 -23 26 -35l-21 -14l9 -13l20 13c2 -5 4 -9 6 -14c3 -8 6 -16 8 -24l-23 -7l5 -16l22 7c2 -8 2 -17 3 -26zM363 173c11 -2 23 -4 34 -5c1 5 1 11 1 16c-10 1 -20 2 -30 4l6 19l-15 5l-7 -20c-8 2 -15 4 -22 7
+c-5 2 -10 5 -15 7l12 17l-14 9l-12 -18c-12 7 -23 15 -34 25l15 15l-12 12l-15 -15c-10 10 -18 21 -25 33l19 13l-9 13l-17 -12c-3 5 -6 11 -8 16c-3 7 -5 14 -7 21l21 7l-5 15l-20 -6c-2 10 -3 20 -4 31c-5 0 -11 0 -16 -1c1 -12 3 -23 5 -35l-26 -8l5 -16l25 8
+c4 -14 9 -28 16 -41l-22 -15l9 -13l21 14c8 -13 17 -25 27 -36l-19 -19l11 -11l19 19c11 -11 24 -20 37 -28l-14 -21l13 -9l15 23c13 -7 27 -13 41 -17l-8 -25l15 -5z" />
+ <glyph glyph-name="ion-ios-basketball-outline" unicode="&#xf3df;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM399 192c0 55 -24 105 -62 140c-14 -34 -31 -65 -52 -95c15 -12 31 -21 49 -29c21 -9 43 -14 65 -16v0zM325 343c-32 25 -73 40 -117 40v0c2 -22 6 -44 15 -65
+c10 -25 26 -47 45 -66c2 -1 2 -3 4 -4c20 29 38 60 52 93c0 1 1 1 1 2zM192 382c-51 -4 -96 -29 -128 -65c64 -28 121 -69 169 -119c11 12 21 24 30 37c-40 37 -67 89 -71 147zM233 174c-15 -16 -31 -30 -48 -44c28 -35 45 -79 47 -127c33 4 63 17 88 35
+c-22 50 -51 95 -87 136zM214 178l8 8l-10 10c-46 46 -99 82 -158 108c-18 -25 -31 -55 -35 -88c62 -3 116 -31 155 -74c14 11 27 23 40 36zM18 200c0 -3 -1 -5 -1 -8c0 -45 16 -87 43 -120c36 16 71 36 102 60l-7 7c-19 19 -41 35 -66 45c-22 9 -46 15 -71 16zM71 59
+c35 -36 83 -58 137 -58c3 0 5 1 8 1c-1 25 -6 48 -16 71c-7 17 -17 33 -28 47c-31 -24 -65 -45 -101 -61zM333 48c37 32 61 77 65 128c-46 3 -89 21 -123 48c-10 -13 -20 -26 -31 -38c36 -41 67 -87 89 -138z" />
+ <glyph glyph-name="ion-ios-basketball" unicode="&#xf3e0;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM333 48c-22 51 -53 97 -89 138c11 12 21 25 31 38c34 -27 77 -45 123 -48c0 5 1 11 1 16c-22 2 -44 7 -65 16c-18 8 -34 17 -49 29c21 30 38 61 52 95c-4 4 -8 8 -12 11
+c0 -1 -1 -1 -1 -2c-14 -33 -32 -64 -52 -93c-2 1 -2 2 -4 4c-19 19 -35 41 -45 66c-9 21 -13 43 -15 65c-5 0 -11 -1 -16 -1c4 -58 31 -110 71 -147c-9 -13 -19 -25 -30 -37c-48 50 -105 91 -169 119c-4 -4 -7 -9 -10 -13c59 -26 112 -62 158 -108l10 -10l-8 -8
+c-13 -13 -26 -25 -40 -36c-39 43 -93 71 -155 74c-1 -5 -1 -11 -1 -16c25 -1 49 -7 71 -16c25 -10 47 -26 66 -45l7 -7c-31 -24 -66 -44 -102 -60c4 -4 7 -9 11 -13c36 16 70 37 101 61c11 -14 21 -30 28 -47c10 -23 15 -46 16 -71c5 0 11 0 16 1c-2 48 -19 92 -47 127
+c17 14 33 28 48 44c36 -41 65 -86 87 -136c4 3 9 6 13 10z" />
+ <glyph glyph-name="ion-ios-bell-outline" unicode="&#xf3e1;" horiz-adv-x="384"
+d="M318 222c0 -114 28 -126 66 -158h-384c38 32 66 44 66 158c0 98 53 130 102 138v2c0 12 11 22 24 22s24 -10 24 -22v-2c49 -7 102 -40 102 -138zM43 80h298c-25 25 -40 58 -40 142c0 46 -13 80 -37 101c-23 19 -52 23 -72 23s-49 -4 -72 -23c-25 -21 -37 -55 -37 -101
+c0 -51 -5 -85 -17 -110c-6 -13 -14 -23 -23 -32zM192 0c-27 0 -49 20 -52 43h104c-3 -23 -25 -43 -52 -43z" />
+ <glyph glyph-name="ion-ios-bell" unicode="&#xf3e2;" horiz-adv-x="384"
+d="M318 222c0 -114 28 -126 66 -158h-384c38 32 66 44 66 158c0 98 53 130 102 138v2c0 12 11 22 24 22s24 -10 24 -22v-2c49 -7 102 -40 102 -138zM192 0c-27 0 -49 20 -52 43h104c-3 -23 -25 -43 -52 -43z" />
+ <glyph glyph-name="ion-ios-body-outline" unicode="&#xf3e3;" horiz-adv-x="384"
+d="M192 400c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM192 416v0c27 0 48 -21 48 -48s-21 -48 -48 -48s-48 21 -48 48s21 48 48 48zM360 304c13 0 24 -11 24 -24s-11 -24 -24 -24h-100c-5 0 -14 -5 -18 -15c-5 -12 -2 -33 1 -51l4 -21v-1v0l32 -172
+c2 -13 -6 -26 -19 -28h-5c-11 0 -22 8 -24 20l-21 120v0s-5 31 -17 31h-2c-12 0 -19 -31 -19 -31v0l-21 -120c-2 -12 -11 -20 -22 -20h-5c-13 2 -21 15 -19 28l32 172v1l4 21c3 18 6 39 1 51c-4 10 -12 15 -18 15h-100c-13 0 -24 11 -24 24s11 24 24 24h336zM24 272
+c-4 0 -8 4 -8 8s4 8 8 8h336c4 0 8 -4 8 -8s-4 -8 -8 -8h-102c-16 0 -26 -15 -30 -24c-5 -13 -6 -32 -1 -61v0v0l3 -19l1 -3l32 -172c0 -3 0 -5 -1 -6s-2 -2 -5 -3h-2c-4 0 -7 2 -8 6l-21 120v0c0 2 -2 10 -5 19c-2 6 -5 11 -8 15c-7 9 -14 11 -20 11h-2
+c-5 0 -13 -2 -20 -11c-3 -4 -6 -9 -8 -15c-4 -9 -6 -17 -6 -18v-1l-21 -120c-1 -4 -3 -6 -7 -6h-2c-3 0 -4 2 -5 3s-2 3 -1 6l32 172v0v1l4 21v0v0c5 29 5 48 0 61c-4 9 -14 24 -32 24z" />
+ <glyph glyph-name="ion-ios-body" unicode="&#xf3e4;" horiz-adv-x="384"
+d="M144 368c0 32 16 48 48 48s48 -16 48 -48s-16 -48 -48 -48s-48 16 -48 48zM360 304c7 0 12 -2 17 -7s7 -10 7 -17s-2 -12 -7 -17s-10 -7 -17 -7h-98c-8 -2 -15 -6 -18 -14c-4 -9 -3 -27 1 -52l4 -21v-1v0l30 -172c1 -7 0 -13 -4 -18s-8 -9 -15 -10s-13 0 -18 4
+s-9 9 -10 16l-21 120v-1l-2 9c-1 5 -3 11 -6 16s-6 8 -10 8h-2c-8 0 -14 -11 -18 -33v1l-21 -120c-1 -7 -5 -12 -10 -16s-11 -5 -18 -4s-11 5 -15 10s-5 11 -4 18l30 172v0v1l4 21c4 25 5 43 1 52c-3 8 -10 12 -18 14h-98c-7 0 -12 2 -17 7s-7 10 -7 17s2 12 7 17s10 7 17 7
+h336z" />
+ <glyph glyph-name="ion-ios-bolt-outline" unicode="&#xf3e5;" horiz-adv-x="226"
+d="M131 316l-100 -140h65h19l-3 -19l-17 -89l100 140h-65h-19l3 19zM160 384v0l-30 -160h96l-160 -224l30 160h-96z" />
+ <glyph glyph-name="ion-ios-bolt" unicode="&#xf3e6;" horiz-adv-x="226"
+d="M160 384v0l-30 -160h96l-160 -224l30 160h-96z" />
+ <glyph glyph-name="ion-ios-book-outline" unicode="&#xf3e7;" horiz-adv-x="384"
+d="M284 384c55 0 100 -26 100 -79v-1v-4v-261v-17h-6h-11h-5c-17 30 -44 42 -78 42c-40 0 -74 -28 -82 -64h-20c-8 36 -42 64 -82 64c-34 0 -65 -16 -78 -42h-5h-11h-6v9v264v9v1c0 53 45 79 100 79c41 0 78 -14 92 -44c12 30 51 44 92 44zM184 37v254v13v2
+c-1 43 -39 62 -84 62c-44 0 -81 -19 -84 -61v-1v0v-262h1c19 26 48 36 83 36s66 -17 84 -43zM368 300v14v1c-3 42 -40 53 -84 53c-46 0 -84 -20 -84 -64v-1v-266c18 26 49 43 84 43s66 -10 84 -36v256z" />
+ <glyph glyph-name="ion-ios-book" unicode="&#xf3e8;" horiz-adv-x="384"
+d="M100 384c35 0 67 -10 84 -31v-353h-2c-8 36 -42 64 -82 64c-34 0 -65 -16 -78 -42h-5h-11h-6v9v264v9v1c0 53 45 79 100 79zM284 384c55 0 100 -26 100 -79v-1v-4v-261v-17h-6h-11h-5c-17 30 -44 42 -78 42c-40 0 -74 -28 -82 -64h-2v353c17 21 50 31 84 31z" />
+ <glyph glyph-name="ion-ios-bookmarks-outline" unicode="&#xf3e9;" horiz-adv-x="418"
+d="M385 384c19 0 33 -13 33 -32v-286c0 -19 -14 -34 -33 -34h-143s-25 -4 -25 -19v-13h-8h-8v13c0 15 -11 19 -25 19h-143c-19 0 -33 15 -33 34v286c0 19 14 32 33 32h150c10 0 20 -5 26 -12v0v0c6 7 16 12 26 12h150zM201 37v309c0 9 -12 22 -25 22h-143
+c-9 0 -16 -7 -16 -16v-286c0 -9 7 -18 16 -18h144c10 0 19 -3 24 -11zM273 368v-100l23 14l9 6l9 -6l23 -14v100h-64zM401 66v286c0 9 -7 16 -16 16h-32v-131l-48 32l-48 -32v131h-15c-13 0 -25 -13 -25 -22v-309c5 9 14 11 24 11h144c9 0 16 9 16 18z" />
+ <glyph glyph-name="ion-ios-bookmarks" unicode="&#xf3ea;" horiz-adv-x="418"
+d="M296 283l-23 -15v116h64v-116l-23 15l-9 6zM385 384c19 0 33 -13 33 -32v-286c0 -19 -14 -34 -33 -34h-143s-25 -4 -25 -19v-13h-8h-8v13c0 15 -11 19 -25 19h-143c-19 0 -33 15 -33 34v286c0 19 14 32 33 32h150s18 -8 18 -15v-329l8 -6l8 6v329s10 15 18 15h22v-146
+l48 32l48 -32v146h32z" />
+ <glyph glyph-name="ion-ios-box-outline" unicode="&#xf3eb;" horiz-adv-x="320"
+d="M192 208h-1h-63c-9 0 -16 -7 -16 -16s7 -16 16 -16h64c9 0 16 7 16 16s-7 16 -16 16zM192 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32h-64c-18 0 -32 14 -32 32s14 32 32 32h64zM320 336v-80h-16v-208h-288v208h-16v80h320zM288 64v192h-256v-192h256zM304 272v48h-288
+v-48h288z" />
+ <glyph glyph-name="ion-ios-box" unicode="&#xf3ec;" horiz-adv-x="320"
+d="M16 48v192h288v-192h-288zM128 208c-9 0 -16 -7 -16 -16s7 -16 16 -16h64c9 0 16 7 16 16s-7 16 -16 16h-64zM0 336h320v-80h-16h-288h-16v80z" />
+ <glyph glyph-name="ion-ios-briefcase-outline" unicode="&#xf3ed;" horiz-adv-x="416"
+d="M368 320h48v-320h-416v320h48v16h32v-16h48v30v2c0 18 10 32 29 32h99c19 0 32 -14 32 -32v-2v-30h48v16h32v-16zM144 320v0h128v0v30c0 10 -7 18 -17 18h-97c-11 0 -14 -8 -14 -18v-30zM400 16v224h-384v-224h384zM400 256v48h-32v-16h-32v16h-256v-16h-32v16h-32v-48
+h384z" />
+ <glyph glyph-name="ion-ios-briefcase" unicode="&#xf3ee;" horiz-adv-x="416"
+d="M48 320v16h32v-16h-32zM0 0v240h416v-240h-416zM336 320v16h32v-16h-32zM368 320h48v-64h-416v64h48v-32h32v32h48v30v2c0 18 10 32 29 32h99c19 0 32 -14 32 -32v-2v-30h48v-32h32v32zM272 320v30c0 10 -7 18 -17 18h-97c-11 0 -14 -8 -14 -18v-30v0h128v0z" />
+ <glyph glyph-name="ion-ios-browsers-outline" unicode="&#xf3ef;" horiz-adv-x="384"
+d="M0 304h304v-304h-304v304zM288 16v272h-272v-272h272zM384 384v-304h-64v16h48v272h-272v-48h-16v64h304z" />
+ <glyph glyph-name="ion-ios-browsers" unicode="&#xf3f0;" horiz-adv-x="384"
+d="M0 304h304v-304h-304v304zM80 384h304v-304h-64v240h-240v64z" />
+ <glyph glyph-name="ion-ios-calculator-outline" unicode="&#xf3f1;" horiz-adv-x="288"
+d="M32 288v64h224v-64h-224zM48 336v-32h192v32h-192zM256 384c18 0 32 -14 32 -32v-320c0 -18 -14 -32 -32 -32h-224c-18 0 -32 14 -32 32v320c0 18 14 32 32 32h224zM272 32v320c0 9 -7 16 -16 16h-224c-9 0 -16 -7 -16 -16v-320c0 -9 7 -16 16 -16h224c9 0 16 7 16 16z
+M48 208h32h16v-16h-64v64h16v-16v-32zM48 128h32h16v-16h-64v64h16v-16v-32zM48 48h32h16v-16h-64v64h16v-16v-32zM128 208h32h16v-16h-64v64h16v-16v-32zM208 208h32h16v-16h-64v64h16v-16v-32zM128 128h32h16v-16h-64v64h16v-16v-32zM128 48h32h16v-16h-64v64h16v-16v-32z
+M208 48h32h16v-16h-64v144h16v-96v-32z" />
+ <glyph glyph-name="ion-ios-calculator" unicode="&#xf3f2;" horiz-adv-x="288"
+d="M256 384c18 0 32 -14 32 -32v-320c0 -18 -14 -32 -32 -32h-224c-18 0 -32 14 -32 32v320c0 18 14 32 32 32h224zM248 168h-48v-128h48v128zM248 248h-48v-48h48v48zM168 88h-48v-48h48v48zM168 168h-48v-48h48v48zM168 248h-48v-48h48v48zM88 88h-48v-48h48v48zM88 168
+h-48v-48h48v48zM88 248h-48v-48h48v48zM40 296h208v48h-208v-48z" />
+ <glyph glyph-name="ion-ios-calendar-outline" unicode="&#xf3f3;" horiz-adv-x="384"
+d="M16 336v-64h352v64zM288 352h96v-352h-384v352h96v32h16v-32h160v32h16v-32zM368 16v240h-352v-240h352zM368 272v64h-80v-32h-16v32h-160v-32h-16v32h-80v-64h352z" />
+ <glyph glyph-name="ion-ios-calendar" unicode="&#xf3f4;" horiz-adv-x="384"
+d="M0 0v256h384v-256h-384zM384 352v-80h-384v80h96v-48h16v48h160v-48h16v48h96zM96 352v32h16v-32h-16zM272 352v32h16v-32h-16z" />
+ <glyph glyph-name="ion-ios-camera-outline" unicode="&#xf3f5;" horiz-adv-x="384"
+d="M354 288c18 0 30 -13 30 -31v-176c0 -18 -12 -33 -30 -33h-320c-18 0 -34 15 -34 33v176c0 18 16 31 34 31h13v16h34v-16h13c32 36 43 48 55 48h88c12 0 23 -12 55 -48h62zM368 81v176c0 9 -5 15 -14 15h-62h-7l-5 3c-3 4 -7 8 -10 11c-12 13 -20 24 -26 30
+c-5 5 -7 4 -7 4h-88s-2 0 -7 -4c-6 -5 -14 -14 -25 -27c-3 -4 -7 -10 -11 -14l-5 -3h-7h-60c-9 0 -18 -7 -18 -15v-176c0 -9 9 -17 18 -17h320c8 0 14 8 14 17zM192 258c47 0 86 -38 86 -85s-39 -85 -86 -85s-86 38 -86 85s39 85 86 85zM192 104c38 0 70 31 70 69
+s-32 69 -70 69s-70 -31 -70 -69s32 -69 70 -69zM288 239v17h17v-17h-17zM160 173c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32z" />
+ <glyph glyph-name="ion-ios-camera" unicode="&#xf3f6;" horiz-adv-x="384"
+d="M354 288c18 0 30 -13 30 -31v-176c0 -18 -12 -33 -30 -33h-320c-18 0 -34 15 -34 33v176c0 18 16 31 34 31h13v16h34v-16h13c32 36 43 48 55 48h88c12 0 23 -12 55 -48h62zM192 88c47 0 86 38 86 85s-39 85 -86 85s-86 -38 -86 -85s39 -85 86 -85zM305 239v17h-17v-17h17
+zM192 242c38 0 70 -31 70 -69s-32 -69 -70 -69s-70 31 -70 69s32 69 70 69zM192 141c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-ios-cart-outline" unicode="&#xf3f7;" horiz-adv-x="384"
+d="M96 48c13 0 24 -11 24 -24s-11 -24 -24 -24s-24 11 -24 24s11 24 24 24zM96 16c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM320 48c13 0 24 -11 24 -24s-11 -24 -24 -24s-24 11 -24 24s11 24 24 24zM320 16c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM384 320
+l-16 -128l-271 -48l5 -30c7 -34 21 -34 26 -34h240v-16h-240c-11 0 -21 5 -28 14c-6 8 -11 19 -13 33l-43 234v0c-2 8 -3 12 -7 16c-6 5 -18 7 -37 7v16c23 0 38 -4 47 -11c7 -6 10 -14 12 -21zM355 206l11 99l-304 31l32 -176z" />
+ <glyph glyph-name="ion-ios-cart" unicode="&#xf3f8;" horiz-adv-x="384"
+d="M96 48c13 0 24 -11 24 -24s-11 -24 -24 -24s-24 11 -24 24s11 24 24 24zM320 48c13 0 24 -11 24 -24s-11 -24 -24 -24s-24 11 -24 24s11 24 24 24zM384 320l-16 -128l-271 -48l5 -30c7 -34 21 -34 26 -34h240v-16h-240c-11 0 -21 5 -28 14c-6 8 -11 19 -13 33l-43 234v0
+c-2 8 -3 12 -7 16c-6 5 -18 7 -37 7v16c23 0 38 -4 47 -11c7 -6 10 -14 12 -21z" />
+ <glyph glyph-name="ion-ios-chatboxes-outline" unicode="&#xf3f9;" horiz-adv-x="416"
+d="M16 384v-192h96v-16h-112v224h288v-112h-16v96h-256zM128 272h288v-224h-48v-64h-13l-64 64h-163v224zM400 64v192h-256v-192h153l55 -55v55h48z" />
+ <glyph glyph-name="ion-ios-chatboxes" unicode="&#xf3fa;" horiz-adv-x="416"
+d="M288 400v-112h-176v-112h-112v224h288zM128 272h288v-224h-48v-64h-13l-64 64h-163v224z" />
+ <glyph glyph-name="ion-ios-chatbubble-outline" unicode="&#xf3fb;" horiz-adv-x="384"
+d="M192 336c-97 0 -176 -62 -176 -138c0 -26 10 -51 27 -73c0 -1 0 -2 1 -3s2 -1 2 -2c4 -6 6 -13 6 -20c0 -3 1 -3 -13 -47l39 17v0c2 1 10 4 11 4h1v0c5 2 10 3 16 3c5 0 9 -1 14 -2l1 -1h2c19 -6 41 -10 70 -10c48 0 92 15 125 40c32 25 50 58 50 94
+c0 76 -79 138 -176 138zM192 352v0c106 0 192 -69 192 -154s-85 -150 -191 -150c-27 0 -52 3 -75 11h-2v0c-3 1 -6 2 -10 2s-9 -1 -12 -2h1h-1c-1 0 -9 -4 -10 -4l-50 -22l-2 -1h-3h-3c-6 1 -8 6 -7 10v0s17 57 17 58c0 4 -1 8 -3 11v0v0v0l1 -1l-4 4c-19 24 -30 53 -30 84
+c0 85 86 154 192 154z" />
+ <glyph glyph-name="ion-ios-chatbubble" unicode="&#xf3fc;" horiz-adv-x="384"
+d="M192 352v0c106 0 192 -69 192 -154s-85 -150 -191 -150c-27 0 -52 3 -75 11h-2v0c-3 1 -6 2 -10 2s-9 -1 -12 -2h1h-1c-1 0 -9 -4 -10 -4l-50 -22l-2 -1h-3h-3c-6 1 -8 6 -7 10v0s17 57 17 58c0 4 -1 8 -3 11v0v0v0l1 -1l-4 4c-19 24 -30 53 -30 84c0 85 86 154 192 154z
+" />
+ <glyph glyph-name="ion-ios-checkmark-empty" unicode="&#xf3fd;" horiz-adv-x="207"
+d="M74 118c-2 -2 -6 -4 -9 -4s-7 2 -9 4l-56 56l18 18l47 -47l125 126l17 -18z" />
+ <glyph glyph-name="ion-ios-checkmark-outline" unicode="&#xf3fe;" horiz-adv-x="416"
+d="M292 271l18 -18l-134 -135c-2 -2 -6 -4 -9 -4s-7 2 -9 4l-56 56l18 18l47 -47zM208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191z" />
+ <glyph glyph-name="ion-ios-checkmark" unicode="&#xf3ff;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM176 118l134 135l-18 18l-125 -126l-47 47l-18 -18l56 -56c2 -2 6 -4 9 -4s7 2 9 4z" />
+ <glyph glyph-name="ion-ios-circle-filled" unicode="&#xf400;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM208 352c88 0 160 -72 160 -160s-72 -160 -160 -160s-160 72 -160 160s72 160 160 160z" />
+ <glyph glyph-name="ion-ios-circle-outline" unicode="&#xf401;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191z" />
+ <glyph glyph-name="ion-ios-clock-outline" unicode="&#xf402;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM208 192v128h17v-145h-113v17h96z" />
+ <glyph glyph-name="ion-ios-clock" unicode="&#xf403;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM225 175v145h-17v-128h-96v-17h113z" />
+ <glyph glyph-name="ion-ios-close-empty" unicode="&#xf404;" horiz-adv-x="192"
+d="M180 288l12 -12l-84 -84l84 -84l-12 -12l-84 84l-84 -84l-12 12l84 84l-84 84l12 12l84 -84z" />
+ <glyph glyph-name="ion-ios-close-outline" unicode="&#xf405;" horiz-adv-x="416"
+d="M355 339c81 -81 81 -213 0 -294s-213 -81 -294 0s-81 213 0 294s213 81 294 0zM343 57c74 74 74 196 0 270s-196 74 -270 0s-74 -196 0 -270s196 -74 270 0zM292 288l12 -12l-84 -84l84 -84l-12 -12l-84 84l-84 -84l-12 12l84 84l-84 84l12 12l84 -84z" />
+ <glyph glyph-name="ion-ios-close" unicode="&#xf406;" horiz-adv-x="416"
+d="M355 339c81 -81 81 -213 0 -294s-213 -81 -294 0s-81 213 0 294s213 81 294 0zM304 108l-84 84l84 84l-12 12l-84 -84l-84 84l-12 -12l84 -84l-84 -84l12 -12l84 84l84 -84z" />
+ <glyph glyph-name="ion-ios-cloud-download-outline" unicode="&#xf407;"
+d="M161 67l55 -54v242h16v-242l55 54l12 -12l-75 -73l-74 73zM367 284c45 0 81 -37 81 -82s-37 -82 -82 -82v0h-101v16h97h4c37 0 66 30 66 66s-29 67 -66 67h-15v20c0 55 -46 97 -101 97c-38 0 -73 -22 -90 -56l-6 -14l-14 7c-6 3 -13 5 -20 5c-22 0 -40 -18 -44 -39l-1 -9
+l-9 -3c-30 -10 -50 -36 -50 -67c0 -40 33 -74 74 -74h91v-16h-91c-50 0 -90 40 -90 89c0 39 26 71 61 83c5 28 29 51 59 51c10 0 18 -2 26 -6c19 39 59 65 105 65c64 0 117 -51 117 -115c0 -1 -1 -2 -1 -3z" />
+ <glyph glyph-name="ion-ios-cloud-download" unicode="&#xf408;"
+d="M216 13v107h16v-107l55 54l12 -12l-75 -73l-74 73l11 12zM367 284c45 0 81 -37 81 -82s-37 -82 -82 -82h-134v135h-16v-135h-35h-21h-70c-50 0 -90 40 -90 89c0 39 26 71 61 83c5 28 29 51 59 51c10 0 18 -2 26 -6c19 39 59 65 105 65c64 0 117 -51 117 -115
+c0 -1 -1 -2 -1 -3z" />
+ <glyph glyph-name="ion-ios-cloud-outline" unicode="&#xf409;"
+d="M367 215c45 0 81 -37 81 -83c0 -45 -37 -84 -82 -84h-276c-50 0 -90 42 -90 92c0 40 26 71 61 83c5 28 29 52 59 52c10 0 18 -2 26 -6c19 39 59 67 105 67c64 0 117 -53 117 -117c0 -1 -1 -3 -1 -4zM366 64c37 0 66 32 66 69s-29 67 -66 67h-15v21c0 56 -46 99 -101 99
+c-38 0 -73 -23 -90 -58l-6 -14l-14 7c-6 3 -13 5 -20 5c-22 0 -40 -17 -44 -39l-1 -9l-9 -3c-30 -10 -50 -37 -50 -69c0 -41 33 -76 74 -76h272h4z" />
+ <glyph glyph-name="ion-ios-cloud-upload-outline" unicode="&#xf40a;"
+d="M161 188l-11 11l74 75l75 -75l-12 -11l-55 54v-242h-16v242zM367 264c45 0 81 -39 81 -85s-37 -83 -82 -83v0h-101v16h97h4c37 0 66 30 66 67s-29 70 -66 70l-15 1v20c0 56 -46 99 -101 99c-38 0 -73 -23 -90 -58l-6 -13l-14 6c-6 3 -13 5 -20 5c-22 0 -40 -17 -44 -39
+l-1 -9l-9 -3c-30 -10 -50 -39 -50 -71c0 -41 33 -75 74 -75h91v-16h-91c-50 0 -90 40 -90 90c0 40 26 74 61 86c5 28 29 52 59 52c10 0 18 -2 26 -6c19 39 59 66 105 66c64 0 117 -52 117 -116c0 -1 -1 -3 -1 -4z" />
+ <glyph glyph-name="ion-ios-cloud-upload" unicode="&#xf40b;"
+d="M216 0v96h16v-96h-16zM367 264c45 0 81 -39 81 -85s-37 -83 -82 -83h-134v146l55 -54l12 11l-75 75l-74 -75l11 -11l55 54v-146h-35h-31h-60c-50 0 -90 40 -90 90c0 40 26 74 61 86c5 28 29 52 59 52c10 0 18 -2 26 -6c19 39 59 66 105 66c64 0 117 -52 117 -116
+c0 -1 -1 -3 -1 -4z" />
+ <glyph glyph-name="ion-ios-cloud" unicode="&#xf40c;"
+d="M367 215c45 0 81 -37 81 -83c0 -45 -37 -84 -82 -84h-276c-50 0 -90 42 -90 92c0 40 26 71 61 83c5 28 29 52 59 52c10 0 18 -2 26 -6c19 39 59 67 105 67c64 0 117 -53 117 -117c0 -1 -1 -3 -1 -4z" />
+ <glyph glyph-name="ion-ios-cloudy-night-outline" unicode="&#xf40d;" horiz-adv-x="384"
+d="M125 224c-34 0 -63 -28 -63 -62v-12s1 -10 1 -10c-5 0 -12 -1 -14 -1c-19 -3 -33 -18 -33 -37c0 -10 3 -19 10 -26s16 -11 26 -11h157c27 0 49 22 49 49s-22 50 -49 50c-2 0 -4 -1 -6 -1l-14 -2l-3 14c-3 14 -11 26 -22 35s-25 14 -39 14zM125 240v0c37 0 68 -26 76 -61
+h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78zM361 142c8 0 15 2 23 4c-4 -7 -9 -14 -14 -20c-21 -24 -50 -41 -84 -45c4 6 6 12 8 19c19 4 36 13 50 25c-18 1 -35 6 -50 13c-23 11 -42 29 -56 51
+c-14 21 -22 48 -22 75c0 15 2 30 7 44c-24 -12 -43 -33 -53 -59c-5 2 -12 4 -18 5c14 36 45 65 82 77c8 2 16 4 24 5c-5 -6 -9 -13 -12 -20c-8 -16 -12 -34 -12 -52c0 -32 12 -63 35 -86s54 -36 86 -36h6z" />
+ <glyph glyph-name="ion-ios-cloudy-night" unicode="&#xf40e;" horiz-adv-x="384"
+d="M361 142c8 0 15 2 23 4c-4 -7 -9 -15 -14 -21c-21 -24 -50 -40 -84 -44h-3c4 10 7 21 7 32c0 22 -9 43 -24 58c-14 15 -33 23 -53 24c-6 16 -16 29 -29 40c-10 8 -20 13 -32 17v2c14 36 45 65 82 77c8 2 16 4 24 5c-5 -6 -9 -13 -12 -20c-8 -16 -12 -34 -12 -52
+c0 -32 12 -63 35 -86s54 -36 86 -36h6zM125 239v0c37 0 68 -26 76 -61h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v7c0 43 35 79 78 79z" />
+ <glyph glyph-name="ion-ios-cloudy-outline" unicode="&#xf40f;" horiz-adv-x="274"
+d="M125 272c-34 0 -63 -28 -63 -62v-12s1 -10 1 -10c-6 0 -12 -1 -14 -1c-19 -3 -33 -18 -33 -37c0 -10 3 -19 10 -26s16 -11 26 -11h157c27 0 49 22 49 49s-22 50 -49 50c-2 0 -4 -1 -6 -1l-14 -2l-3 14c-3 14 -11 26 -22 35s-25 14 -39 14zM125 288v0c37 0 68 -26 76 -61
+h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78z" />
+ <glyph glyph-name="ion-ios-cloudy" unicode="&#xf410;" horiz-adv-x="274"
+d="M125 288v0c37 0 68 -26 76 -61h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78z" />
+ <glyph glyph-name="ion-ios-cog-outline" unicode="&#xf411;" horiz-adv-x="384"
+d="M384 175l-33 -8l-3 -14l27 -20l-12 -30l-34 5l-8 -11l17 -29l-23 -23l-29 17l-10 -7l5 -34l-29 -12l-21 27l-14 -3l-8 -33h-32l-9 33l-13 3l-21 -28l-29 12l4 34l-11 8l-30 -19l-23 23l18 31l-7 11l-35 -5l-12 29l28 22l-2 12l-35 9v32l35 9l2 12l-29 22l12 30l36 -5
+l7 10l-19 32l22 22l32 -19l11 8l-4 35l29 13l22 -29l12 2l9 35h32l9 -35l12 -2l22 28l29 -12l-5 -35l11 -8l30 18l22 -23l-17 -30l7 -10l35 5l12 -30l-28 -21l3 -13l33 -9v-32zM356 127l-26 20l6 33l32 8v7l-32 8l-6 33l26 19l-3 7l-32 -5l-19 27l17 28l-5 6l-28 -17l-28 18
+l5 34l-6 2l-20 -26l-32 6l-8 33h-7l-9 -33l-32 -6l-20 27l-7 -3l5 -34l-28 -18l-9 6l-21 12l-5 -5l18 -30l-18 -27l-33 5l-3 -7l27 -20l-6 -32l-33 -8v-7l33 -9l6 -32l-27 -20l3 -6l33 4l18 -27l-17 -29l5 -6l29 18l28 -18l-5 -33l7 -3l19 27l33 -7l8 -31h8l7 31l33 7
+l20 -26l7 3l-5 32l26 18l28 -16l5 5l-16 27l19 28l32 -4zM192 320c71 0 128 -57 128 -128s-57 -128 -128 -128s-128 57 -128 128s57 128 128 128zM80 192c0 -7 1 -15 2 -22l104 28l28 104c-7 1 -15 2 -22 2c-30 0 -58 -12 -79 -33s-33 -49 -33 -79zM192 80c27 0 53 10 73 27
+l-75 75l-104 -28c6 -15 15 -29 27 -41c21 -21 49 -33 79 -33zM276 118c18 20 28 47 28 74c0 30 -12 58 -33 79c-12 12 -26 22 -42 27l-28 -105z" />
+ <glyph glyph-name="ion-ios-cog" unicode="&#xf412;" horiz-adv-x="384"
+d="M229 298c16 -5 30 -15 42 -27c21 -21 33 -49 33 -79c0 -27 -10 -54 -28 -74l-75 75zM214 302l-28 -104l-104 -28c-1 7 -2 15 -2 22c0 30 12 58 33 79s49 33 79 33c7 0 15 -1 22 -2zM86 154l104 28l75 -75c-20 -17 -46 -27 -73 -27c-30 0 -58 12 -79 33
+c-12 12 -21 26 -27 41zM384 175l-33 -8l-3 -14l27 -20l-12 -30l-34 5l-8 -11l17 -29l-23 -23l-29 17l-10 -7l5 -34l-29 -12l-21 27l-14 -3l-8 -33h-32l-9 33l-13 3l-21 -28l-29 12l4 34l-11 8l-30 -19l-23 23l18 31l-7 11l-35 -5l-12 29l28 22l-2 12l-35 9v32l35 9l2 12
+l-29 22l12 30l36 -5l7 10l-19 32l22 22l32 -19l11 8l-4 35l29 13l22 -29l12 2l9 35h32l9 -35l12 -2l22 28l29 -12l-5 -35l11 -8l30 18l22 -23l-17 -30l7 -10l35 5l12 -30l-28 -21l3 -13l33 -9v-32zM192 64c71 0 128 57 128 128s-57 128 -128 128s-128 -57 -128 -128
+s57 -128 128 -128z" />
+ <glyph glyph-name="ion-ios-color-filter-outline" unicode="&#xf413;" horiz-adv-x="384"
+d="M302 236c47 -13 82 -57 82 -108c0 -62 -50 -112 -112 -112c-31 0 -60 13 -80 34c-20 -21 -49 -34 -80 -34c-62 0 -112 50 -112 112c0 51 35 95 82 108c-1 7 -2 13 -2 20c0 62 50 112 112 112s112 -50 112 -112c0 -7 -1 -13 -2 -20zM96 256c0 -6 0 -12 1 -17
+c5 1 10 1 15 1c31 0 60 -13 80 -34c20 21 49 34 80 34c5 0 10 0 15 -1c1 5 1 11 1 17c0 53 -43 96 -96 96s-96 -43 -96 -96zM208 128c0 6 0 12 -1 17c-5 -1 -10 -1 -15 -1s-10 0 -15 1c-1 -5 -1 -11 -1 -17c0 -20 6 -38 16 -53c10 15 16 33 16 53zM192 160c3 0 7 1 10 1
+c-3 7 -6 14 -10 20c-4 -6 -7 -13 -10 -20c3 0 7 -1 10 -1zM166 164c4 11 9 21 16 30c-18 18 -43 30 -70 30c-3 0 -7 -1 -10 -1c10 -29 34 -51 64 -59zM202 194c7 -9 12 -19 16 -30c30 8 54 30 64 59c-3 0 -7 1 -10 1c-27 0 -52 -12 -70 -30zM112 32c27 0 52 12 70 30
+c-14 19 -22 41 -22 66c0 7 1 13 2 20c-36 10 -64 37 -76 72c-40 -11 -70 -48 -70 -92c0 -53 43 -96 96 -96zM272 32c53 0 96 43 96 96c0 44 -30 81 -70 92c-12 -35 -40 -62 -76 -72c1 -7 2 -13 2 -20c0 -25 -8 -47 -22 -66c18 -18 43 -30 70 -30z" />
+ <glyph glyph-name="ion-ios-color-filter" unicode="&#xf414;" horiz-adv-x="384"
+d="M302 236c47 -13 82 -57 82 -108c0 -62 -50 -112 -112 -112c-31 0 -60 13 -80 34c-20 -21 -49 -34 -80 -34c-62 0 -112 50 -112 112c0 51 35 95 82 108c-1 7 -2 13 -2 20c0 62 50 112 112 112s112 -50 112 -112c0 -7 -1 -13 -2 -20zM192 53l1 -2c3 3 6 7 9 11
+c14 19 22 41 22 66c0 7 -1 13 -2 20c36 10 64 37 76 72c2 5 3 10 4 15c-1 0 -2 1 -3 1v1c-4 1 -8 1 -12 2c-5 1 -10 1 -15 1c-31 0 -60 -13 -80 -34c-20 21 -49 34 -80 34c-5 0 -10 0 -15 -1c-4 -1 -8 -1 -12 -2v-1c-1 0 -2 -1 -3 -1c1 -5 2 -10 4 -15c12 -35 40 -62 76 -72
+c-1 -7 -2 -13 -2 -20c0 -25 8 -47 22 -66c3 -4 6 -8 9 -11zM207 145c1 -5 1 -11 1 -17c0 -20 -6 -38 -16 -53c-10 15 -16 33 -16 53c0 6 0 12 1 17c5 -1 10 -1 15 -1s10 0 15 1zM282 223c-10 -29 -34 -51 -64 -59c-4 11 -9 21 -16 30c18 18 43 30 70 30c3 0 7 -1 10 -1z
+M202 161c-3 0 -7 -1 -10 -1s-7 1 -10 1c3 7 6 14 10 20c4 -6 7 -13 10 -20zM112 224c27 0 52 -12 70 -30c-7 -9 -12 -19 -16 -30c-30 8 -54 30 -64 59c3 0 7 1 10 1z" />
+ <glyph glyph-name="ion-ios-color-wand-outline" unicode="&#xf415;" horiz-adv-x="384"
+d="M128 298l256 -256l-34 -34l-256 256zM149 232l201 -201l11 11l-201 202zM120 344v40h16v-40h-16zM120 140v40h16v-40h-16zM216 256v16h40v-16h-40zM0 256v16h40v-16h-40zM47 354l29 -29l-12 -11l-28 28zM76 198l-29 -28l-11 11l28 28zM220 342l-28 -28l-12 11l29 29z" />
+ <glyph glyph-name="ion-ios-color-wand" unicode="&#xf416;" horiz-adv-x="396"
+d="M140 289l256 -257l-34 -34l-256 257zM124 322v64h32v-64h-32zM124 118v64h32v-64h-32zM216 238v32h64v-32h-64zM246 336l-45 -45l-23 22l45 46zM34 336l23 23l45 -46l-23 -22zM34 169l45 45l23 -22l-45 -46zM0 238v32h64v-32h-64z" />
+ <glyph glyph-name="ion-ios-compose-outline" unicode="&#xf417;" horiz-adv-x="384"
+d="M304 32v208l16 16v-240h-320v304h256l-16 -16h-224v-272h288zM174 164l171 171l11 -11l-180 -180h-32v32l180 180l11 -11l-171 -171zM380 368c2 -3 4 -6 4 -10s-2 -7 -4 -10l-12 -12l-21 21l-11 11v0l12 12c3 2 6 4 10 4s7 -2 10 -4z" />
+ <glyph glyph-name="ion-ios-compose" unicode="&#xf418;" horiz-adv-x="384"
+d="M192 128l128 128v-240h-320v304h256l-128 -128v-64h64zM324 356l32 -32l-180 -180h-32v32zM380 368c2 -3 4 -6 4 -10s-2 -7 -4 -10l-12 -12l-21 21l-11 11v0l12 12c3 2 6 4 10 4s7 -2 10 -4z" />
+ <glyph glyph-name="ion-ios-contact-outline" unicode="&#xf419;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 383c-105 0 -191 -86 -191 -191c0 -47 17 -89 45 -122c18 8 62 24 90 32c2 1 3 0 3 10c0 11 -1 18 -4 24c-4 8 -7 20 -9 31c-4 5 -10 15 -14 33c-3 16 -1 22 1 28v2
+c1 4 0 23 -3 38c-2 10 1 34 15 52c9 12 27 26 58 28h18c32 -2 49 -16 58 -28c14 -18 17 -42 15 -52c-3 -15 -4 -34 -3 -38c0 0 1 -1 1 -2c2 -6 3 -12 0 -28c-4 -18 -10 -27 -14 -32c-2 -11 -5 -24 -9 -32c-3 -7 -6 -15 -6 -23c0 -10 0 -10 2 -11c27 -8 73 -24 93 -32
+c28 33 45 76 45 122c0 105 -86 191 -191 191z" />
+ <glyph glyph-name="ion-ios-contact" unicode="&#xf41a;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c59 0 111 27 146 69c-20 8 -66 24 -93 32c-2 1 -3 1 -3 11c0 8 4 16 7 23c4 8 7 21 9 32c4 5 10 14 14 32c3 16 2 22 0 28c0 0 -1 1 -1 2c-1 4 0 23 3 38c2 10 -1 34 -15 52
+c-9 12 -26 26 -58 28h-18c-31 -2 -49 -16 -58 -28c-14 -18 -17 -42 -15 -52c3 -15 4 -34 3 -38v-2c-2 -6 -4 -12 -1 -28c4 -18 10 -28 14 -33c2 -11 5 -23 9 -31c3 -6 4 -13 4 -24c0 -10 -1 -9 -3 -10c-28 -8 -72 -24 -90 -32c35 -42 87 -69 146 -69z" />
+ <glyph glyph-name="ion-ios-copy-outline" unicode="&#xf41b;" horiz-adv-x="288"
+d="M192 352v-64h64v-16h-80v80h16zM213 384l75 -75v-261h-48v-48h-240v336h48v48h165zM224 16v32h-176v272h-32v-304h208zM272 64v238l-65 66h-143v-304h208z" />
+ <glyph glyph-name="ion-ios-copy" unicode="&#xf41c;" horiz-adv-x="288"
+d="M32 32h16h192v-32h-240v336h32v-288v-16zM213 384l75 -75v-261h-48h-192v288v48h165zM256 272v16h-64v64h-16v-80h80z" />
+ <glyph glyph-name="ion-ios-crop-strong" unicode="&#xf41d;" horiz-adv-x="384"
+d="M64 336v48h32v-48h-32zM96 96h176v-32h-208v208h32v-176zM336 64v32h48v-32h-48zM0 320h320v-320h-32v288h-288v32z" />
+ <glyph glyph-name="ion-ios-crop" unicode="&#xf41e;" horiz-adv-x="384"
+d="M64 336v48h16v-48h-16zM80 80h208v-16h-224v224h16v-208zM336 64v16h48v-16h-48zM0 320h320v-320h-16v304h-304v16z" />
+ <glyph glyph-name="ion-ios-download-outline" unicode="&#xf41f;" horiz-adv-x="320"
+d="M192 304h128v-304h-320v304h128v-16h-112v-272h288v272h-112v16zM97 196l55 -55v243h16v-243l55 55l11 -12l-74 -74l-74 74z" />
+ <glyph glyph-name="ion-ios-download" unicode="&#xf420;" horiz-adv-x="320"
+d="M168 304h152v-304h-320v304h152v-163l-55 55l-11 -12l74 -74l74 74l-11 12l-55 -55v163zM152 304v80h16v-80h-16z" />
+ <glyph glyph-name="ion-ios-drag" unicode="&#xf421;" horiz-adv-x="352"
+d="M0 128v16h352v-16h-352zM0 184v16h352v-16h-352zM0 240v16h352v-16h-352z" />
+ <glyph glyph-name="ion-ios-email-outline" unicode="&#xf422;" horiz-adv-x="384"
+d="M0 320h384v-256h-384v256zM192 180l163 124h-326zM16 80h352v214l-115 -88l68 -77l-2 -2l-79 70l-48 -37l-48 37l-79 -70l-2 2l68 77l-115 88v-214z" />
+ <glyph glyph-name="ion-ios-email" unicode="&#xf423;" horiz-adv-x="384"
+d="M384 64h-384v242l131 -100l-68 -77l2 -2l79 70l48 -37l48 37l79 -70l2 2l-68 77l131 100v-242zM376 320l-184 -140l-184 140h368z" />
+ <glyph glyph-name="ion-ios-eye-outline" unicode="&#xf424;" horiz-adv-x="384"
+d="M383 192l1 -1l-6 -6c-21 -21 -47 -48 -78 -69c-36 -24 -72 -36 -108 -36c-83 0 -130 49 -185 105l-7 7l1 1c39 40 67 64 94 81c32 20 63 30 97 30c83 0 146 -60 191 -112zM192 288c-62 0 -111 -36 -170 -96c24 -24 48 -50 76 -68c30 -20 60 -28 94 -28
+c75 0 133 56 171 95c-26 29 -50 50 -74 66c-32 21 -64 31 -97 31zM192 112c-44 0 -80 36 -80 80s36 80 80 80s80 -36 80 -80s-36 -80 -80 -80zM192 256c-35 0 -64 -29 -64 -64s29 -64 64 -64s64 29 64 64s-29 64 -64 64zM224 192h16v0c0 -26 -22 -48 -48 -48s-48 21 -48 48
+s22 48 48 48v-16c-16 0 -32 -13 -32 -31s15 -33 32 -33s32 14 32 32v0z" />
+ <glyph glyph-name="ion-ios-eye" unicode="&#xf425;" horiz-adv-x="384"
+d="M383 192l1 -1l-6 -6c-21 -21 -47 -48 -78 -69c-36 -24 -72 -36 -108 -36c-83 0 -130 49 -185 105l-7 7l1 1c39 40 67 64 94 81c32 20 63 30 97 30c83 0 146 -60 191 -112zM192 112c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80zM186 221
+c0 -19 16 -35 35 -35c7 0 14 2 19 6v0c0 -27 -22 -48 -48 -48s-48 21 -48 48s22 48 48 48c-4 -5 -6 -12 -6 -19z" />
+ <glyph glyph-name="ion-ios-fastforward-outline" unicode="&#xf426;"
+d="M16 293v-202l184 101zM240 292v0v-78v-27v-95l176 100zM224 320v0l224 -128l-224 -128v123l-224 -123v256l224 -123v123z" />
+ <glyph glyph-name="ion-ios-fastforward" unicode="&#xf427;"
+d="M224 320v0l224 -128l-224 -128v123l-224 -123v256l224 -123v123z" />
+ <glyph glyph-name="ion-ios-filing-outline" unicode="&#xf428;" horiz-adv-x="352"
+d="M288 320l64 -96v-160h-176h-176v160l64 96h224zM333 224l-45 68v-68h45zM80 304v-80h48c0 -26 22 -48 48 -48s48 22 48 48h48v80h-192zM64 292l-45 -68h45v68zM336 80v128h-98c-7 -28 -32 -48 -62 -48s-55 20 -62 48h-98v-128h160h160z" />
+ <glyph glyph-name="ion-ios-filing" unicode="&#xf429;" horiz-adv-x="352"
+d="M176 160c30 0 55 20 62 48h114v-144h-176h-176v144h114c7 -28 32 -48 62 -48zM64 224h-7h-57l64 96v0v-80h16v80h192v-80h16v80v0l64 -96h-56h-8h-16h-8h-40c0 -26 -22 -48 -48 -48s-48 22 -48 48h-39h-9h-16z" />
+ <glyph glyph-name="ion-ios-film-outline" unicode="&#xf42a;" horiz-adv-x="400"
+d="M0 360h400v-336h-400v336zM72 40v48h-56v-48h56zM72 104v48h-56v-48h56zM72 168v48h-56v-48h56zM72 232v48h-56v-48h56zM72 296v48h-56v-48h56zM312 40v144h-224v-144h224zM312 200v144h-224v-144h224zM384 40v48h-56v-48h56zM384 104v48h-56v-48h56zM384 168v48h-56v-48
+h56zM384 232v48h-56v-48h56zM384 296v48h-56v-48h56z" />
+ <glyph glyph-name="ion-ios-film" unicode="&#xf42b;" horiz-adv-x="400"
+d="M0 360h400v-336h-400v336zM72 40v48h-56v-48h56zM72 104v48h-56v-48h56zM72 168v48h-56v-48h56zM72 232v48h-56v-48h56zM72 296v48h-56v-48h56zM312 184v16h-224v-16h224zM384 40v48h-56v-48h56zM384 104v48h-56v-48h56zM384 168v48h-56v-48h56zM384 232v48h-56v-48h56z
+M384 296v48h-56v-48h56z" />
+ <glyph glyph-name="ion-ios-flag-outline" unicode="&#xf42c;" horiz-adv-x="256"
+d="M240 336c6 1 11 1 16 2v-16v-157c-5 -1 -10 -1 -16 -2c-11 -1 -24 -3 -39 -3c-25 0 -47 4 -69 9s-42 13 -64 13c-30 0 -46 -5 -52 -7v-143h-16v142v162v2l3 3c2 1 18 11 65 11c24 0 45 -4 67 -9c21 -4 42 -11 65 -11c15 0 29 3 40 4zM240 179v0v141c-11 -1 -25 -4 -40 -4
+c-25 0 -46 6 -68 11s-42 9 -64 9c-30 0 -46 -5 -52 -7v-137c10 3 26 6 52 6c24 0 45 -8 67 -13c21 -4 43 -9 66 -9c15 0 28 2 39 3z" />
+ <glyph glyph-name="ion-ios-flag" unicode="&#xf42d;" horiz-adv-x="256"
+d="M240 336c6 1 11 1 16 2v-16v-157c-5 -1 -10 -1 -16 -2c-11 -1 -24 -3 -39 -3c-25 0 -47 4 -69 9s-42 13 -64 13c-30 0 -46 -5 -52 -7v-143h-16v142v162v2l3 3c2 1 18 11 65 11c24 0 45 -4 67 -9c21 -4 42 -11 65 -11c15 0 29 3 40 4z" />
+ <glyph glyph-name="ion-ios-flame-outline" unicode="&#xf42e;" horiz-adv-x="256"
+d="M96 416c87 -64 170 -179 159 -288c-13 -134 -104 -160 -127 -160s-127 40 -128 160c-1 146 122 143 96 288zM128 -24c0 0 40 36 40 80s-40 80 -40 80s-41 -36 -41 -80s41 -80 41 -80zM239 130c5 47 -10 99 -41 151c-22 36 -50 70 -83 99c0 -57 -24 -91 -49 -123
+c-26 -34 -50 -65 -50 -129c0 -25 5 -48 15 -68c8 -17 20 -32 35 -45c8 -7 16 -12 23 -16c-9 16 -18 35 -18 57c0 51 44 90 46 92l11 9l11 -9c2 -2 45 -41 45 -92c0 -23 -9 -44 -19 -60c7 4 13 8 20 14c14 12 25 27 34 44c11 21 17 47 20 76z" />
+ <glyph glyph-name="ion-ios-flame" unicode="&#xf42f;" horiz-adv-x="256"
+d="M96 416c87 -64 170 -179 159 -288c-13 -134 -104 -160 -127 -160s-127 40 -128 160c-1 146 122 143 96 288zM128 -24c0 0 40 36 40 80s-40 80 -40 80s-41 -36 -41 -80s41 -80 41 -80z" />
+ <glyph glyph-name="ion-ios-flask-outline" unicode="&#xf430;" horiz-adv-x="384"
+d="M373 78c8 -16 11 -32 11 -46c-1 -36 -27 -64 -63 -64h-256c-36 0 -64 27 -65 64c0 14 4 30 12 46l116 195v127h-16v16h16h16v-16v-16h48v-16h-48v-32h32v-16h-32v-32h48v-16h-48v-3l-2 -4l-15 -25h49v-16h-58l-92 -154c-13 -25 -14 -43 -2 -63c9 -14 23 -23 41 -23h256
+c17 0 33 8 41 22c5 8 6 17 6 26c0 12 -2 25 -9 38l-116 195l-3 4v131v16h16h16v-16h-16v-127zM44 73l72 119h153l72 -119c7 -11 10 -24 10 -33c-1 -24 -16 -40 -46 -40h-226c-30 0 -46 12 -46 40c0 9 4 22 11 33zM260 176h-135l-67 -111v0v0c-5 -8 -9 -19 -9 -25
+c0 -13 5 -17 6 -18c4 -4 13 -6 24 -6h226c10 0 18 3 23 7c4 4 7 10 7 18c0 6 -3 16 -8 24v0v0z" />
+ <glyph glyph-name="ion-ios-flask" unicode="&#xf431;" horiz-adv-x="384"
+d="M327 65v0c5 -8 8 -18 8 -24c0 -8 -3 -14 -7 -18c-5 -4 -13 -7 -23 -7h-226c-11 0 -20 2 -24 6c-1 1 -6 5 -6 18c0 6 4 17 9 25v0v0l67 111h135l67 -111v0zM373 78c8 -16 11 -32 11 -46c-1 -36 -27 -64 -63 -64h-256c-36 0 -64 27 -65 64c0 14 4 30 12 46l116 195v127h-16
+v16h160v-16h-16v-127zM144 384v-16h48v16h-48zM144 336v-16h32v16h-32zM144 288v-16h48v16h-48zM127 240l-9 -16h58v16h-49zM351 40c0 9 -3 22 -10 33l-72 119h-154l-71 -119c-7 -11 -11 -24 -11 -33c0 -28 16 -40 46 -40h226c30 0 45 16 46 40z" />
+ <glyph glyph-name="ion-ios-flower-outline" unicode="&#xf432;"
+d="M363 164c-29 0 -65 7 -93 14c-1 -3 -2 -6 -4 -9c25 -15 56 -36 76 -56c40 -40 53 -68 41 -80c-3 -3 -7 -4 -12 -4c-15 0 -38 15 -68 45c-20 20 -41 51 -56 76c-3 -2 -7 -3 -10 -4c7 -28 15 -64 15 -93c0 -56 -12 -85 -28 -85s-28 29 -28 85c0 29 8 65 15 93
+c-3 1 -7 2 -10 4c-15 -25 -36 -56 -56 -76c-30 -30 -53 -45 -68 -45c-5 0 -9 1 -12 4c-12 12 1 40 41 80c20 20 51 41 76 56c-2 3 -3 6 -4 9c-28 -7 -64 -14 -93 -14c-56 0 -85 12 -85 28s29 28 85 28c29 0 65 -8 93 -15c1 3 2 7 4 10c-25 15 -56 35 -76 55
+c-40 40 -53 68 -41 80c3 3 7 4 12 4c15 0 38 -14 68 -44c20 -20 41 -51 56 -76c3 2 7 3 10 4c-7 28 -15 64 -15 93c0 56 12 85 28 85s28 -29 28 -85c0 -29 -8 -65 -15 -93c3 -1 7 -2 10 -4c15 25 36 56 56 76c30 30 53 44 68 44c5 0 9 -1 12 -4c12 -12 -1 -40 -41 -80
+c-20 -20 -51 -40 -76 -55c2 -3 3 -7 4 -10c28 7 64 15 93 15c56 0 85 -12 85 -28s-29 -28 -85 -28zM288 193v-3c30 -7 56 -10 75 -10c21 0 39 2 52 5c10 3 14 6 16 7c-2 1 -6 4 -16 7c-13 3 -31 5 -52 5c-19 0 -45 -4 -75 -11zM314 299c-14 -14 -30 -35 -46 -61l2 -2
+c26 16 47 32 61 46c15 15 26 28 33 40c5 9 7 14 7 16c-4 0 -22 -4 -57 -39zM178 236l2 2c-16 26 -32 47 -46 61c-35 35 -53 39 -57 39c0 -2 2 -7 7 -16c7 -12 18 -25 33 -40c14 -14 35 -30 61 -46zM85 180c19 0 45 3 75 10v3c-30 7 -56 11 -75 11c-21 0 -39 -2 -52 -5
+c-10 -3 -14 -6 -16 -7c2 -1 5 -4 15 -7c13 -3 32 -5 53 -5zM134 85c14 14 30 35 46 61l-2 2c-26 -16 -47 -32 -61 -46c-15 -15 -26 -29 -33 -41c-5 -9 -7 -14 -7 -16c4 0 22 5 57 40zM270 148l-2 -2c16 -26 32 -47 46 -61c35 -35 53 -40 57 -40c0 2 -2 7 -7 16
+c-7 12 -18 26 -33 41c-14 14 -35 30 -61 46zM217 383c-3 -13 -5 -31 -5 -52c0 -19 4 -45 11 -75h2c7 30 11 56 11 75c0 21 -2 39 -5 52c-3 10 -6 14 -7 16c-1 -2 -4 -6 -7 -16zM231 0c3 13 5 32 5 53c0 19 -4 45 -11 75h-2c-7 -30 -11 -56 -11 -75c0 -21 2 -40 5 -53
+c3 -10 6 -13 7 -15c1 2 4 5 7 15zM224 160c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM313 42c10 -34 7 -53 -5 -58c-2 -1 -3 -1 -5 -1c-11 0 -25 13 -37 35c5 35 -2 76 -2 76s24 -34 49 -52zM302 -1c1 4 2 14 -3 34c-5 4 -10 9 -15 14
+c0 -9 0 -17 -1 -25c10 -16 16 -22 19 -23zM182 365c-6 -35 1 -75 1 -75s-27 35 -48 51c-10 35 -7 54 5 59c2 1 3 1 5 1c11 0 24 -12 37 -36zM164 337c0 9 0 17 1 25c-10 16 -16 21 -19 22c-1 -4 -2 -14 3 -34c5 -4 10 -8 15 -13zM50 149c35 -4 76 2 76 2s-34 -24 -51 -48
+c-12 -4 -26 -6 -35 -6c-13 0 -21 4 -24 11c-5 11 7 25 34 41zM66 117c4 5 8 10 13 15c-9 0 -17 0 -25 1c-16 -10 -21 -16 -22 -19c1 0 4 -1 8 -1c7 0 16 1 26 4zM432 276c5 -11 -7 -26 -34 -42c-35 5 -76 -2 -76 -2s33 25 51 49c13 4 26 5 35 5c13 0 21 -3 24 -10zM394 250
+c16 10 21 16 22 19c-1 0 -4 1 -8 1c-7 0 -16 -1 -26 -4c-4 -5 -8 -9 -13 -14c9 0 17 -1 25 -2zM131 39c31 24 53 55 53 55s-7 -39 -3 -71c-15 -26 -28 -39 -39 -39c-2 0 -4 0 -6 1c-11 5 -13 24 -5 54zM143 1c4 2 12 8 22 26c0 6 -1 13 -1 20c-6 -6 -13 -12 -19 -17
+c-4 -18 -3 -26 -2 -29zM312 398c11 -5 13 -22 5 -54c-29 -21 -53 -55 -53 -55s8 48 3 71c13 25 28 39 39 39c2 0 4 0 6 -1zM303 353c5 18 3 27 2 30c-4 -2 -12 -8 -22 -26c0 -6 1 -14 1 -21c6 6 13 12 19 17zM71 285c18 -24 55 -53 55 -53s-40 7 -70 3c-28 15 -43 32 -38 44
+c3 7 10 11 22 11c8 0 21 -1 31 -5zM33 273c2 -4 8 -12 26 -22c6 0 13 1 20 1c-6 6 -12 12 -17 18c-8 2 -16 4 -22 4c-4 0 -6 -1 -7 -1zM392 149c30 -17 43 -33 38 -45c-3 -7 -10 -10 -22 -10c-8 0 -19 1 -31 5c-20 27 -55 52 -55 52s45 -8 70 -2zM408 110c4 0 6 1 7 1
+c-2 4 -8 12 -26 22c-6 0 -13 -1 -20 -1c6 -6 12 -13 17 -19c8 -2 16 -3 22 -3z" />
+ <glyph glyph-name="ion-ios-flower" unicode="&#xf433;"
+d="M363 220c56 0 85 -12 85 -28s-29 -28 -85 -28c-29 0 -65 7 -93 14c-1 -3 -2 -6 -4 -9c25 -15 56 -36 76 -56c40 -40 53 -68 41 -80s-40 1 -80 41c-20 20 -41 51 -56 76c-3 -2 -7 -3 -10 -4c7 -28 15 -64 15 -93c0 -56 -12 -85 -28 -85s-28 29 -28 85c0 29 8 65 15 93
+c-3 1 -7 2 -10 4c-15 -25 -36 -56 -56 -76c-40 -40 -68 -53 -80 -41s1 40 41 80c20 20 51 41 76 56c-2 3 -3 6 -4 9c-28 -7 -64 -14 -93 -14c-56 0 -85 12 -85 28s29 28 85 28c29 0 65 -8 93 -15c1 3 2 7 4 10c-25 15 -56 35 -76 55c-40 40 -53 68 -41 80s40 0 80 -40
+c20 -20 41 -51 56 -76c3 2 6 3 9 4c-7 28 -14 64 -14 93c0 56 12 85 28 85s28 -29 28 -85c0 -29 -7 -65 -14 -93c3 -1 6 -2 9 -4c15 25 36 56 56 76c40 40 68 52 80 40s-1 -40 -41 -80c-20 -20 -51 -40 -76 -55c2 -3 3 -7 4 -10c28 7 64 15 93 15zM264 94c0 0 24 -34 49 -52
+c10 -34 7 -53 -5 -58c-2 -1 -3 -1 -5 -1c-11 0 -25 13 -37 35c5 35 -2 76 -2 76zM183 290c0 0 -27 35 -48 51c-10 35 -7 54 5 59c2 1 3 1 5 1c11 0 24 -12 37 -36c-6 -35 1 -75 1 -75zM126 151c0 0 -34 -24 -51 -48c-12 -4 -26 -6 -35 -6c-13 0 -21 4 -24 11
+c-5 11 7 25 34 41c35 -4 76 2 76 2zM322 232c0 0 33 25 51 49c13 4 26 5 35 5c13 0 21 -3 24 -10c5 -11 -7 -26 -34 -42c-35 5 -76 -2 -76 -2zM131 39c31 24 53 55 53 55s-7 -39 -3 -71c-15 -26 -28 -39 -39 -39c-2 0 -4 0 -6 1c-11 5 -13 24 -5 54zM317 344
+c-29 -21 -53 -55 -53 -55s8 48 3 71c13 25 28 39 39 39c2 0 4 0 6 -1c11 -5 13 -22 5 -54zM56 235c-28 15 -43 32 -38 44c3 7 10 11 22 11c8 0 21 -1 31 -5c18 -24 55 -53 55 -53s-40 7 -70 3zM392 149c30 -17 43 -33 38 -45c-3 -7 -10 -10 -22 -10c-8 0 -19 1 -31 5
+c-20 27 -55 52 -55 52s45 -8 70 -2z" />
+ <glyph glyph-name="ion-ios-folder-outline" unicode="&#xf434;"
+d="M425 352c13 0 23 -10 23 -23v-304c0 -14 -10 -25 -23 -25h-400c-13 0 -25 12 -25 25v336c0 13 11 23 25 23h112c8 0 12 -2 17 -7v0l23 -23c2 -2 3 -2 6 -2h242zM25 368c-4 0 -9 -3 -9 -7v-74c3 1 5 1 8 1h400c3 0 5 0 8 -1v42c0 4 -3 7 -7 7h-242c-7 0 -12 2 -17 7
+l-23 23c-2 2 -3 2 -6 2h-112zM432 25v239c0 4 -4 8 -8 8h-400c-4 0 -8 -4 -8 -8v-239c0 -4 5 -9 9 -9h400c4 0 7 5 7 9z" />
+ <glyph glyph-name="ion-ios-folder" unicode="&#xf435;"
+d="M440 272c4 0 8 -4 8 -8v-239c0 -14 -10 -25 -23 -25h-400c-13 0 -25 12 -25 25v239c0 4 4 8 8 8h432zM425 352c13 0 23 -10 23 -23v-42c-3 1 -5 1 -8 1h-432c-3 0 -5 0 -8 -1v74c0 13 11 23 25 23h112c8 0 12 -2 17 -7v0l23 -23c2 -2 3 -2 6 -2h242z" />
+ <glyph glyph-name="ion-ios-football-outline" unicode="&#xf436;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM249 6c3 1 5 1 8 2l24 64l-20 39v1h-106l-20 -39l25 -65c2 -1 5 -1 7 -2c12 -3 25 -5 38 -5c14 0 30 2 44 5zM41 284c-15 -27 -23 -57 -24 -89l43 37v0zM142 371
+c-36 -14 -68 -38 -90 -69l22 -64l5 -2l49 -23l71 60v58zM277 201l-70 58l-69 -58v-1l18 -72h104l18 72zM399 195c-1 32 -9 63 -24 90l-19 -53v0zM364 302c-22 31 -54 56 -90 69l-58 -40v-58l71 -60l54 24zM18 175c3 -34 15 -66 33 -92l70 -1l21 39l-20 77l-1 1l-49 22z
+M295 82l70 1c18 26 30 58 33 92l-54 46l-50 -23l-20 -77zM207 345l47 32c-15 4 -30 6 -46 6s-32 -2 -47 -6zM118 66l-54 1c20 -23 46 -42 75 -53l-20 50zM277 14c29 11 55 30 75 53l-56 -1l-2 -3z" />
+ <glyph glyph-name="ion-ios-football" unicode="&#xf437;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM249 6c3 1 5 1 8 2l24 64l-20 39v1h-106l-20 -39l25 -65c2 -1 5 -1 7 -2c12 -3 25 -5 38 -5c14 0 30 2 44 5zM142 371c-36 -14 -68 -38 -90 -69l22 -64l5 -2l49 -23l71 60v58z
+M364 302c-22 31 -54 56 -90 69l-58 -40v-58l71 -60l54 24zM18 175c3 -34 15 -66 33 -92l70 -1l21 39l-20 77l-1 1l-49 22zM295 82l70 1c18 26 30 58 33 92l-54 46l-50 -23l-20 -77z" />
+ <glyph glyph-name="ion-ios-game-controller-a-outline" unicode="&#xf438;"
+d="M163 208c3 0 5 -2 5 -5v-22c0 -3 -2 -5 -5 -5h-35v-35c0 -3 -3 -5 -6 -5h-21c-3 0 -5 2 -5 5v35h-35c-3 0 -5 3 -5 6v21c0 3 2 5 5 5h35v35c0 3 2 5 5 5h22c3 0 5 -2 5 -5v-35h35zM330 169c11 0 20 -8 20 -19s-9 -19 -20 -19s-19 8 -19 19s8 19 19 19zM288 211
+c11 0 19 -8 19 -19s-8 -19 -19 -19s-20 8 -20 19s9 19 20 19zM373 211c11 0 19 -8 19 -19s-8 -19 -19 -19s-20 8 -20 19s9 19 20 19zM330 253c11 0 20 -8 20 -19s-9 -20 -20 -20s-19 9 -19 20s8 19 19 19zM337 286h-226c-26 0 -49 -9 -67 -26s-28 -41 -28 -67s10 -51 28 -68
+s41 -27 67 -27h226c26 0 49 10 67 27s28 42 28 68s-10 50 -28 67s-41 26 -67 26zM337 302v0c61 0 111 -45 111 -109s-50 -111 -111 -111h-226c-61 0 -111 47 -111 111s50 109 111 109h226z" />
+ <glyph glyph-name="ion-ios-game-controller-a" unicode="&#xf439;"
+d="M337 302c61 0 111 -45 111 -109s-50 -111 -111 -111h-226c-61 0 -111 47 -111 111s50 109 111 109h226zM168 181v0v22c0 3 -2 5 -5 5h-35v35c0 3 -2 5 -5 5h-22c-3 0 -5 -2 -5 -5v-35h-35c-3 0 -5 -2 -5 -5v-21c0 -3 2 -6 5 -6h35v-35c0 -3 2 -5 5 -5h21c3 0 6 2 6 5v35
+h35c3 0 5 2 5 5zM288 173c11 0 19 8 19 19s-8 19 -19 19s-20 -8 -20 -19s9 -19 20 -19zM330 131c11 0 20 8 20 19s-9 19 -20 19s-19 -8 -19 -19s8 -19 19 -19zM330 214c11 0 20 9 20 20s-9 19 -20 19s-19 -8 -19 -19s8 -20 19 -20zM373 173c11 0 19 8 19 19s-8 19 -19 19
+s-20 -8 -20 -19s9 -19 20 -19z" />
+ <glyph glyph-name="ion-ios-game-controller-b-outline" unicode="&#xf43a;"
+d="M276 244c11 0 20 -9 20 -20s-9 -20 -20 -20s-20 9 -20 20s9 20 20 20zM320 200c11 0 20 -9 20 -20s-9 -20 -20 -20s-20 9 -20 20s9 20 20 20zM103 264c22 0 39 -18 39 -40s-17 -40 -39 -40s-39 18 -39 40s17 40 39 40zM103 205c11 0 19 8 19 19s-8 19 -19 19
+s-19 -8 -19 -19s8 -19 19 -19zM320 288c11 0 20 -9 20 -20s-9 -20 -20 -20s-20 9 -20 20s9 20 20 20zM364 244c11 0 20 -9 20 -20s-9 -20 -20 -20s-20 9 -20 20s9 20 20 20zM434 199c21 -88 18 -152 -7 -164c-4 -2 -9 -3 -13 -3c-22 0 -45 24 -68 52c-26 32 -32 33 -110 33
+h-24c-78 0 -84 -1 -110 -33c-23 -28 -46 -52 -68 -52c-4 0 -9 1 -13 3c-25 12 -28 76 -7 164s43 136 88 149c10 3 18 4 26 4c28 0 47 -15 96 -15s68 15 96 15c8 0 16 -1 26 -4c45 -13 67 -61 88 -149zM420 49c10 5 23 48 -1 146c-21 90 -43 128 -78 138c-8 2 -14 3 -21 3
+c-10 0 -19 -2 -30 -5c-16 -4 -36 -10 -66 -10s-50 6 -66 10c-11 3 -20 5 -30 5c-7 0 -13 -1 -21 -3c-35 -10 -57 -48 -78 -138c-24 -98 -11 -141 -1 -146c2 -1 4 -1 6 -1c6 0 14 4 23 12s19 18 32 34s24 28 44 34c17 5 38 5 79 5h24c41 0 62 0 79 -5c20 -6 31 -18 44 -34
+s23 -26 32 -34s17 -12 23 -12c2 0 4 0 6 1z" />
+ <glyph glyph-name="ion-ios-game-controller-b" unicode="&#xf43b;"
+d="M103 243c11 0 19 -8 19 -19s-8 -19 -19 -19s-19 8 -19 19s8 19 19 19zM434 199c21 -88 18 -152 -7 -164c-4 -2 -9 -3 -13 -3c-22 0 -45 24 -68 52c-26 32 -32 33 -110 33h-24c-78 0 -84 -1 -110 -33c-23 -28 -46 -52 -68 -52c-4 0 -9 1 -13 3c-25 12 -28 76 -7 164
+s43 136 88 149c10 3 18 4 26 4c28 0 47 -15 96 -15s68 15 96 15c8 0 16 -1 26 -4c45 -13 67 -61 88 -149zM103 184c22 0 39 18 39 40s-17 40 -39 40s-39 -18 -39 -40s17 -40 39 -40zM276 204c11 0 20 9 20 20s-9 20 -20 20s-20 -9 -20 -20s9 -20 20 -20zM320 160
+c11 0 20 9 20 20s-9 20 -20 20s-20 -9 -20 -20s9 -20 20 -20zM320 248c11 0 20 9 20 20s-9 20 -20 20s-20 -9 -20 -20s9 -20 20 -20zM364 204c11 0 20 9 20 20s-9 20 -20 20s-20 -9 -20 -20s9 -20 20 -20z" />
+ <glyph glyph-name="ion-ios-gear-outline" unicode="&#xf43c;" horiz-adv-x="384"
+d="M193 288c26 0 50 -10 68 -28s28 -42 28 -68s-10 -50 -28 -68s-42 -28 -68 -28s-50 10 -68 28s-28 42 -28 68s10 50 28 68s42 28 68 28zM193 112c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80zM138 365c-10 -3 -20 -7 -30 -12c2 -8 1 -16 0 -24
+c-2 -13 -8 -25 -18 -35c-12 -12 -29 -19 -46 -19c-4 0 -9 0 -13 1c-5 -10 -9 -20 -12 -30c7 -4 12 -10 17 -17c8 -11 12 -24 12 -37s-4 -26 -12 -37c-5 -7 -10 -13 -17 -17c3 -10 7 -20 12 -30c4 1 9 1 13 1c17 0 34 -7 46 -19c10 -10 16 -22 18 -35c1 -8 2 -16 0 -24
+c10 -5 20 -9 30 -12c4 7 10 12 17 17c11 8 24 12 37 12s26 -4 37 -12c7 -5 13 -10 17 -17c10 3 20 7 30 12c-2 8 -1 16 0 24c2 13 8 25 18 35c12 12 29 19 46 19c4 0 9 0 13 -1c5 10 9 20 12 30c-7 4 -12 10 -17 17c-8 11 -12 24 -12 37s4 26 12 37c5 7 10 13 17 17
+c-3 10 -7 20 -12 30c-4 -1 -9 -1 -13 -1c-17 0 -34 7 -46 19c-10 10 -16 22 -18 35c-1 8 -2 16 0 24c-10 5 -20 9 -30 12c-4 -7 -10 -12 -17 -17c-11 -8 -24 -12 -37 -12s-26 4 -37 12c-7 5 -13 10 -17 17zM238 384v0c20 -5 40 -13 57 -24c-8 -18 -5 -40 10 -55
+c10 -10 22 -14 35 -14c7 0 14 1 20 4c11 -17 19 -37 24 -57c-19 -7 -32 -25 -32 -46s14 -39 32 -46c-5 -20 -13 -40 -24 -57c-6 3 -13 4 -20 4c-13 0 -25 -4 -35 -14c-15 -15 -18 -37 -10 -55c-17 -11 -37 -19 -57 -24c-7 18 -25 32 -46 32s-39 -14 -46 -32
+c-20 5 -40 13 -57 24c8 18 5 40 -10 55c-10 10 -22 14 -35 14c-7 0 -14 -1 -20 -4c-11 17 -19 37 -24 57c18 7 32 25 32 46s-13 39 -32 46c5 20 13 40 24 57c6 -3 13 -4 20 -4c13 0 25 4 35 14c15 15 18 37 10 55c17 11 37 19 57 24c7 -19 25 -32 46 -32s39 13 46 32z" />
+ <glyph glyph-name="ion-ios-gear" unicode="&#xf43d;" horiz-adv-x="384"
+d="M352 192c0 -21 14 -39 32 -46c-5 -20 -13 -40 -24 -57c-6 3 -13 4 -20 4c-13 0 -25 -4 -35 -14c-15 -15 -18 -37 -10 -55c-17 -11 -37 -19 -57 -24c-7 18 -25 32 -46 32s-39 -14 -46 -32c-20 5 -40 13 -57 24c8 18 5 40 -10 55c-10 10 -22 14 -35 14c-7 0 -14 -1 -20 -4
+c-11 17 -19 37 -24 57c18 7 32 25 32 46s-13 39 -32 46c5 20 13 40 24 57c6 -3 13 -4 20 -4c13 0 25 4 35 14c15 15 18 37 10 55c17 11 37 19 57 24c7 -19 25 -32 46 -32s39 13 46 32c20 -5 40 -13 57 -24c-8 -18 -5 -40 10 -55c10 -10 22 -14 35 -14c7 0 14 1 20 4
+c11 -17 19 -37 24 -57c-19 -7 -32 -25 -32 -46zM193 112c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80z" />
+ <glyph glyph-name="ion-ios-glasses-outline" unicode="&#xf43e;"
+d="M433 201v0h15v-18h-15c-2 -22 -13 -43 -29 -58c-17 -16 -39 -25 -62 -25c-51 0 -92 41 -92 92v0v0c0 10 -12 22 -26 22s-26 -12 -26 -22v0v0c0 -51 -41 -92 -92 -92c-23 0 -45 9 -62 25c-16 15 -27 36 -29 58h-15v18h15c2 22 13 43 29 59c17 16 39 24 62 24
+c42 0 78 -27 89 -67c7 7 18 12 29 12s22 -5 29 -12c11 40 47 67 89 67c23 0 45 -9 62 -25c16 -15 27 -36 29 -58zM342 115c42 0 77 35 77 77s-35 77 -77 77s-77 -35 -77 -77s35 -77 77 -77zM106 115c42 0 77 35 77 77s-35 77 -77 77s-77 -35 -77 -77s35 -77 77 -77z" />
+ <glyph glyph-name="ion-ios-glasses" unicode="&#xf43f;"
+d="M433 201v0h15v-18h-15c-2 -22 -13 -43 -29 -58c-17 -16 -39 -25 -62 -25c-51 0 -92 41 -92 92v0v0c0 10 -12 22 -26 22s-26 -12 -26 -22v0v0c0 -51 -41 -92 -92 -92c-23 0 -45 9 -62 25c-16 15 -27 36 -29 58h-15v18h15c2 22 13 43 29 59c17 16 39 24 62 24
+c42 0 78 -27 89 -67c7 7 18 12 29 12s22 -5 29 -12c11 40 47 67 89 67c23 0 45 -9 62 -25c16 -15 27 -36 29 -58z" />
+ <glyph glyph-name="ion-ios-grid-view-outline" unicode="&#xf440;" horiz-adv-x="384"
+d="M384 256h-112v-128h112v-16h-112v-112h-16v112h-128v-112h-16v112h-112v16h112v128h-112v16h112v112h16v-112h128v112h16v-112h112v-16zM256 128v128h-128v-128h128z" />
+ <glyph glyph-name="ion-ios-grid-view" unicode="&#xf441;" horiz-adv-x="384"
+d="M128 128v128h128v-128h-128zM0 384h384v-384h-384v384zM352 256v16h-80v80h-16v-80h-128v80h-16v-80h-80v-16h80v-128h-80v-16h80v-80h16v80h128v-80h16v80h80v16h-80v128h80z" />
+ <glyph glyph-name="ion-ios-heart-outline" unicode="&#xf442;"
+d="M327 368c69 0 121 -43 121 -116c0 -31 -13 -71 -41 -105s-45 -52 -100 -88s-83 -43 -83 -43s-28 7 -83 43s-72 54 -100 88s-41 74 -41 105c0 73 52 116 121 116c39 0 82 -18 103 -53c21 35 64 53 103 53zM395 157c12 14 22 31 28 49c6 16 9 31 9 46c0 30 -10 56 -29 74
+c-9 8 -20 15 -33 19c-13 5 -28 7 -43 7c-38 0 -73 -18 -89 -45l-14 -23l-14 23c-16 27 -51 45 -89 45c-15 0 -30 -2 -43 -7c-13 -4 -24 -11 -33 -19c-19 -18 -29 -44 -29 -74c0 -15 3 -30 9 -46c6 -18 16 -35 28 -49c27 -32 42 -49 97 -85c40 -27 65 -36 74 -39
+c9 3 34 12 74 39c55 36 70 53 97 85z" />
+ <glyph glyph-name="ion-ios-heart" unicode="&#xf443;"
+d="M327 368c69 0 121 -43 121 -116c0 -31 -13 -71 -41 -105s-45 -52 -100 -88s-83 -43 -83 -43s-28 7 -83 43s-72 54 -100 88s-41 74 -41 105c0 73 52 116 121 116c39 0 82 -18 103 -53c21 35 64 53 103 53z" />
+ <glyph glyph-name="ion-ios-help-empty" unicode="&#xf444;" horiz-adv-x="128"
+d="M68 82c-9 0 -17 8 -17 17s8 17 17 17s17 -8 17 -17s-8 -17 -17 -17zM102 197c-23 -22 -22 -27 -23 -53h-19c1 28 7 43 30 64c11 10 19 24 19 39c0 24 -19 39 -42 39c-32 0 -49 -16 -48 -46h-19c0 42 25 62 68 62c33 0 60 -20 60 -54c0 -22 -11 -37 -26 -51z" />
+ <glyph glyph-name="ion-ios-help-outline" unicode="&#xf445;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM212 302c33 0 60 -21 60 -55c0 -22 -11 -36 -26 -50c-23 -23 -22 -27 -23 -53h-19
+c1 28 7 43 30 64c11 10 19 23 19 38c0 24 -19 40 -42 40c-32 0 -49 -16 -48 -46h-19c0 42 25 62 68 62zM212 116c9 0 17 -8 17 -17s-8 -17 -17 -17s-17 8 -17 17s8 17 17 17z" />
+ <glyph glyph-name="ion-ios-help" unicode="&#xf446;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM212 82c9 0 17 8 17 17s-8 17 -17 17s-17 -8 -17 -17s8 -17 17 -17zM246 197c15 14 26 29 26 51c0 34 -27 54 -60 54c-43 0 -68 -20 -68 -62h19c-1 30 16 46 48 46
+c23 0 42 -15 42 -39c0 -15 -8 -29 -19 -39c-23 -21 -29 -36 -30 -64h19c1 26 0 31 23 53z" />
+ <glyph glyph-name="ion-ios-home-outline" unicode="&#xf447;" horiz-adv-x="384"
+d="M192 336l160 -128v-208h-112v128h-96v-128h-112v208zM336 16v184l-144 116l-144 -116v-184h80v128h128v-128h80zM192 384l192 -153l-12 -12l-180 145l-180 -145l-12 12l32 25v96h64v-45zM80 294v42h-32v-67z" />
+ <glyph glyph-name="ion-ios-home" unicode="&#xf448;" horiz-adv-x="384"
+d="M192 336l160 -128v-208h-112v128h-96v-128h-112v208zM192 384l192 -153l-12 -12l-180 145l-180 -145l-12 12l32 25v96h64v-45z" />
+ <glyph glyph-name="ion-ios-infinite-outline" unicode="&#xf449;"
+d="M419 260c19 -19 29 -43 29 -68s-10 -49 -29 -68c-19 -18 -44 -28 -70 -28s-50 10 -69 28l-126 123c-15 15 -35 22 -56 22s-40 -7 -55 -22c-31 -30 -31 -80 0 -110c15 -15 34 -22 55 -22s41 7 56 22l43 42l13 -14l-42 -41c-19 -18 -44 -28 -70 -28s-50 10 -69 28
+c-19 19 -29 43 -29 68s10 49 29 68c19 18 43 28 69 28s51 -10 70 -28l126 -123c15 -15 34 -22 55 -22s41 7 56 22c31 30 31 80 0 110c-15 15 -35 22 -56 22s-40 -7 -55 -22l-43 -42l-13 14l42 41c19 18 44 28 70 28s50 -10 69 -28z" />
+ <glyph glyph-name="ion-ios-infinite" unicode="&#xf44a;" horiz-adv-x="464"
+d="M433 266c20 -20 31 -46 31 -74s-11 -54 -31 -74s-48 -30 -76 -30s-55 10 -75 30l-125 123c-13 13 -32 20 -51 20s-37 -7 -50 -20s-21 -31 -21 -49c0 -19 8 -36 21 -49s31 -20 50 -20s38 7 51 20l39 38l25 -25l-39 -38c-20 -20 -48 -30 -76 -30s-55 10 -75 30
+s-31 46 -31 74s11 54 31 74s47 30 75 30s56 -10 76 -30l125 -123c13 -13 31 -20 50 -20s38 7 51 20s20 31 20 49c0 19 -7 36 -20 49s-32 20 -51 20s-37 -7 -50 -20l-39 -38l-25 25l39 38c20 20 48 30 76 30s55 -10 75 -30z" />
+ <glyph glyph-name="ion-ios-information-empty" unicode="&#xf44b;" horiz-adv-x="64"
+d="M8 276c0 13 7 20 20 20s20 -7 20 -20s-7 -20 -20 -20s-20 7 -20 20zM48 104h16v-8h-64v8h16v120h-16v8h48v-128z" />
+ <glyph glyph-name="ion-ios-information-outline" unicode="&#xf44c;" horiz-adv-x="416"
+d="M184 276c0 13 7 20 20 20s20 -7 20 -20s-7 -20 -20 -20s-20 7 -20 20zM224 104h16v-8h-64v8h16v120h-16v8h48v-128zM208 400c57 0 106 -20 147 -61s61 -90 61 -147s-20 -106 -61 -147s-90 -61 -147 -61s-106 20 -147 61s-61 90 -61 147s20 106 61 147s90 61 147 61z
+M208 1c53 0 98 19 135 56s56 82 56 135s-19 98 -56 135s-82 56 -135 56s-98 -19 -135 -56s-56 -82 -56 -135s19 -98 56 -135s82 -56 135 -56z" />
+ <glyph glyph-name="ion-ios-information" unicode="&#xf44d;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM204 296c-11 0 -20 -9 -20 -20s9 -20 20 -20s20 9 20 20s-9 20 -20 20zM240 96v8h-16v128h-48v-8h16v-120h-16v-8h64z" />
+ <glyph glyph-name="ion-ios-ionic-outline" unicode="&#xf44e;" horiz-adv-x="416"
+d="M378 313c24 -34 38 -76 38 -121c0 -115 -92 -208 -207 -208s-209 93 -209 208s94 208 209 208c45 0 86 -14 120 -38c6 5 13 8 21 8c19 0 35 -16 35 -35c0 -8 -2 -16 -7 -22zM350 357c-12 0 -22 -10 -22 -22s10 -22 22 -22s22 10 22 22s-10 22 -22 22zM344 56
+c18 18 31 39 41 62c10 24 15 48 15 74s-5 51 -15 75c-5 13 -12 25 -20 36c-5 -2 -10 -3 -15 -3c-19 0 -35 16 -35 35c0 5 2 11 4 15c-11 8 -23 15 -36 20c-24 10 -49 14 -75 14s-51 -4 -75 -14c-23 -10 -43 -24 -61 -42s-31 -38 -41 -61c-10 -24 -15 -49 -15 -75
+s5 -50 15 -74c10 -23 23 -44 41 -62s38 -31 61 -41c24 -10 49 -15 75 -15s51 5 75 15c23 10 43 23 61 41zM208 288c53 0 96 -43 96 -96s-43 -96 -96 -96s-96 43 -96 96s43 96 96 96zM208 112c44 0 80 36 80 80s-36 80 -80 80s-79 -36 -79 -80s35 -80 79 -80z" />
+ <glyph glyph-name="ion-ios-keypad-outline" unicode="&#xf44f;" horiz-adv-x="384"
+d="M331 107c30 0 53 -24 53 -54s-23 -53 -53 -53s-54 23 -54 53s24 54 54 54zM331 16c21 0 37 16 37 37s-16 38 -37 38s-38 -17 -38 -38s17 -37 38 -37zM192 107c30 0 53 -24 53 -54s-23 -53 -53 -53s-53 23 -53 53s23 54 53 54zM192 16c21 0 37 16 37 37s-16 38 -37 38
+s-37 -17 -37 -38s16 -37 37 -37zM53 107c30 0 54 -24 54 -54s-24 -53 -54 -53s-53 23 -53 53s23 54 53 54zM53 16c21 0 38 16 38 37s-17 38 -38 38s-37 -17 -37 -38s16 -37 37 -37zM331 245c30 0 53 -23 53 -53s-23 -53 -53 -53s-54 23 -54 53s24 53 54 53zM331 155
+c21 0 37 16 37 37s-16 37 -37 37s-38 -16 -38 -37s17 -37 38 -37zM192 245c30 0 53 -23 53 -53s-23 -53 -53 -53s-53 23 -53 53s23 53 53 53zM192 155c21 0 37 16 37 37s-16 37 -37 37s-37 -16 -37 -37s16 -37 37 -37zM53 245c30 0 54 -23 54 -53s-24 -53 -54 -53
+s-53 23 -53 53s23 53 53 53zM53 155c21 0 38 16 38 37s-17 37 -38 37s-37 -16 -37 -37s16 -37 37 -37zM331 277c-30 0 -54 24 -54 54s24 53 54 53s53 -23 53 -53s-23 -54 -53 -54zM331 368c-21 0 -38 -16 -38 -37s17 -38 38 -38s37 17 37 38s-16 37 -37 37zM192 384
+c30 0 53 -23 53 -53s-23 -54 -53 -54s-53 24 -53 54s23 53 53 53zM192 293c21 0 37 17 37 38s-16 37 -37 37s-37 -16 -37 -37s16 -38 37 -38zM53 384c30 0 54 -23 54 -53s-24 -54 -54 -54s-53 24 -53 54s23 53 53 53zM53 293c21 0 38 17 38 38s-17 37 -38 37
+s-37 -16 -37 -37s16 -38 37 -38z" />
+ <glyph glyph-name="ion-ios-keypad" unicode="&#xf450;" horiz-adv-x="384"
+d="M331 107c30 0 53 -24 53 -54s-23 -53 -53 -53s-54 23 -54 53s24 54 54 54zM192 107c30 0 53 -24 53 -54s-23 -53 -53 -53s-53 23 -53 53s23 54 53 54zM53 107c30 0 54 -24 54 -54s-24 -53 -54 -53s-53 23 -53 53s23 54 53 54zM331 245c30 0 53 -23 53 -53
+s-23 -53 -53 -53s-54 23 -54 53s24 53 54 53zM192 245c30 0 53 -23 53 -53s-23 -53 -53 -53s-53 23 -53 53s23 53 53 53zM53 245c30 0 54 -23 54 -53s-24 -53 -54 -53s-53 23 -53 53s23 53 53 53zM331 277c-30 0 -54 24 -54 54s24 53 54 53s53 -23 53 -53s-23 -54 -53 -54z
+M192 384c30 0 53 -23 53 -53s-23 -54 -53 -54s-53 24 -53 54s23 53 53 53zM53 384c30 0 54 -23 54 -53s-24 -54 -54 -54s-53 24 -53 54s23 53 53 53z" />
+ <glyph glyph-name="ion-ios-lightbulb-outline" unicode="&#xf451;" horiz-adv-x="288"
+d="M288 275c0 -31 -13 -59 -30 -83v0c-11 -15 -22 -28 -32 -45c-22 -38 -18 -73 -18 -82v-1h-128v1c0 7 3 44 -19 82c-10 17 -20 30 -31 45v0c-17 24 -30 52 -30 83c0 78 66 141 144 141s144 -63 144 -141zM239 194l6 8c16 22 27 47 27 73c0 33 -16 65 -40 89s-55 36 -88 36
+s-64 -12 -88 -36s-40 -56 -40 -89c0 -26 11 -51 27 -73l19 -26v0c5 -6 9 -13 13 -21c17 -29 21 -58 21 -75h16v112l-32 64h17l31 -64v-112h32v112l31 64h17l-32 -64v-112h16c0 17 4 45 21 75c8 14 16 25 24 36c1 1 1 2 2 3zM112 -32v16h64v-16h-64zM96 0v16h96v-16h-96z
+M96 32v16h96v-16h-96z" />
+ <glyph glyph-name="ion-ios-lightbulb" unicode="&#xf452;" horiz-adv-x="288"
+d="M288 275c0 -31 -13 -59 -30 -83v0c-11 -15 -22 -28 -32 -45c-22 -38 -18 -73 -18 -82v-1h-32v128l32 64h-16l-32 -64v-128h-32v128l-31 64h-17l32 -64v-128h-32v1c0 7 3 44 -19 82c-10 17 -20 30 -31 45v0c-17 24 -30 52 -30 83c0 78 66 141 144 141s144 -63 144 -141z
+M112 -32v16h64v-16h-64zM96 0v16h96v-16h-96zM96 32v16h96v-16h-96z" />
+ <glyph glyph-name="ion-ios-list-outline" unicode="&#xf453;" horiz-adv-x="384"
+d="M368 368h-352v-352h352v352zM384 384v0v-384h-384v384h384zM128 280v16h192v-16h-192zM128 184v16h192v-16h-192zM128 88v16h192v-16h-192zM64 288c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16zM64 192c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16
+s-16 5 -16 16zM64 96c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16z" />
+ <glyph glyph-name="ion-ios-list" unicode="&#xf454;" horiz-adv-x="384"
+d="M0 384h384v-384h-384v384zM80 80c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM80 176c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM80 272c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM320 88v16h-192v-16h192zM320 184v16
+h-192v-16h192zM320 280v16h-192v-16h192z" />
+ <glyph glyph-name="ion-ios-location-outline" unicode="&#xf455;" horiz-adv-x="288"
+d="M144 400c-34 0 -67 -13 -91 -37s-37 -57 -37 -91c0 -43 24 -107 70 -186c22 -38 44 -72 58 -91c14 19 36 53 58 91c46 79 70 143 70 186c0 34 -13 67 -37 91s-57 37 -91 37zM144 416v0c80 0 144 -64 144 -144c0 -112 -144 -304 -144 -304s-144 192 -144 304
+c0 80 64 144 144 144zM144 336c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM144 225c26 0 47 21 47 47s-21 47 -47 47s-47 -21 -47 -47s21 -47 47 -47z" />
+ <glyph glyph-name="ion-ios-location" unicode="&#xf456;" horiz-adv-x="288"
+d="M144 416c80 0 144 -64 144 -144c0 -112 -144 -304 -144 -304s-144 192 -144 304c0 80 64 144 144 144zM144 225c26 0 47 21 47 47s-21 47 -47 47s-47 -21 -47 -47s21 -47 47 -47z" />
+ <glyph glyph-name="ion-ios-locked-outline" unicode="&#xf457;" horiz-adv-x="320"
+d="M264 224h56v-240h-320v240h56v72c0 57 47 104 104 104s104 -47 104 -104v-72zM72 296v-72h176v72c0 49 -39 88 -88 88s-88 -39 -88 -88zM304 0v208h-288v-208h288zM160 160c18 0 32 -14 32 -32c0 -15 -10 -27 -24 -31v-33h-16v33c-14 4 -24 16 -24 31c0 18 14 32 32 32z
+M160 112c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16z" />
+ <glyph glyph-name="ion-ios-locked" unicode="&#xf458;" horiz-adv-x="320"
+d="M264 224h56v-240h-320v240h56v72c0 57 47 104 104 104s104 -47 104 -104v-72zM168 97c14 4 24 16 24 31c0 18 -14 32 -32 32s-32 -14 -32 -32c0 -15 10 -27 24 -31v-33h16v33zM248 224v72c0 49 -39 88 -88 88s-88 -39 -88 -88v-72h176zM160 144c9 0 16 -7 16 -16
+s-7 -16 -16 -16s-16 7 -16 16s7 16 16 16z" />
+ <glyph glyph-name="ion-ios-loop-strong" unicode="&#xf459;" horiz-adv-x="512"
+d="M256 400c115 0 208 -93 208 -208c0 -14 -1 -28 -4 -42l-1 -4l-24 5l1 4c2 12 4 24 4 37c0 101 -83 184 -184 184c-66 0 -127 -36 -160 -94l-2 -3l-21 11l2 4c37 65 106 106 181 106zM416 102l2 3l21 -11l-2 -4c-37 -65 -106 -106 -181 -106c-115 0 -208 93 -208 208
+c0 14 1 28 4 42l1 4l24 -5l-1 -4c-2 -12 -4 -24 -4 -37c0 -101 83 -184 184 -184c66 0 127 36 160 94zM384 192h128l-64 -64zM0 192l64 64l64 -64h-128z" />
+ <glyph glyph-name="ion-ios-loop" unicode="&#xf45a;" horiz-adv-x="489"
+d="M478 192l11 -11l-52 -53l-53 53l10 11l43 -41zM449 192v0v0c0 -7 0 -14 -1 -21l-16 1c1 7 1 14 1 21c-1 103 -85 187 -188 187c-68 0 -131 -37 -164 -96l-14 8c36 64 104 104 178 104c112 0 203 -91 204 -202v0v-2zM409 100l14 -8c-36 -64 -104 -104 -178 -104
+c-111 0 -202 90 -204 200v0v3v1v0c0 7 0 14 1 21l16 -1c-1 -7 -1 -14 -1 -21c0 -103 85 -187 188 -187c68 0 131 37 164 96zM53 256l52 -53l-11 -11l-41 41l-42 -41l-11 11z" />
+ <glyph glyph-name="ion-ios-medical-outline" unicode="&#xf45b;" horiz-adv-x="364"
+d="M364 260l-118 -68l118 -68l-32 -56l-118 69v-137h-64v137l-118 -69l-32 56l118 68l-118 68l32 56l118 -69v137h64v-137l118 69zM342 118l-128 74l128 74l-16 28l-128 -74v148h-32v-148l-128 74l-16 -28l128 -74l-128 -74l16 -28l128 74v-148h32v148l128 -74z" />
+ <glyph glyph-name="ion-ios-medical" unicode="&#xf45c;" horiz-adv-x="364"
+d="M364 260l-118 -68l118 -68l-32 -56l-118 69v-137h-64v137l-118 -69l-32 56l118 68l-118 68l32 56l118 -69v137h64v-137l118 69z" />
+ <glyph glyph-name="ion-ios-medkit-outline" unicode="&#xf45d;" horiz-adv-x="416"
+d="M224 240h-32v-48v-16h-16h-48v-32h48h16v-16v-48h32v48v16h16h48v32h-48h-16v16v48zM240 256v0v-64h64v-64h-64v-64h-64v64h-64v64h64v64h64zM288 320h128v-320h-416v320h128v32c0 18 10 32 29 32h99c19 0 32 -14 32 -32v-32zM144 350v-30h128v30c0 10 -7 18 -17 18h-97
+c-11 0 -14 -8 -14 -18zM400 16v288h-384v-288h384z" />
+ <glyph glyph-name="ion-ios-medkit" unicode="&#xf45e;" horiz-adv-x="416"
+d="M224 176h16h48v-32h-48h-16v-16v-48h-32v48v16h-16h-48v32h48h16v16v48h32v-48v-16zM288 320h128v-320h-416v320h128v32c0 18 10 32 29 32h99c19 0 32 -14 32 -32v-32zM144 350v-30h128v30c0 10 -7 18 -17 18h-97c-11 0 -14 -8 -14 -18zM304 128v64h-64v64h-64v-64h-64
+v-64h64v-64h64v64h64z" />
+ <glyph glyph-name="ion-ios-mic-off" unicode="&#xf45f;" horiz-adv-x="280"
+d="M266 -32l-258 440l14 8l258 -440zM128 95c-44 0 -79 37 -79 83v118l113 -193c-10 -5 -22 -8 -34 -8zM207 178c0 -10 -2 -19 -5 -28l-136 234c14 20 37 32 62 32c44 0 79 -38 79 -84v-154zM256 176c0 -28 -9 -54 -24 -75l-10 17c11 17 17 36 17 58v80h17v-80zM139 49v0
+v-63h69v-18h-161v18h73v63c-67 5 -120 60 -120 127v80h19v-80c0 -60 50 -109 110 -109c17 0 34 4 48 11l9 -16c-14 -7 -30 -12 -47 -13z" />
+ <glyph glyph-name="ion-ios-mic-outline" unicode="&#xf460;" horiz-adv-x="256"
+d="M128 416c44 0 79 -38 79 -84v-154c0 -46 -35 -84 -79 -84s-79 38 -79 84v154c0 46 35 84 79 84zM191 178v154c0 37 -28 68 -63 68s-63 -31 -63 -68v-154c0 -37 28 -68 63 -68s63 31 63 68zM239 256h17v-80c0 -67 -51 -122 -117 -127v-63h69v-18h-161v18h73v63
+c-67 5 -120 60 -120 127v80h19v-80c0 -60 50 -109 110 -109s110 49 110 109v80z" />
+ <glyph glyph-name="ion-ios-mic" unicode="&#xf461;" horiz-adv-x="256"
+d="M128 94c-44 0 -79 38 -79 84v154c0 46 35 84 79 84s79 -38 79 -84v-154c0 -46 -35 -84 -79 -84zM239 256h17v-80c0 -67 -51 -122 -117 -127v-63h69v-18h-161v18h73v63c-67 5 -120 60 -120 127v80h19v-80c0 -60 50 -109 110 -109s110 49 110 109v80z" />
+ <glyph glyph-name="ion-ios-minus-empty" unicode="&#xf462;" horiz-adv-x="256"
+d="M256 183h-256v17h256v-17z" />
+ <glyph glyph-name="ion-ios-minus-outline" unicode="&#xf463;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM80 183v17h256v-17h-256z" />
+ <glyph glyph-name="ion-ios-minus" unicode="&#xf464;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM336 183v17h-256v-17h256z" />
+ <glyph glyph-name="ion-ios-monitor-outline" unicode="&#xf465;" horiz-adv-x="480"
+d="M480 64h-176v-16h64v-16h-257v16h64v16h-175v288h480v-288zM16 336v-256h448v256h-448z" />
+ <glyph glyph-name="ion-ios-monitor" unicode="&#xf466;" horiz-adv-x="480"
+d="M480 64h-176v-16h64v-16h-257v16h64v16h-175v288h480v-288zM16 336v-256h448v256h-448zM32 96v224h416v-224h-416z" />
+ <glyph glyph-name="ion-ios-moon-outline" unicode="&#xf467;" horiz-adv-x="216"
+d="M195 133c7 0 14 1 21 3c-4 -7 -7 -12 -12 -18c-21 -25 -53 -41 -88 -41c-64 0 -116 51 -116 115c0 52 34 96 81 111c7 2 14 3 22 4c-4 -6 -8 -12 -11 -18c-7 -14 -11 -30 -11 -47c0 -29 11 -56 32 -77s48 -32 77 -32h5zM116 93c25 0 48 9 65 24c-65 5 -116 59 -116 125
+c0 14 2 28 6 40c-33 -16 -55 -51 -55 -90c0 -55 45 -99 100 -99z" />
+ <glyph glyph-name="ion-ios-moon" unicode="&#xf468;" horiz-adv-x="216"
+d="M195 133c7 0 14 1 21 3c-4 -7 -7 -12 -12 -18c-21 -25 -53 -41 -88 -41c-64 0 -116 51 -116 115c0 52 34 96 81 111c7 2 14 3 22 4c-4 -6 -8 -12 -11 -18c-7 -14 -11 -30 -11 -47c0 -29 11 -56 32 -77s48 -32 77 -32h5z" />
+ <glyph glyph-name="ion-ios-more-outline" unicode="&#xf469;" horiz-adv-x="320"
+d="M160 210c-10 0 -18 -8 -18 -18s8 -18 18 -18s18 8 18 18s-8 18 -18 18zM160 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM32 210c-10 0 -18 -8 -18 -18s8 -18 18 -18s18 8 18 18s-8 18 -18 18zM32 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32
+s-32 14 -32 32s14 32 32 32zM288 210c-10 0 -18 -8 -18 -18s8 -18 18 -18s18 8 18 18s-8 18 -18 18zM288 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32z" />
+ <glyph glyph-name="ion-ios-more" unicode="&#xf46a;" horiz-adv-x="320"
+d="M160 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM32 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM288 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32z" />
+ <glyph glyph-name="ion-ios-musical-note" unicode="&#xf46b;" horiz-adv-x="192"
+d="M192 346v-1v-65c0 -3 -3 -6 -6 -5v0l-73 13v-192c0 -33 1 -80 -51 -82c-48 -2 -62 16 -62 41c0 19 9 39 51 41c22 1 37 1 45 1v273l90 -19l2 -1c2 0 3 -1 4 -3v0v-1v0z" />
+ <glyph glyph-name="ion-ios-musical-notes" unicode="&#xf46c;" horiz-adv-x="320"
+d="M320 128c0 -34 4 -80 -49 -82c-49 -2 -62 16 -62 41c0 20 9 39 52 41c23 1 34 2 43 2v160l-191 -32v-161c0 -34 3 -81 -50 -83c-49 -2 -63 17 -63 42c0 20 9 39 52 41c23 1 35 1 44 1v237l224 35v-242z" />
+ <glyph glyph-name="ion-ios-navigate-outline" unicode="&#xf46d;" horiz-adv-x="416"
+d="M208 384c-51 0 -99 -21 -135 -57s-57 -84 -57 -135s21 -99 57 -135s84 -57 135 -57s99 21 135 57s57 84 57 135s-21 99 -57 135s-84 57 -135 57zM208 400v0c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM304 288l-96 -224v128h-128z" />
+ <glyph glyph-name="ion-ios-navigate" unicode="&#xf46e;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 64l96 224l-224 -96h128v-128z" />
+ <glyph glyph-name="ion-ios-nutrition-outline" unicode="&#xf46f;" horiz-adv-x="384"
+d="M294 214v0c6 -6 10 -14 10 -23c0 -11 -5 -20 -13 -26v0s-51 -37 -106 -77l-38 31c-2 2 -4 3 -6 3c-1 0 -2 0 -3 -1v0c-2 -2 -2 -6 1 -10l29 -35l-115 -84c-6 -4 -13 -8 -21 -8c-18 0 -32 14 -32 32c0 7 1 13 4 18v0c2 2 17 25 37 57l21 -17c2 -2 4 -2 6 -2c1 0 3 0 4 1v0
+c2 2 1 6 -2 10l-19 23c27 43 60 96 84 134l36 -30c2 -2 4 -3 6 -3c1 0 2 1 3 2v0c2 2 2 5 -1 9l-33 40c11 18 19 29 19 29v0c6 10 15 16 27 16c9 0 18 -4 24 -10v0l78 -79v0v0zM282 178c4 3 6 8 6 13c0 4 -2 9 -5 12l-5 4v1l-69 69v0l-5 5c-3 3 -8 5 -12 5
+c-6 0 -10 -3 -13 -8l-5 -8c-2 -3 -5 -7 -8 -12l25 -30v0l1 -1c8 -10 8 -22 0 -30l-1 -1l-1 -1c-4 -3 -8 -5 -13 -5s-11 2 -16 6v1h-1l-21 18l-24 -39l-44 -70l12 -14v0v0c8 -10 8 -23 0 -31v0c-4 -4 -9 -6 -15 -6c-5 0 -11 2 -16 6v0v0l-7 5c-3 -5 -5 -9 -8 -13
+c-12 -19 -16 -26 -18 -29c-1 -3 -2 -6 -2 -9c0 -9 7 -16 16 -16c3 0 6 2 11 5l101 74l-18 22h-1v0c-8 10 -8 23 0 31v0v0v0c4 4 10 6 15 6s11 -2 16 -6v0h1l28 -24c49 36 93 68 96 70zM376 333l8 -14l-5 -3l-103 -60l-17 17l71 123l2 4l14 -8l-3 -4l-63 -111l91 53z" />
+ <glyph glyph-name="ion-ios-nutrition" unicode="&#xf470;" horiz-adv-x="384"
+d="M295 214v0c6 -6 9 -13 9 -22c0 -11 -5 -20 -13 -26v0s-51 -38 -106 -78l-38 32c-4 3 -8 3 -10 1v0c-2 -2 -2 -6 1 -10l29 -35l-114 -84c-6 -4 -13 -8 -21 -8c-18 0 -32 14 -32 32c0 7 2 13 5 18v0c1 2 16 25 36 57l20 -17c4 -3 8 -3 10 -1v0c2 2 2 6 -1 10l-20 23
+c27 43 60 96 84 134l36 -30c4 -3 8 -3 10 -1v0c2 2 2 6 -1 10l-33 40c11 18 18 29 18 29v0c6 10 16 16 28 16c9 0 18 -4 24 -10v0l78 -79l1 -1v0zM384 309l-103 -59l-28 29l70 121l28 -16l-50 -85l67 38z" />
+ <glyph glyph-name="ion-ios-paper-outline" unicode="&#xf471;" horiz-adv-x="384"
+d="M48 384h336v-353c0 -17 -14 -31 -31 -31h-322c-17 0 -31 14 -31 31v305h32v-16h-16v-289c0 -8 7 -15 15 -15h322c8 0 15 7 15 15v337h-304v-320h-16v320v16zM96 320v16h128v-16h-128zM96 240v16h240v-16h-240zM96 160v16h192v-16h-192zM96 80v16h240v-16h-240z" />
+ <glyph glyph-name="ion-ios-paper" unicode="&#xf472;" horiz-adv-x="384"
+d="M48 384h336v-353c0 -17 -14 -31 -31 -31h-322c-17 0 -31 14 -31 31v305h32v-288h16v288v32v16zM96 336v-16h128v16h-128zM96 176v-16h192v16h-192zM336 80v16h-240v-16h240zM336 240v16h-240v-16h240z" />
+ <glyph glyph-name="ion-ios-paperplane-outline" unicode="&#xf473;" horiz-adv-x="320"
+d="M0 198l320 154l-146 -320l-57 115zM132 152l41 -83l115 249zM286 320l-248 -121l83 -36z" />
+ <glyph glyph-name="ion-ios-paperplane" unicode="&#xf474;" horiz-adv-x="320"
+d="M0 198l320 154l-214 -200zM320 352l-146 -320l-52 104z" />
+ <glyph glyph-name="ion-ios-partlysunny-outline" unicode="&#xf475;" horiz-adv-x="384"
+d="M144 298v54h16v-54h-16zM0 192v16h55v-16h-55zM44 299l10 11l32 -32l-11 -11zM223 268l-11 11l32 32l11 -11zM56 96l-10 11l31 31l11 -11zM129 153c-4 -3 -8 -7 -12 -12c-23 12 -39 36 -39 63c0 39 32 71 71 71c21 0 40 -10 53 -25c-4 -2 -9 -4 -14 -8
+c-10 11 -23 17 -39 17c-30 0 -55 -25 -55 -55c0 -23 15 -43 35 -51zM235 208c-34 0 -63 -28 -63 -62v-12s1 -10 1 -10c-5 0 -12 -1 -14 -1c-19 -3 -33 -18 -33 -37c0 -10 3 -19 10 -26s16 -11 26 -11h157c27 0 49 22 49 49s-22 50 -49 50c-2 0 -4 -1 -6 -1l-14 -2l-3 14
+c-3 14 -11 26 -22 35s-25 14 -39 14zM235 224v0c37 0 68 -26 76 -61h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78z" />
+ <glyph glyph-name="ion-ios-partlysunny" unicode="&#xf476;" horiz-adv-x="384"
+d="M144 298v54h16v-54h-16zM0 192v16h55v-16h-55zM44 299l10 11l32 -32l-11 -11zM223 268l-11 11l32 32l11 -11zM56 96l-10 11l31 31l11 -11zM235 224v0c37 0 68 -26 76 -61h8c36 0 65 -29 65 -65s-29 -66 -65 -66h-157c-28 0 -52 24 -52 53c0 27 21 51 47 53v8
+c0 43 35 78 78 78zM201 252l1 -2v0c-31 -5 -62 -43 -62 -75c0 -2 1 -5 1 -7l-1 -1h-1c-11 -6 -18 -14 -22 -26v1v-1c-23 12 -39 36 -39 63c0 39 32 71 71 71c21 0 39 -9 52 -23z" />
+ <glyph glyph-name="ion-ios-pause-outline" unicode="&#xf477;" horiz-adv-x="256"
+d="M63 336h-47v-288h47v288zM79 352v0v-320h-79v320h79zM240 336h-47v-288h47v288zM256 352v0v-320h-79v320h79z" />
+ <glyph glyph-name="ion-ios-pause" unicode="&#xf478;" horiz-adv-x="256"
+d="M0 32v320h79v-320h-79zM177 32v320h79v-320h-79z" />
+ <glyph glyph-name="ion-ios-paw-outline" unicode="&#xf479;" horiz-adv-x="384"
+d="M380 252c6 -17 5 -38 -3 -57c-10 -25 -31 -43 -51 -43c-5 0 -10 1 -15 3c-22 10 -30 45 -17 79c10 28 31 46 51 46c5 0 10 -1 14 -3c10 -4 17 -13 21 -25zM362 202c6 15 7 31 2 44c-2 5 -5 12 -12 15c-2 1 -4 2 -7 2c-13 0 -28 -15 -36 -36c-9 -25 -6 -50 8 -56
+c2 -1 5 -1 8 -1c14 0 29 13 37 32zM90 234c13 -34 5 -69 -17 -79c-5 -2 -10 -3 -15 -3c-20 0 -41 18 -51 43c-8 19 -9 40 -3 57c4 12 11 21 21 25c4 2 9 3 14 3c20 0 41 -18 51 -46zM67 171c14 6 17 31 8 56c-8 21 -23 36 -36 36c-3 0 -5 -1 -7 -2c-7 -3 -10 -10 -12 -15
+c-5 -13 -4 -29 2 -44c8 -19 23 -32 37 -32c3 0 6 0 8 1zM134 237c-28 1 -52 32 -56 69c-2 23 4 45 16 60c8 10 19 17 31 18h6c27 -1 46 -29 50 -67c3 -24 -1 -48 -13 -63c-8 -9 -17 -15 -28 -16c-2 0 -4 -1 -6 -1zM107 356c-10 -12 -14 -29 -12 -48c3 -29 21 -53 40 -54h3
+c6 1 12 4 17 10c10 12 12 31 10 51c-3 29 -17 52 -35 53h-3c-9 -1 -16 -7 -20 -12zM192 208c64 0 128 -76 128 -149c0 -22 -11 -40 -22 -47c-13 -9 -23 -12 -42 -12c-23 0 -29 8 -40 15c-8 5 -14 10 -24 10s-16 -5 -24 -10c-11 -7 -17 -15 -40 -15c-19 0 -29 3 -42 12
+c-11 7 -22 25 -22 47c0 73 64 149 128 149zM290 27c6 4 14 16 14 32c0 30 -14 64 -36 91c-11 13 -23 24 -36 31c-13 8 -27 11 -40 11s-27 -3 -40 -11c-13 -7 -25 -18 -36 -31c-22 -27 -36 -61 -36 -91c0 -16 8 -28 14 -32c11 -7 18 -10 34 -10c14 0 19 4 26 9c2 1 4 3 6 4
+c9 6 18 12 32 12s23 -6 32 -12c2 -1 4 -3 6 -4c7 -5 12 -9 26 -9c16 0 23 3 34 10zM244 238c-11 1 -20 7 -28 16c-12 15 -16 39 -13 63c4 38 23 66 50 67h7c12 -1 22 -8 30 -18c12 -15 18 -37 16 -60c-4 -37 -28 -67 -56 -68h-6zM219 315c-2 -20 0 -39 10 -51
+c5 -6 11 -9 17 -10h3c19 1 38 25 41 54c2 19 -3 36 -13 48c-4 5 -10 11 -19 12h-4c-18 -1 -32 -24 -35 -53z" />
+ <glyph glyph-name="ion-ios-paw" unicode="&#xf47a;" horiz-adv-x="384"
+d="M380 252c6 -17 5 -38 -3 -57c-10 -25 -31 -43 -51 -43c-5 0 -10 1 -15 3c-22 10 -30 45 -17 79c10 28 31 46 51 46c5 0 10 -1 14 -3c10 -4 17 -13 21 -25zM90 234c13 -34 5 -69 -17 -79c-5 -2 -10 -3 -15 -3c-20 0 -41 18 -51 43c-8 19 -9 40 -3 57c4 12 11 21 21 25
+c4 2 9 3 14 3c20 0 41 -18 51 -46zM134 237c-28 1 -52 32 -56 69c-2 23 4 45 16 60c8 10 19 17 31 18h6c27 -1 46 -29 50 -67c3 -24 -1 -48 -13 -63c-8 -9 -17 -15 -28 -16c-2 0 -4 -1 -6 -1zM192 208c64 0 128 -76 128 -149c0 -22 -11 -40 -22 -47c-13 -9 -23 -12 -42 -12
+c-23 0 -29 8 -40 15c-8 5 -14 10 -24 10s-16 -5 -24 -10c-11 -7 -17 -15 -40 -15c-19 0 -29 3 -42 12c-11 7 -22 25 -22 47c0 73 64 149 128 149zM244 238c-11 1 -20 7 -28 16c-12 15 -16 39 -13 63c4 38 23 66 50 67h7c12 -1 22 -8 30 -18c12 -15 18 -37 16 -60
+c-4 -37 -28 -67 -56 -68h-6z" />
+ <glyph glyph-name="ion-ios-people-outline" unicode="&#xf47b;"
+d="M224 336v0v0zM317 113c11 -4 -11 4 0 0c28 -10 46 -35 46 -65h-28h-250c0 22 9 42 27 55c15 11 31 12 49 16c7 1 24 5 26 13s1 15 1 23c0 3 0 3 -2 5c-4 4 -6 9 -8 14c-2 8 -3 16 -4 24c-9 -2 -10 16 -12 21c-1 4 -7 24 3 21c-3 5 -4 13 -5 19c-2 13 -2 26 3 39
+c10 26 37 39 64 38c26 -1 51 -16 59 -42c4 -12 3 -26 1 -39c-1 -5 -2 -11 -4 -15c10 3 4 -20 3 -23c-2 -5 -3 -21 -12 -19c-1 -10 -2 -22 -7 -31c-1 -2 -7 -8 -7 -10v-11c0 -5 0 -10 2 -15s10 -7 14 -8c14 -5 27 -5 41 -10zM115 84c-6 -6 9 10 0 0c-6 -6 -10 -12 -12 -20h4
+h238c-4 15 -17 27 -30 33s-28 4 -41 9s-25 9 -28 25c-2 11 -2 22 -2 33c0 2 7 7 8 9c3 5 4 11 5 17c1 5 0 12 4 15c5 4 7 7 9 13c2 8 3 12 -1 19c-3 5 0 8 1 13c3 11 4 24 2 36c-8 37 -62 45 -86 19c-12 -13 -12 -31 -9 -47c1 -6 6 -14 3 -19c-1 -3 -5 -6 -4 -10
+c2 -5 2 -11 4 -16c2 -4 4 -6 7 -8s3 -6 3 -9c1 -7 2 -17 6 -23c3 -4 8 -6 8 -11v-21c-1 -8 -2 -18 -8 -24c-7 -6 -18 -10 -27 -12c-11 -3 -23 -3 -33 -7c-8 -3 -15 -8 -21 -14zM112 126c-15 -7 9 4 0 0c-9 -5 -18 -11 -25 -19c-1 -2 -6 -11 -7 -11h-25h-55c0 20 13 34 31 40
+c6 2 27 4 30 11c2 5 0 11 0 16c-10 -1 -24 1 -32 7c-2 2 3 9 4 12l3 12c1 9 1 19 1 28c0 16 -1 34 8 48c8 13 23 18 38 18c24 0 43 -13 47 -37c3 -16 1 -32 2 -48c0 -8 2 -16 5 -24c1 -2 5 -7 3 -9l-6 -3c-5 -2 -11 -3 -17 -4c-1 0 -8 0 -9 -1s0 -9 0 -11c0 -4 1 -6 5 -7
+c6 -2 19 -3 23 -8c2 -3 1 -5 -2 -5c-8 -1 -15 -1 -22 -5zM71 112c6 10 16 18 26 24c-9 9 -5 26 -4 37c0 2 0 5 2 5h8c6 0 11 1 17 2c-7 23 0 47 -5 70c-3 16 -15 23 -31 23c-17 0 -27 -9 -30 -25c-4 -22 3 -46 -4 -68c9 -1 17 -2 26 -2c1 0 1 -28 1 -29
+c-1 -12 -8 -18 -19 -22c-12 -4 -29 -3 -36 -15h49zM368 96c-2 8 -10 14 -16 19c-8 6 -18 13 -28 15c-3 1 -16 -1 -13 5c2 4 9 5 13 6s15 2 16 7c0 1 1 14 0 14c-6 0 -12 1 -18 2c-4 1 -7 2 -11 4c-6 3 -2 6 0 11c14 32 -10 88 32 105c15 6 34 5 48 -3c15 -9 20 -27 20 -44
+c0 -20 -4 -44 7 -62c2 -3 4 -4 0 -6c-2 -1 -4 -1 -6 -2l-12 -3s-9 -1 -13 -1c0 -4 -2 -13 1 -17c6 -7 21 -7 29 -10c18 -6 31 -20 31 -40h-80zM367 123c4 -4 -5 5 0 0s8 -11 15 -11h16h28c-7 12 -26 11 -38 16c-11 4 -16 12 -17 24c0 2 -1 27 1 27c9 0 18 0 26 1
+c-7 23 1 47 -4 70c-3 15 -15 23 -30 23c-17 0 -28 -8 -31 -25c-4 -23 2 -46 -5 -68c6 -2 12 -2 18 -2s8 1 9 -5c1 -11 5 -28 -4 -37c6 -4 11 -8 16 -13z" />
+ <glyph glyph-name="ion-ios-people" unicode="&#xf47c;"
+d="M317 113c11 -4 -11 4 0 0v0zM317 113c28 -10 46 -35 46 -65h-28h-250c0 22 9 42 27 55c15 11 31 12 49 16c7 1 24 5 26 13s1 15 1 23c0 3 0 3 -2 5c-4 4 -6 9 -8 14c-2 8 -3 16 -4 24c-9 -2 -10 16 -12 21c-1 4 -7 24 3 21c-3 5 -4 13 -5 19c-2 13 -2 26 3 39
+c10 26 37 39 64 38c26 -1 51 -16 59 -42c4 -12 3 -26 1 -39c-1 -5 -2 -11 -4 -15c10 3 4 -20 3 -23c-2 -5 -3 -21 -12 -19c-1 -10 -2 -22 -7 -31c-1 -2 -7 -8 -7 -10v-11c0 -5 0 -10 2 -15s10 -7 14 -8c14 -5 27 -5 41 -10zM111 126h2h-1h-1zM111 126c-9 -5 -17 -11 -24 -19
+c-1 -2 -6 -11 -7 -11h-25h-55c0 20 12 34 30 40c6 2 27 4 30 11c2 5 1 11 1 16c-10 -1 -24 1 -32 7c-2 2 3 9 4 12c1 4 2 7 3 11c1 9 1 19 1 28c0 16 -1 35 8 49c8 13 23 18 38 18c24 0 43 -13 47 -37c3 -16 1 -32 2 -48c0 -8 2 -16 5 -24c1 -2 5 -7 3 -9l-6 -3
+c-5 -2 -11 -3 -17 -4c-1 0 -8 0 -9 -1s0 -9 0 -11c0 -4 1 -6 5 -7c6 -2 19 -3 23 -8c2 -3 1 -5 -2 -5c-7 -1 -14 -2 -21 -5c2 1 2 2 -1 0c-8 -4 -4 -2 -1 0zM417 136c18 -6 31 -20 31 -40h-80c-2 8 -10 14 -16 19c-8 6 -18 13 -28 15c-3 1 -16 -1 -13 5c2 4 9 5 13 6
+s15 2 16 7c0 1 1 14 0 14c-6 0 -12 1 -18 2c-4 1 -7 2 -11 4c-6 3 -2 6 0 11c14 32 -10 88 32 105c15 6 34 5 48 -3c15 -9 20 -27 20 -44c0 -20 -4 -44 7 -62c2 -3 4 -4 0 -6c-2 -1 -4 -1 -6 -2l-12 -3s-9 -1 -13 -1c0 -4 -2 -13 1 -17c6 -7 21 -7 29 -10z" />
+ <glyph glyph-name="ion-ios-person-outline" unicode="&#xf47d;" horiz-adv-x="320"
+d="M106 246v0v0zM267 84c13 -5 53 -20 53 -52h-160h-160c0 32 40 47 53 52s31 6 43 9c7 2 17 5 20 9s1 41 1 41s-6 10 -9 18s-7 32 -7 32s-7 0 -9 12c-2 13 -6 17 -6 27c0 9 5 10 5 10v0s-4 13 -5 42c-1 34 25 68 74 68s75 -34 74 -68c-1 -29 -5 -42 -5 -42v0s5 -1 5 -10
+c0 -10 -3 -15 -6 -28c-2 -12 -9 -12 -9 -12s-4 -23 -7 -31s-9 -18 -9 -18s-2 -37 1 -41s13 -7 20 -9c12 -3 30 -4 43 -9zM160 48v0h137c-2 3 -4 6 -8 8c-7 5 -16 9 -27 13c-7 2 -17 4 -26 5c-6 1 -10 2 -15 3c-3 1 -21 5 -29 15c-4 5 -6 12 -6 32c0 10 1 20 1 20v4l2 4
+c1 2 6 9 8 15c2 5 5 19 6 28c0 0 0 -1 1 4s8 4 9 8s3 7 5 18s-5 12 -5 17c0 4 1 5 1 5v0c0 1 4 14 4 38c0 13 -5 26 -14 35c-11 11 -25 16 -44 16c-18 0 -34 -5 -45 -16c-9 -9 -13 -22 -13 -35c1 -24 4 -37 4 -38v0s1 -3 0 -6c-1 -5 -6 -5 -4 -16s4 -14 5 -18s8 -3 9 -8
+s1 -4 1 -4c1 -9 4 -23 6 -28c2 -6 6 -13 8 -15l2 -4v-4s1 -10 1 -20c0 -20 -2 -27 -6 -32c-8 -10 -26 -14 -29 -15c-5 -1 -10 -2 -16 -3c-9 -1 -18 -3 -25 -5c-11 -4 -20 -8 -27 -13c-4 -2 -6 -5 -8 -8h137z" />
+ <glyph glyph-name="ion-ios-person" unicode="&#xf47e;" horiz-adv-x="320"
+d="M267 84c13 -5 53 -20 53 -52h-160h-160c0 32 40 47 53 52s31 6 43 9c7 2 17 5 20 9s1 41 1 41s-6 10 -9 18s-7 32 -7 32s-7 0 -9 12c-2 13 -6 17 -6 27c0 9 5 10 5 10v0s-4 13 -5 42c-1 34 25 68 74 68s75 -34 74 -68c-1 -29 -5 -42 -5 -42v0s5 -1 5 -10
+c0 -10 -3 -15 -6 -28c-2 -12 -9 -12 -9 -12s-4 -23 -7 -31s-9 -18 -9 -18s-2 -37 1 -41s13 -7 20 -9c12 -3 30 -4 43 -9z" />
+ <glyph glyph-name="ion-ios-personadd-outline" unicode="&#xf47f;" horiz-adv-x="320"
+d="M320 295v-14h-25v-25h-14v25h-25v14h25v25h14v-25h25zM106 246v0v0zM267 84c13 -5 53 -20 53 -52h-160h-160c0 32 40 47 53 52s31 6 43 9c7 2 17 5 20 9s1 41 1 41s-6 10 -9 18s-7 32 -7 32s-7 0 -9 12c-2 13 -6 17 -6 27c0 9 5 10 5 10v0s-4 13 -5 42c-1 34 25 68 74 68
+s75 -34 74 -68c-1 -29 -5 -42 -5 -42v0s5 -1 5 -10c0 -10 -3 -15 -6 -28c-2 -12 -9 -12 -9 -12s-4 -23 -7 -31s-9 -18 -9 -18s-2 -37 1 -41s13 -7 20 -9c12 -3 30 -4 43 -9zM160 48v0h137c-2 3 -4 6 -8 8c-7 5 -16 9 -27 13c-7 2 -17 4 -26 5c-6 1 -10 2 -15 3
+c-3 1 -21 5 -29 15c-4 5 -6 12 -6 32c0 10 1 20 1 20v4l2 4c1 2 6 9 8 15c2 5 5 19 6 28c0 0 0 -1 1 4s8 4 9 8s3 7 5 18s-5 12 -5 17c0 4 1 5 1 5v0c0 1 4 14 4 38c0 13 -5 26 -14 35c-11 11 -25 16 -44 16c-18 0 -34 -5 -45 -16c-9 -9 -13 -22 -13 -35c1 -24 4 -37 4 -38
+v0s1 -3 0 -6c-1 -5 -6 -5 -4 -16s4 -14 5 -18s8 -3 9 -8s1 -4 1 -4c1 -9 4 -23 6 -28c2 -6 6 -13 8 -15l2 -4v-4s1 -10 1 -20c0 -20 -2 -27 -6 -32c-8 -10 -26 -14 -29 -15c-5 -1 -10 -2 -16 -3c-9 -1 -18 -3 -25 -5c-11 -4 -20 -8 -27 -13c-4 -2 -6 -5 -8 -8h137z" />
+ <glyph glyph-name="ion-ios-personadd" unicode="&#xf480;" horiz-adv-x="320"
+d="M320 295v-14h-25v-25h-14v25h-25v14h25v25h14v-25h25zM267 84c13 -5 53 -20 53 -52h-160h-160c0 32 40 47 53 52s31 6 43 9c7 2 17 5 20 9s1 41 1 41s-6 10 -9 18s-7 32 -7 32s-7 0 -9 12c-2 13 -6 17 -6 27c0 9 5 10 5 10v0s-4 13 -5 42c-1 34 25 68 74 68
+s75 -34 74 -68c-1 -29 -5 -42 -5 -42v0s5 -1 5 -10c0 -10 -3 -15 -6 -28c-2 -12 -9 -12 -9 -12s-4 -23 -7 -31s-9 -18 -9 -18s-2 -37 1 -41s13 -7 20 -9c12 -3 30 -4 43 -9z" />
+ <glyph glyph-name="ion-ios-photos-outline" unicode="&#xf481;"
+d="M64 320h384v-320h-384v320zM432 16v288h-352v-288h352zM0 384h384v-48h-16v32h-352v-288h32v-16h-48v320z" />
+ <glyph glyph-name="ion-ios-photos" unicode="&#xf482;"
+d="M64 320h384v-320h-384v320zM384 384v-48h-336v-272h-48v320h384z" />
+ <glyph glyph-name="ion-ios-pie-outline" unicode="&#xf483;"
+d="M256 367v0v-207v-12l-12 -4l-180 -45c6 -13 13 -25 21 -36c12 -16 25 -30 41 -42c33 -24 73 -37 114 -37c26 0 51 5 75 15c23 10 43 23 61 41s31 38 41 61c10 24 15 49 15 75c0 51 -20 100 -56 136c-32 32 -75 51 -120 55zM240 384v0c115 0 208 -93 208 -208
+s-93 -208 -208 -208c-92 0 -171 60 -198 143l198 49v224zM208 400c-31 -1 -60 -7 -85 -18c-24 -11 -44 -26 -61 -46c-29 -34 -46 -80 -46 -127v0v0c0 -13 3 -46 12 -70l180 46v215zM224 416v0v-244l-205 -52c-19 32 -19 89 -19 89c0 91 58 207 218 207h6z" />
+ <glyph glyph-name="ion-ios-pie" unicode="&#xf484;"
+d="M240 384v0c115 0 208 -93 208 -208s-93 -208 -208 -208c-92 0 -171 60 -198 143l198 49v224zM224 416v0v-244l-205 -52c-19 32 -19 89 -19 89c0 91 58 207 218 207h6z" />
+ <glyph glyph-name="ion-ios-pint-outline" unicode="&#xf485;" horiz-adv-x="224"
+d="M224 278c0 -98 -32 -101 -32 -181c0 -40 16 -71 16 -99c0 -27 -9 -30 -32 -30h-128c-23 0 -32 2 -32 29c0 28 16 60 16 100c0 80 -32 83 -32 181c0 21 1 89 19 125c4 9 13 13 32 13h122c19 0 28 -4 32 -13c18 -36 19 -104 19 -125zM34 396c-8 -16 -14 -43 -17 -76h190
+c-3 33 -9 60 -17 76c-1 2 -1 1 -2 2c-2 1 -6 2 -15 2h-122c-9 0 -13 -1 -15 -2c-1 -1 -1 0 -2 -2zM191 -15c0 1 1 5 1 13c0 11 -4 23 -7 37c-4 18 -9 39 -9 62c0 41 8 64 16 86c8 23 16 46 16 95c0 9 -1 18 -1 26h-190c0 -8 -1 -17 -1 -26c0 -49 8 -72 16 -95
+c8 -22 16 -45 16 -86c0 -23 -5 -44 -9 -62c-3 -14 -7 -26 -7 -37c0 -8 1 -12 1 -13c2 -1 7 -1 15 -1h128c8 0 13 0 15 1z" />
+ <glyph glyph-name="ion-ios-pint" unicode="&#xf486;" horiz-adv-x="224"
+d="M224 278c0 -98 -32 -101 -32 -181c0 -40 16 -71 16 -99c0 -27 -9 -30 -32 -30h-128c-23 0 -32 2 -32 29c0 28 16 60 16 100c0 80 -32 83 -32 181c0 21 1 89 19 125c4 9 13 13 32 13h122c19 0 28 -4 32 -13c18 -36 19 -104 19 -125zM34 396c-8 -16 -14 -43 -17 -76h190
+c-3 33 -9 60 -17 76c-1 2 -1 1 -2 2c-2 1 -6 2 -15 2h-122c-9 0 -13 -1 -15 -2c-1 -1 -1 0 -2 -2z" />
+ <glyph glyph-name="ion-ios-play-outline" unicode="&#xf487;" horiz-adv-x="256"
+d="M16 323v-262l210 131zM0 352v0l256 -160l-256 -160v320z" />
+ <glyph glyph-name="ion-ios-play" unicode="&#xf488;" horiz-adv-x="256"
+d="M0 352v0l256 -160l-256 -160v320z" />
+ <glyph glyph-name="ion-ios-plus-empty" unicode="&#xf489;" horiz-adv-x="256"
+d="M256 183h-120v-119h-17v119h-119v17h119v120h17v-120h120v-17z" />
+ <glyph glyph-name="ion-ios-plus-outline" unicode="&#xf48a;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191zM216 320v-120h120v-17h-120v-119h-17v119h-119v17h119v120h17z" />
+ <glyph glyph-name="ion-ios-plus" unicode="&#xf48b;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM336 183v17h-120v120h-17v-120h-119v-17h119v-119h17v119h120z" />
+ <glyph glyph-name="ion-ios-pricetag-outline" unicode="&#xf48c;" horiz-adv-x="416"
+d="M416 416v-160l-256 -288l-160 160l256 288h160zM400 264v136h-136l-240 -272l136 -136zM320 288c-18 0 -32 14 -32 32s14 32 32 32s32 -14 32 -32s-14 -32 -32 -32zM320 336c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16z" />
+ <glyph glyph-name="ion-ios-pricetag" unicode="&#xf48d;" horiz-adv-x="416"
+d="M304 320c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16zM256 416h160v-160l-256 -288l-160 160zM320 288c9 0 16 4 22 10s10 13 10 22s-4 16 -10 22s-13 10 -22 10s-16 -4 -22 -10s-10 -13 -10 -22s4 -16 10 -22s13 -10 22 -10z" />
+ <glyph glyph-name="ion-ios-pricetags-outline" unicode="&#xf48e;"
+d="M416 384h32v-144l-240 -272l-25 24l-23 -24l-160 160l256 288h160v-32zM160 -9l12 12l11 12l217 248v105v16v16h-137l-241 -272zM432 247v121h-16v-112l-221 -253l13 -12zM320 288c-18 0 -32 14 -32 32s14 32 32 32s32 -14 32 -32s-14 -32 -32 -32zM320 336
+c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16z" />
+ <glyph glyph-name="ion-ios-pricetags" unicode="&#xf48f;"
+d="M432 384h16v-144l-240 -272l-13 13l237 266v137zM256 416h160v-32v-16v-112l-221 -253l-12 -11l-23 -24l-160 160zM320 288c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM304 320c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16z" />
+ <glyph glyph-name="ion-ios-printer-outline" unicode="&#xf490;" horiz-adv-x="416"
+d="M384 336c18 0 32 -13 32 -31v-159c0 -18 -14 -32 -32 -32h-48v-114h-256v114h-48c-18 0 -32 14 -32 32v159c0 18 14 31 32 31h32v48h288v-48h32zM80 368v-32h256v32h-256zM320 16v192h-224v-192h224zM400 146v159c0 9 -7 15 -16 15v0h-352c-9 0 -16 -6 -16 -15v-159
+c0 -9 7 -16 16 -16h48v94h256v-94h48c9 0 16 7 16 16z" />
+ <glyph glyph-name="ion-ios-printer" unicode="&#xf491;" horiz-adv-x="416"
+d="M80 0v224h256v-224h-256zM80 -0v224h256v-224h-256zM64 352v32h288v-32h-288zM385 336c18 0 31 -14 31 -31v-158c0 -17 -13 -34 -31 -34h-33v126h-288v-126h-31c-18 0 -33 17 -33 34v158c0 17 15 31 33 31h352z" />
+ <glyph glyph-name="ion-ios-pulse-strong" unicode="&#xf492;" horiz-adv-x="480"
+d="M432 175c27 0 48 -20 48 -47s-21 -49 -48 -49c-21 0 -38 13 -45 31h-51c-7 0 -13 4 -15 11l-16 47l-50 -173c-2 -7 -8 -11 -15 -11h-1c-7 0 -14 5 -15 12l-51 308l-45 -182c-2 -7 -9 -12 -16 -12h-112v32h99l61 245c2 7 8 13 16 13s15 -7 16 -14l52 -314l45 155
+c2 7 8 11 15 11v0c7 0 13 -4 15 -11l29 -85h38c6 19 25 33 46 33z" />
+ <glyph glyph-name="ion-ios-pulse" unicode="&#xf493;"
+d="M416 160c18 0 32 -14 32 -32s-14 -32 -32 -32c-15 0 -27 10 -31 23h-65c-3 0 -7 2 -8 5l-23 72l-57 -198c-1 -3 -4 -6 -8 -6v0c-4 0 -7 3 -8 7l-58 346l-54 -220c-1 -4 -4 -6 -8 -6h-96v16h90l62 251c1 4 4 6 8 6s7 -3 8 -7l58 -349l54 190c1 3 4 5 8 5s7 -2 8 -5l30 -91
+h59c3 14 16 25 31 25z" />
+ <glyph glyph-name="ion-ios-rainy-outline" unicode="&#xf494;" horiz-adv-x="288"
+d="M220 269c38 0 68 -33 68 -71c0 -29 -19 -56 -45 -66l-55 -80c-2 -2 -5 -4 -8 -4c-5 0 -8 3 -8 8c0 2 1 4 2 6l46 66v0h-35l-31 -44c-2 -2 -4 -4 -7 -4c-5 0 -9 3 -9 8c0 2 1 3 2 5l25 35h-37l-53 -76c-2 -2 -4 -4 -7 -4c-5 0 -9 3 -9 8c0 2 2 4 3 6l46 66h-36l-32 -44
+c-2 -2 -4 -4 -7 -4c-5 0 -8 3 -8 8c0 2 1 4 2 6l25 34c-29 2 -52 27 -52 56c0 28 22 58 50 60c0 3 -1 5 -1 8c0 46 31 84 82 84c45 0 73 -31 81 -68c3 0 5 1 8 1zM220 146c28 0 52 24 52 52s-24 54 -52 54h-6l-15 -2l-3 15c-3 14 -11 31 -23 40c-12 10 -26 14 -41 14
+c-36 0 -66 -31 -66 -67v-12v-10c-6 0 -12 -2 -14 -2c-20 -3 -35 -23 -35 -43c0 -10 4 -20 11 -27s16 -12 26 -12h124v0v0h42z" />
+ <glyph glyph-name="ion-ios-rainy" unicode="&#xf495;" horiz-adv-x="288"
+d="M220 269c38 0 68 -33 68 -71c0 -29 -19 -56 -45 -66l-55 -80c-2 -2 -5 -4 -8 -4c-5 0 -8 3 -8 8c0 2 1 4 2 6l46 66v0h-35l-31 -44c-2 -2 -4 -4 -7 -4c-5 0 -9 3 -9 8c0 2 1 3 2 5l25 35h-37l-53 -76c-2 -2 -4 -4 -7 -4c-5 0 -9 3 -9 8c0 2 2 4 3 6l46 66h-36l-32 -44
+c-2 -2 -4 -4 -7 -4c-5 0 -8 3 -8 8c0 2 1 4 2 6l25 34c-29 2 -52 27 -52 56c0 28 22 58 50 60c0 3 -1 5 -1 8c0 46 31 84 82 84c45 0 73 -31 81 -68c3 0 5 1 8 1z" />
+ <glyph glyph-name="ion-ios-recording-outline" unicode="&#xf496;" horiz-adv-x="480"
+d="M370 304c61 0 110 -50 110 -112s-49 -112 -110 -112h-260c-61 0 -110 50 -110 112s49 112 110 112s110 -50 110 -112c0 -40 -21 -75 -53 -95h146c-32 20 -53 55 -53 95c0 62 49 112 110 112zM16 192c0 -53 42 -95 94 -95s93 42 93 95s-41 95 -93 95s-94 -42 -94 -95z
+M370 97c52 0 94 42 94 95s-42 95 -94 95s-93 -42 -93 -95s41 -95 93 -95zM368 240c-26 0 -48 -22 -48 -48s22 -48 48 -48s48 22 48 48s-22 48 -48 48zM368 256v0c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM112 240c-26 0 -48 -22 -48 -48
+s22 -48 48 -48s48 22 48 48s-22 48 -48 48zM112 256v0c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64z" />
+ <glyph glyph-name="ion-ios-recording" unicode="&#xf497;" horiz-adv-x="480"
+d="M370 304c61 0 110 -50 110 -112s-49 -112 -110 -112h-260c-61 0 -110 50 -110 112s49 112 110 112s110 -50 110 -112c0 -40 -21 -76 -53 -95h146c-32 19 -53 55 -53 95c0 62 49 112 110 112zM112 128c35 0 64 29 64 64s-29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64z
+M368 128c35 0 64 29 64 64s-29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64zM368 240c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48zM112 240c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48z" />
+ <glyph glyph-name="ion-ios-redo-outline" unicode="&#xf498;" horiz-adv-x="384"
+d="M0 48v32c0 17 -3 83 49 136c35 36 80 53 143 56v80l192 -128l-192 -128v80c-40 -1 -63 -9 -87 -20c-31 -14 -55 -44 -75 -77l-20 -31h-10zM208 256c-201 0 -192 -169 -192 -169c48 81 101 105 192 105v-65l148 97l-148 97v-65z" />
+ <glyph glyph-name="ion-ios-redo" unicode="&#xf499;" horiz-adv-x="384"
+d="M0 48v32c0 17 -3 83 49 136c35 36 80 53 143 56v80l192 -128l-192 -128v80c-40 -1 -63 -9 -87 -20c-31 -14 -55 -44 -75 -77l-20 -31h-10z" />
+ <glyph glyph-name="ion-ios-refresh-empty" unicode="&#xf49a;" horiz-adv-x="256"
+d="M128 64c-71 0 -128 57 -128 128s57 128 128 128v44l96 -64l-96 -56v56c-60 0 -108 -48 -108 -108s48 -108 108 -108s108 48 108 108h20c0 -71 -57 -128 -128 -128z" />
+ <glyph glyph-name="ion-ios-refresh-outline" unicode="&#xf49b;" horiz-adv-x="416"
+d="M316 192v0h20c0 -71 -57 -128 -128 -128s-128 57 -128 128s57 128 128 128v44l96 -64l-96 -56v56c-60 0 -108 -48 -108 -108s48 -108 108 -108s108 48 108 108zM208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 1
+c105 0 191 86 191 191s-86 191 -191 191s-191 -86 -191 -191s86 -191 191 -191z" />
+ <glyph glyph-name="ion-ios-refresh" unicode="&#xf49c;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM208 64c71 0 128 57 128 128h-20c0 -60 -48 -108 -108 -108s-108 48 -108 108s48 108 108 108v-56l96 56l-96 64v-44c-71 0 -128 -57 -128 -128s57 -128 128 -128z" />
+ <glyph glyph-name="ion-ios-reload" unicode="&#xf49d;"
+d="M192 384c106 0 192 -86 192 -192l55 53l9 -9l-70 -68l-67 68l9 9l51 -52c0 98 -80 178 -179 178s-179 -80 -179 -179s80 -179 179 -179c79 0 146 50 170 121l12 -3c-26 -76 -97 -131 -182 -131c-106 0 -192 86 -192 192s86 192 192 192z" />
+ <glyph glyph-name="ion-ios-reverse-camera-outline" unicode="&#xf49e;" horiz-adv-x="384"
+d="M238 129l2 2l11 -12l-2 -2c-16 -14 -36 -21 -57 -21c-45 0 -82 36 -87 78h-30l38 50l39 -50h-31c5 -33 35 -62 71 -62c17 0 33 6 46 17zM252 249c16 -14 25 -37 27 -57h30l-38 -51l-39 51h31c-5 35 -35 64 -71 64c-17 0 -33 -6 -46 -17l-2 -2l-11 12l2 2
+c16 14 36 21 57 21c22 0 44 -8 60 -23zM354 288c18 0 30 -14 30 -31v-176c0 -17 -12 -33 -30 -33h-320c-18 0 -34 16 -34 33v176c0 17 16 31 34 31h13v16h34v-16h13c32 36 43 48 55 48h88c12 0 23 -12 55 -48h62zM368 81v176c0 9 -5 15 -14 15h-62h-6s-4 1 -6 3s-6 8 -9 11
+c-12 13 -21 24 -27 30c-5 5 -7 4 -7 4h-88s-1 0 -6 -4c-6 -5 -15 -14 -26 -27c-3 -4 -8 -11 -11 -14s-4 -3 -6 -3h-6h-60c-9 0 -18 -7 -18 -15v-176c0 -9 9 -17 18 -17h320c8 0 14 8 14 17z" />
+ <glyph glyph-name="ion-ios-reverse-camera" unicode="&#xf49f;" horiz-adv-x="384"
+d="M354 288c18 0 30 -14 30 -31v-176c0 -17 -12 -33 -30 -33h-320c-18 0 -34 16 -34 33v176c0 17 16 31 34 31h13v16h34v-16h13c32 36 43 48 55 48h88c12 0 23 -12 55 -48h62zM249 117l2 2l-11 12l-2 -2c-13 -11 -29 -17 -46 -17c-36 0 -66 29 -71 62h31l-39 50l-38 -50h30
+c5 -42 42 -78 87 -78c21 0 41 7 57 21zM271 141l38 51h-30c-2 20 -11 43 -27 57c-16 15 -38 23 -60 23c-21 0 -41 -7 -57 -21l-2 -2l11 -12l2 2c13 11 29 17 46 17c36 0 66 -29 71 -64h-31z" />
+ <glyph glyph-name="ion-ios-rewind-outline" unicode="&#xf4a0;"
+d="M432 293l-184 -101l184 -101v202zM208 292v0l-176 -100l176 -100v95v27v78zM224 320v0v-123l224 123v-256l-224 123v-123l-224 128z" />
+ <glyph glyph-name="ion-ios-rewind" unicode="&#xf4a1;"
+d="M224 320v0v-123l224 123v-256l-224 123v-123l-224 128z" />
+ <glyph glyph-name="ion-ios-rose-outline" unicode="&#xf4a2;" horiz-adv-x="320"
+d="M284 295c-4 -1 -9 -3 -13 -4c-37 -11 -71 -24 -103 -39c-17 -8 -24 -12 -44 -24l-7 -4c-31 -18 -50 -33 -63 -51c-15 -21 -22 -45 -22 -77c0 -16 3 -30 9 -44c6 -13 14 -26 25 -36c23 -21 55 -32 94 -32s71 11 94 32c11 10 19 23 25 36c6 14 9 28 9 44c0 20 -5 40 -11 60
+c-11 40 -23 83 7 139zM320 320v0c-77 -96 -16 -151 -16 -224s-56 -128 -144 -128s-144 55 -144 128s35 109 93 142c25 14 33 19 52 28c30 14 65 28 105 40c17 5 35 10 54 14zM38 325c14 -28 18 -57 19 -83c9 7 20 13 30 20c7 4 14 9 21 13c5 3 10 6 16 9c-5 4 -11 7 -17 11
+c-22 13 -48 23 -69 30zM0 352v0s66 -15 115 -43c15 -8 28 -18 37 -29c-12 -6 -24 -12 -36 -19c-7 -4 -14 -8 -20 -12c-25 -16 -44 -31 -57 -42c5 41 2 98 -39 145zM249 367c-8 -1 -20 -2 -35 -7c-25 -8 -47 -20 -64 -36c8 -6 15 -12 21 -18c29 12 65 26 95 34
+c-5 10 -12 20 -17 27zM256 384v0s26 -32 32 -55c-33 -8 -84 -25 -121 -42l-3 3c-9 11 -22 22 -39 32c52 60 131 62 131 62zM85 394c-6 -10 -10 -20 -14 -28c12 -4 22 -10 36 -17c4 5 9 10 14 14c-13 15 -27 25 -36 31zM80 416v0s35 -16 64 -56c-12 -9 -23 -20 -33 -31
+c-26 13 -40 21 -61 27c5 15 15 38 30 60z" />
+ <glyph glyph-name="ion-ios-rose" unicode="&#xf4a3;" horiz-adv-x="320"
+d="M320 320v0c-77 -96 -16 -151 -16 -224s-56 -128 -144 -128s-144 55 -144 128s35 109 93 142c25 14 33 19 52 28c30 14 65 28 105 40c17 5 35 10 54 14zM0 352v0s66 -15 115 -43c15 -8 28 -18 37 -29c-12 -6 -24 -12 -36 -19c-7 -4 -14 -8 -20 -12
+c-25 -16 -44 -31 -57 -42c5 41 2 98 -39 145zM256 384v0s26 -32 32 -55c-33 -8 -84 -25 -121 -42l-3 3c-9 11 -22 22 -39 32c52 60 131 62 131 62zM80 416v0s35 -16 64 -56c-12 -9 -23 -20 -33 -31c-26 13 -40 21 -61 27c5 15 15 38 30 60z" />
+ <glyph glyph-name="ion-ios-search-strong" unicode="&#xf4a4;" horiz-adv-x="384"
+d="M280 150l-4 -7l108 -109l-34 -34l-108 109l-7 -5c-24 -15 -53 -25 -83 -25c-84 0 -152 69 -152 153s68 152 152 152s152 -68 152 -152c0 -30 -9 -58 -24 -82zM237 317c-23 23 -53 35 -85 35s-62 -12 -85 -35s-35 -53 -35 -85s12 -62 35 -85s53 -35 85 -35s62 12 85 35
+s36 53 36 85s-13 62 -36 85z" />
+ <glyph glyph-name="ion-ios-search" unicode="&#xf4a5;" horiz-adv-x="384"
+d="M384 23l-23 -23l-113 113c-26 -21 -60 -33 -96 -33c-84 0 -152 68 -152 152s68 152 152 152s152 -68 152 -152c0 -36 -12 -69 -33 -95zM56 135c26 -26 60 -39 96 -39s70 14 96 40s40 60 40 96s-14 70 -40 96s-60 40 -96 40s-70 -14 -96 -40s-40 -60 -40 -96
+s14 -71 40 -97z" />
+ <glyph glyph-name="ion-ios-settings-strong" unicode="&#xf4a6;"
+d="M0 72h283c6 14 21 24 37 24s31 -10 37 -24h91v-32h-91c-6 -14 -21 -24 -37 -24s-31 10 -37 24h-283zM0 208h91c6 14 21 24 37 24s31 -10 37 -24h283v-32h-283c-6 -14 -21 -24 -37 -24s-31 10 -37 24h-91zM0 344h283c6 14 21 24 37 24s31 -10 37 -24h91v-32h-91
+c-6 -14 -21 -24 -37 -24s-31 10 -37 24h-283z" />
+ <glyph glyph-name="ion-ios-settings" unicode="&#xf4a7;"
+d="M320 344c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16zM320 360v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM320 72c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16zM320 88v0c18 0 32 -14 32 -32s-14 -32 -32 -32
+s-32 14 -32 32s14 32 32 32zM128 208c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16zM128 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM175 200h273v-16h-273c0 3 1 5 1 8s-1 5 -1 8zM80 192c0 -3 1 -5 1 -8h-81v16h81
+c0 -3 -1 -5 -1 -8zM367 64h81v-16h-81c0 3 1 5 1 8s-1 5 -1 8zM272 56c0 -3 1 -5 1 -8h-273v16h273c0 -3 -1 -5 -1 -8zM367 336h81v-16h-81c0 3 1 5 1 8s-1 5 -1 8zM273 336c0 -3 -1 -5 -1 -8s1 -5 1 -8h-273v16h273z" />
+ <glyph glyph-name="ion-ios-shuffle-strong" unicode="&#xf4a8;" horiz-adv-x="384"
+d="M301 296c-85 0 -119 -64 -152 -126c-1 -3 -3 -5 -4 -8l-1 -1c-2 -3 -2 -5 -4 -8c-21 -38 -43 -68 -68 -83c-15 -9 -34 -18 -72 -18v32c45 0 76 18 112 84c2 3 2 6 4 9h1c1 2 3 4 4 7c34 64 76 144 180 144h15l-52 43l21 25l99 -84l-99 -82l-21 24l51 42h-14zM285 154
+l99 -82l-99 -84l-21 25l52 43h-15c-78 0 -122 45 -153 95l18 33c29 -51 64 -96 135 -96h14l-51 42zM112 216c-36 66 -67 84 -112 84v32c38 0 57 -9 72 -18c25 -15 47 -44 67 -81c-7 -11 -13 -22 -19 -33c-1 2 -2 5 -3 7h-1c-2 3 -2 6 -4 9z" />
+ <glyph glyph-name="ion-ios-shuffle" unicode="&#xf4a9;" horiz-adv-x="384"
+d="M298 241l-10 12l62 51h-46c-93 0 -129 -75 -164 -139c-2 -3 -3 -6 -5 -9c-20 -37 -41 -61 -65 -75c-14 -8 -33 -17 -70 -17v16c48 0 83 14 121 84c2 3 3 6 5 9c35 65 75 147 178 147h46l-62 52l10 12l86 -72zM135 228c0 -1 1 -2 1 -3c-3 -5 -6 -11 -9 -16c0 1 -1 1 -1 2
+c-2 3 -3 6 -5 9c-38 70 -73 84 -121 84v16c37 0 56 -9 70 -17c24 -14 45 -38 65 -75zM298 143l86 -71l-86 -72l-10 12l62 52h-46c-76 0 -118 45 -149 95c1 2 2 5 3 7c2 3 4 7 6 10c30 -50 67 -96 140 -96h46l-62 51z" />
+ <glyph glyph-name="ion-ios-skipbackward-outline" unicode="&#xf4aa;" horiz-adv-x="320"
+d="M0 352h79v-142l241 142v-320l-241 142v-142h-79v320zM80 192l7 -4l217 -128v264v0l-217 -128zM16 336v-288h47v126v8v28v126h-47z" />
+ <glyph glyph-name="ion-ios-skipbackward" unicode="&#xf4ab;" horiz-adv-x="320"
+d="M0 352h79v-142l241 142v-320l-241 142v-142h-79v320z" />
+ <glyph glyph-name="ion-ios-skipforward-outline" unicode="&#xf4ac;" horiz-adv-x="320"
+d="M241 352h79v-320h-79v142l-241 -142v320l241 -142v142zM233 188l7 4l-7 4l-217 128v0v-264zM304 48v288h-47v-126v-28v-8v-126h47z" />
+ <glyph glyph-name="ion-ios-skipforward" unicode="&#xf4ad;" horiz-adv-x="320"
+d="M241 352h79v-320h-79v142l-241 -142v320l241 -142v142z" />
+ <glyph glyph-name="ion-ios-snowy" unicode="&#xf4ae;" horiz-adv-x="256"
+d="M252 131c4 -2 5 -7 3 -11s-7 -5 -11 -3l-29 17c-2 -8 -2 -16 0 -24c1 -4 -3 -9 -7 -10s-8 2 -9 6c-2 12 -3 24 1 36l-64 36v-73c11 -3 22 -8 31 -16c3 -3 4 -8 1 -11s-8 -4 -11 -1c-6 5 -13 10 -21 12v-33c0 -4 -4 -8 -8 -8s-8 4 -8 8v33c-8 -2 -15 -7 -21 -12
+c-3 -3 -8 -2 -11 1s-3 8 0 11c9 8 20 13 32 16v73l-65 -36c4 -12 4 -23 2 -35c-1 -4 -5 -8 -9 -7s-8 6 -7 10c2 8 2 16 0 24l-29 -17c-4 -2 -9 -1 -11 3s-1 9 3 11l29 16c-6 6 -13 10 -21 13c-4 1 -6 6 -5 10c2 4 6 6 10 5c12 -4 22 -11 30 -19l65 36l-65 37
+c-8 -9 -18 -15 -30 -19c-4 -1 -9 0 -10 4s1 10 5 11c8 3 15 6 21 12l-29 16c-4 2 -5 7 -3 11s7 5 11 3l29 -16c2 8 2 15 0 23c-1 4 3 9 7 10s8 -2 9 -6c2 -12 1 -25 -2 -36l65 -36v73c-12 3 -23 8 -32 16c-3 3 -3 8 0 11s8 4 11 1c6 -5 13 -10 21 -12v33c0 4 4 8 8 8
+s8 -4 8 -8v-33c8 2 15 7 21 12c3 3 8 2 11 -1s2 -8 -1 -11c-9 -8 -20 -13 -31 -16v-73l64 36c-3 11 -4 24 -2 36c1 4 6 7 10 6s7 -6 6 -10c-2 -8 -1 -15 1 -23l29 16c4 2 9 1 11 -3s1 -9 -3 -11l-29 -16c6 -6 13 -10 21 -13c4 -1 6 -6 5 -10s-6 -6 -10 -5
+c-12 4 -23 10 -31 19l-64 -36l64 -36c8 8 19 15 31 19c4 1 9 -1 10 -5s-1 -9 -5 -10c-8 -3 -15 -7 -21 -13z" />
+ <glyph glyph-name="ion-ios-speedometer-outline" unicode="&#xf4af;"
+d="M224 384c124 0 224 -100 224 -224c0 -57 -21 -108 -56 -148c-4 -4 -7 -8 -11 -12l-10 10l-1 2c-19 18 -41 33 -65 43c-26 11 -53 16 -81 16s-55 -5 -81 -16c-24 -10 -46 -25 -65 -43l-1 -2l-10 -10c-4 4 -7 8 -11 12c-35 40 -56 91 -56 148c0 124 100 224 224 224z
+M416 79c10 23 15 48 16 73h-32v16h32c-1 25 -6 50 -16 73c-9 22 -23 42 -39 60l-27 -27l-6 6l-5 5v0h-1l27 27c-18 17 -38 31 -60 40c-23 10 -48 15 -74 16v-38h-16v38c-25 -1 -49 -6 -72 -16c-22 -10 -43 -23 -61 -40l27 -27v0v0l-6 -6l-5 -5l-27 27
+c-16 -18 -30 -38 -39 -60c-10 -23 -15 -49 -16 -74h32v-16h-32c1 -25 6 -49 16 -72c9 -20 20 -39 35 -56c40 40 96 64 157 64s117 -24 157 -64c15 17 26 36 35 56zM336 273l2 -1l-75 -84c6 -8 9 -18 9 -28c0 -26 -22 -48 -48 -48c-10 0 -19 4 -27 9l-13 -12l-11 11l12 12
+c-6 8 -9 18 -9 28c0 26 22 48 48 48c10 0 19 -3 27 -8zM224 128c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-ios-speedometer" unicode="&#xf4b0;"
+d="M385 169v-15h30c-1 -22 -6 -44 -15 -65c-8 -18 -19 -35 -32 -50c-39 37 -90 58 -144 58s-105 -21 -144 -58c-13 15 -24 32 -32 50c-9 21 -14 43 -15 65h28h1v16h-29c1 23 6 45 15 66c9 20 20 38 35 54l25 -24l10 10l1 1v0v0l-25 25c16 15 36 26 56 35c21 9 43 14 66 15
+v-34h14h1v34c23 -1 46 -6 67 -15s39 -20 55 -35l-24 -25l11 -11l25 25c15 -16 26 -35 35 -55c9 -21 14 -43 15 -66h-30v-1zM272 160c0 10 -3 20 -9 28l63 76l-2 1l-73 -65c-8 5 -17 8 -27 8c-26 0 -48 -22 -48 -48c0 -10 3 -20 9 -28l-12 -12l11 -11l13 12c8 -5 17 -9 27 -9
+c26 0 48 22 48 48zM224 384c124 0 224 -100 224 -224c0 -57 -21 -108 -56 -148c-4 -4 -7 -8 -11 -12h-23c-32 39 -80 64 -134 64s-102 -25 -134 -64h-23c-4 4 -7 8 -11 12c-35 40 -56 91 -56 148c0 124 100 224 224 224zM379 27c34 37 52 86 52 136c0 55 -22 106 -61 145
+s-91 60 -146 60s-107 -21 -146 -60s-61 -90 -61 -145c0 -50 18 -99 52 -136l10 -10l1 -1v1l9 9l1 1v0c17 17 38 30 60 39c24 10 48 15 74 15s50 -5 74 -15c22 -9 43 -22 60 -39v0l1 -1l9 -9v-1l1 1zM192 160c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32z
+" />
+ <glyph glyph-name="ion-ios-star-half" unicode="&#xf4b1;"
+d="M140 143l-140 98h171l53 159l53 -159h171l-140 -98l54 -159l-138 99l-138 -99zM224 347v-244l107 -76l-43 122l108 75h-131z" />
+ <glyph glyph-name="ion-ios-star-outline" unicode="&#xf4b2;"
+d="M448 241l-140 -98l54 -159l-138 99l-138 -99l54 159l-140 98h171l53 159l53 -159h171zM331 27l-43 122l108 75h-131l-41 123l-41 -123h-131l108 -75l-43 -122l107 76z" />
+ <glyph glyph-name="ion-ios-star" unicode="&#xf4b3;"
+d="M448 241l-140 -98l54 -159l-138 99l-138 -99l54 159l-140 98h171l53 159l53 -159h171z" />
+ <glyph glyph-name="ion-ios-stopwatch-outline" unicode="&#xf4b4;" horiz-adv-x="384"
+d="M334 301c32 -35 50 -80 50 -128c0 -104 -86 -189 -192 -189s-192 85 -192 189c0 48 18 94 51 129l1 1h-18l-8 -8l-23 23l41 40l23 -22l-9 -9v-18c31 30 72 50 116 53h2v38h32v-38c43 -4 82 -21 113 -49l5 -5v19l-9 9l23 22l41 -40l-22 -23l-9 8h-18zM192 2
+c96 0 173 77 173 171s-77 171 -173 171c-95 0 -173 -77 -173 -171s77 -171 173 -171zM200 191c14 -4 24 -17 24 -31c0 -15 -10 -26 -24 -30l-8 -18v0l-8 18c-14 4 -24 15 -24 30c0 14 12 27 24 31v129h16v-129z" />
+ <glyph glyph-name="ion-ios-stopwatch" unicode="&#xf4b5;" horiz-adv-x="384"
+d="M334 301c32 -35 50 -80 50 -128c0 -104 -86 -189 -192 -189s-192 85 -192 189c0 48 18 94 51 129l1 1h-18l-8 -8l-23 23l41 40l23 -22l-9 -9v-18c31 30 72 50 116 53h2v38h32v-38c43 -4 82 -21 113 -49l5 -5v19l-9 9l23 22l41 -40l-22 -23l-9 8h-18zM200 130
+c14 4 24 15 24 30c0 14 -10 27 -24 31v129h-16v-129c-12 -4 -24 -17 -24 -31c0 -15 10 -26 24 -30l8 -18z" />
+ <glyph glyph-name="ion-ios-sunny-outline" unicode="&#xf4b6;" horiz-adv-x="320"
+d="M151 296v56h18v-56h-18zM151 32v60h18v-60h-18zM264 183v18h56v-18h-56zM0 183v18h60v-18h-60zM240 130l34 -34l-12 -12l-33 34zM64 306l34 -33l-12 -12l-34 34zM229 272l33 34l12 -12l-34 -33zM52 96l34 34l11 -12l-33 -34zM160 116c-42 0 -76 34 -76 76s34 76 76 76
+s76 -34 76 -76s-34 -76 -76 -76zM160 251c-32 0 -59 -27 -59 -59s27 -59 59 -59s59 27 59 59s-27 59 -59 59z" />
+ <glyph glyph-name="ion-ios-sunny" unicode="&#xf4b7;" horiz-adv-x="320"
+d="M151 296v56h18v-56h-18zM151 32v60h18v-60h-18zM264 183v18h56v-18h-56zM0 183v18h60v-18h-60zM240 130l34 -34l-12 -12l-33 34zM64 306l34 -33l-12 -12l-34 34zM229 272l33 34l12 -12l-34 -33zM52 96l34 34l11 -12l-33 -34zM160 116c-42 0 -76 34 -76 76s34 76 76 76
+s76 -34 76 -76s-34 -76 -76 -76z" />
+ <glyph glyph-name="ion-ios-telephone-outline" unicode="&#xf4b8;" horiz-adv-x="352"
+d="M336 112c16 -16 26 -35 0 -66c-25 -30 -42 -30 -64 -30c-24 0 -58 14 -93 40c-32 23 -46 34 -78 67c-34 35 -55 64 -79 107c-27 50 -24 74 -18 92c4 12 14 24 28 33l1 1c6 4 18 12 32 12c13 0 24 -6 34 -18l1 -1c11 -14 24 -31 32 -47c10 -21 10 -38 -1 -53
+c-9 -12 -12 -19 -12 -23s5 -9 13 -18l1 -1c16 -18 20 -23 26 -29c1 -1 3 -2 4 -3l2 -2c7 -7 11 -12 29 -28l1 -1c7 -6 9 -8 12 -8c5 0 16 7 29 15c4 3 11 5 17 5c27 0 68 -29 83 -44zM324 57c19 22 13 31 1 43c-13 14 -50 39 -72 39c-3 0 -6 -1 -8 -2
+c-19 -12 -28 -18 -37 -18s-15 6 -23 13h-1c-19 16 -23 21 -30 29l-2 2c-1 1 -3 2 -4 3c-6 6 -11 12 -27 30v1c-10 11 -17 18 -18 28s5 20 16 34c15 20 -5 48 -31 79l-1 1c-7 8 -14 12 -22 12c-10 0 -18 -6 -23 -9c-1 0 -2 -1 -2 -1c-11 -7 -18 -16 -21 -24
+c-5 -16 -7 -35 17 -79c23 -42 43 -70 76 -104c31 -32 45 -42 76 -64c32 -23 64 -38 84 -38c21 0 32 1 52 25z" />
+ <glyph glyph-name="ion-ios-telephone" unicode="&#xf4b9;" horiz-adv-x="352"
+d="M336 112c16 -16 26 -35 0 -66c-25 -30 -42 -30 -64 -30c-24 0 -58 14 -93 40c-32 23 -46 34 -78 67c-34 35 -55 64 -79 107c-27 50 -24 74 -18 92c4 12 14 24 28 33l1 1c6 4 18 12 32 12c13 0 24 -6 34 -18l1 -1c11 -14 24 -31 32 -47c10 -21 10 -38 -1 -53
+c-9 -12 -12 -19 -12 -23s5 -9 13 -18l1 -1c16 -18 20 -23 26 -29c1 -1 3 -2 4 -3l2 -2c7 -7 11 -12 29 -28l1 -1c7 -6 9 -8 12 -8c5 0 16 7 29 15c4 3 11 5 17 5c27 0 68 -29 83 -44z" />
+ <glyph glyph-name="ion-ios-tennisball-outline" unicode="&#xf4ba;" horiz-adv-x="416"
+d="M416 192v-8v0c0 -5 0 -11 -1 -16v0c-11 -97 -90 -174 -187 -183v0h-4h-2s-1 -1 -2 -1h-3h-1h-8c-115 0 -208 93 -208 208s93 208 208 208s208 -93 208 -208zM399 192c0 105 -86 191 -191 191c-3 0 -5 -1 -8 -1c1 -24 6 -46 15 -68c10 -26 26 -49 46 -69s43 -36 69 -46
+c22 -9 44 -14 68 -15c0 3 1 5 1 8zM17 192c0 -105 86 -191 191 -191h4c-1 22 -7 45 -15 66c-10 26 -26 48 -46 68s-42 36 -68 46c-21 8 -44 14 -66 15v-4zM228 2c88 9 158 78 169 166c-54 3 -106 25 -147 66s-63 93 -66 147c-88 -11 -157 -81 -166 -169
+c53 -3 105 -25 145 -65s62 -92 65 -145z" />
+ <glyph glyph-name="ion-ios-tennisball" unicode="&#xf4bb;" horiz-adv-x="416"
+d="M0 196v0v0v0zM212 -16h1h-1v0zM208 400c115 0 208 -93 208 -208c0 -8 0 -16 -1 -24v0v0c-11 -97 -90 -174 -187 -183v0v0c-6 -1 -13 -1 -20 -1c-115 0 -208 93 -208 208v4v0v0c0 6 0 11 1 16v0v0c9 97 86 176 183 187v0v0c6 1 11 1 16 1v0v0h8zM83 181
+c26 -10 48 -26 68 -46s36 -42 46 -68c8 -21 14 -44 15 -66c5 0 11 0 16 1c-3 53 -25 105 -65 145s-92 62 -145 65c-1 -5 -1 -11 -1 -16c22 -1 45 -7 66 -15zM250 234c41 -41 93 -63 147 -66c1 5 1 11 1 16c-24 1 -46 6 -68 15c-26 10 -49 26 -69 46s-36 43 -46 69
+c-9 22 -14 44 -15 68c-5 0 -11 0 -16 -1c3 -54 25 -106 66 -147z" />
+ <glyph glyph-name="ion-ios-thunderstorm-outline" unicode="&#xf4bc;" horiz-adv-x="274"
+d="M193 176l-88 -128l29 96h-52l15 80h72l-16 -48h40zM209 275c36 0 65 -29 65 -65s-29 -66 -65 -66h-8v17h8c27 0 49 22 49 49s-22 50 -49 50h-6l-14 -2l-3 14c-3 14 -11 26 -22 35s-25 13 -39 13c-34 0 -63 -27 -63 -62v-12s1 -9 1 -9c-5 0 -12 -2 -14 -2
+c-19 -3 -33 -18 -33 -37c0 -10 3 -19 10 -26s16 -11 26 -11h11v-17h-11c-28 0 -52 24 -52 53c0 27 21 51 47 53v8c0 43 35 78 78 78c37 0 68 -26 76 -61h8z" />
+ <glyph glyph-name="ion-ios-thunderstorm" unicode="&#xf4bd;" horiz-adv-x="274"
+d="M153 176h40l-22 -32l-66 -96l29 96h-52l15 80h72zM84 240h107l-16 -48h18h30l-33 -48h19c36 0 65 30 65 66s-29 65 -65 65h-8c-8 35 -39 61 -76 61c-43 0 -78 -35 -78 -78v-8c-26 -2 -47 -26 -47 -53c0 -29 24 -53 52 -53h14z" />
+ <glyph glyph-name="ion-ios-time-outline" unicode="&#xf4be;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM371 45c19 19 35 41 45 66c11 26 16 53 16 81s-5 55 -16 81c-10 25 -26 47 -45 66s-41 35 -66 45c-26 11 -53 16 -81 16s-55 -5 -81 -16c-25 -10 -47 -26 -66 -45
+s-35 -41 -45 -66c-11 -26 -16 -53 -16 -81s5 -55 16 -81c10 -25 26 -47 45 -66s41 -35 66 -45c26 -11 53 -16 81 -16s55 5 81 16c25 10 47 26 66 45zM216 368c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM216 16c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM392 192
+c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM40 192c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM128 344c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM304 40c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM368 280c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8
+zM64 104c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM64 280c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM368 104c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM304 344c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM128 40c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8
+s-8 3 -8 8zM238 200c4 -8 2 -18 -6 -22v-122c0 -4 -4 -8 -8 -8s-8 4 -8 8v122c-2 1 -4 4 -6 6c-3 5 -3 11 0 16l-37 63c-2 4 -1 9 3 11s8 1 10 -3l38 -63c5 0 11 -3 14 -8z" />
+ <glyph glyph-name="ion-ios-time" unicode="&#xf4bf;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM224 376c-4 0 -8 -4 -8 -8s4 -8 8 -8s8 4 8 8s-4 8 -8 8zM48 184c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM76 97c4 2 4 7 2 11s-6 5 -10 3s-5 -7 -3 -11s7 -5 11 -3z
+M78 276c2 4 2 9 -2 11s-9 1 -11 -3s-1 -9 3 -11s8 -1 10 3zM132 351c-4 -2 -5 -7 -3 -11s7 -4 11 -2s5 6 3 10s-7 5 -11 3zM143 36c2 4 1 8 -3 10s-9 2 -11 -2s-1 -9 3 -11s9 -1 11 3zM224 8c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM232 178c8 4 10 14 6 22
+c-3 5 -9 8 -14 8l-38 64c-2 4 -7 4 -11 2s-4 -7 -2 -11l37 -63c-3 -5 -3 -11 0 -16c2 -2 4 -5 6 -6v-122c0 -4 4 -8 8 -8s8 4 8 8v122zM316 33c4 2 5 7 3 11s-7 4 -11 2s-5 -6 -3 -10s7 -5 11 -3zM319 340c2 4 1 9 -3 11s-9 1 -11 -3s-1 -8 3 -10s9 -2 11 2zM383 100
+c2 4 1 9 -3 11s-8 1 -10 -3s-2 -9 2 -11s9 -1 11 3zM380 273c4 2 5 7 3 11s-7 5 -11 3s-4 -7 -2 -11s6 -5 10 -3zM400 184c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8z" />
+ <glyph glyph-name="ion-ios-timer-outline" unicode="&#xf4c0;" horiz-adv-x="416"
+d="M189 176l-1 2s-89 118 -86 120s121 -85 121 -85c1 -1 1 -2 2 -3c5 -5 8 -11 8 -18c0 -14 -11 -25 -25 -25c-8 0 -14 3 -19 9zM208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208c0 57 23 109 61 147l12 -12c-35 -35 -56 -82 -56 -135
+c0 -106 85 -191 191 -191s191 85 191 191c0 100 -77 183 -175 191v-95h-16v112v0v0z" />
+ <glyph glyph-name="ion-ios-timer" unicode="&#xf4c1;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208s-208 93 -208 208s93 208 208 208zM102 298c-2 -2 86 -120 86 -120l1 -1c5 -6 11 -10 19 -10c14 0 25 11 25 25c0 7 -3 13 -8 18l-3 3c0 0 -117 87 -120 85zM208 1c106 0 192 85 192 191s-86 192 -192 192v-96h16v78
+c88 -9 158 -84 158 -174c0 -96 -78 -174 -174 -174s-175 78 -175 174c0 48 19 92 51 124l-11 12c-35 -35 -56 -83 -56 -136c0 -106 85 -191 191 -191z" />
+ <glyph glyph-name="ion-ios-toggle-outline" unicode="&#xf4c2;"
+d="M96 128c-26 0 -48 -22 -48 -48s22 -48 48 -48s48 22 48 48s-22 48 -48 48zM96 144v0c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM351 160v0h-255c-44 0 -80 -36 -80 -80s36 -80 80 -80h256c44 0 80 36 80 80s-37 80 -81 80zM352 176v0
+c53 0 96 -43 96 -96s-43 -96 -96 -96h-256c-53 0 -96 43 -96 96s43 96 96 96h256zM352 352c-26 0 -48 -22 -48 -48s22 -48 48 -48s48 22 48 48s-22 48 -48 48zM352 368v0c35 0 64 -29 64 -64s-29 -64 -64 -64s-64 29 -64 64s29 64 64 64zM97 384v0c-44 0 -81 -36 -81 -80
+s36 -80 80 -80h256c44 0 80 36 80 80s-36 80 -80 80h-255zM96 400v0h256c53 0 96 -43 96 -96s-43 -96 -96 -96h-256c-53 0 -96 43 -96 96s43 96 96 96z" />
+ <glyph glyph-name="ion-ios-toggle" unicode="&#xf4c3;"
+d="M96 128c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48zM352 176c53 0 96 -43 96 -96s-43 -96 -96 -96h-256c-53 0 -96 43 -96 96s43 96 96 96h256zM96 16c35 0 64 29 64 64s-29 64 -64 64s-64 -29 -64 -64s29 -64 64 -64zM352 256c-26 0 -48 22 -48 48
+s22 48 48 48s48 -22 48 -48s-22 -48 -48 -48zM96 208c-53 0 -96 43 -96 96s43 96 96 96h256c53 0 96 -43 96 -96s-43 -96 -96 -96h-256zM352 368c-35 0 -64 -29 -64 -64s29 -64 64 -64s64 29 64 64s-29 64 -64 64z" />
+ <glyph glyph-name="ion-ios-trash-outline" unicode="&#xf4c4;" horiz-adv-x="288"
+d="M288 335v-15h-20l-24 -291c0 -16 -13 -29 -29 -29h-141c-16 0 -29 13 -29 29l-24 291h-21v15h80v20c0 16 13 29 29 29h70c16 0 29 -13 29 -29v-20h80zM95 355v-20h98v20c0 8 -6 14 -14 14h-70c-8 0 -14 -6 -14 -14zM230 30l23 290h-217l23 -290v0v-1c0 -8 7 -14 15 -14
+h141c8 0 15 6 15 14v1v0zM137 47v241h14v-241h-14zM208 288l-11 -241h-14l10 241h15zM94 288l11 -241h-14l-11 241h14z" />
+ <glyph glyph-name="ion-ios-trash" unicode="&#xf4c5;" horiz-adv-x="288"
+d="M208 335h80v-15h-20l-24 -291c0 -16 -13 -29 -29 -29h-141c-16 0 -29 13 -29 29l-24 291h-21v15h80v20c0 16 13 29 29 29h70c16 0 29 -13 29 -29v-20zM95 355v0v-20h98v20c0 8 -6 14 -14 14h-70c-8 0 -14 -6 -14 -14zM91 47h14l-11 241h-14zM151 47v241h-14v-241h14z
+M197 47l11 241h-14l-11 -241h14z" />
+ <glyph glyph-name="ion-ios-undo-outline" unicode="&#xf4c6;" horiz-adv-x="384"
+d="M384 80v-32h-10l-20 31c-20 33 -44 63 -75 77c-24 11 -47 19 -87 20v-80l-192 128l192 128v-80c63 -3 108 -21 143 -56c52 -53 49 -119 49 -136zM368 87c0 0 9 169 -192 169v65l-148 -97l148 -97v65c91 0 144 -24 192 -105z" />
+ <glyph glyph-name="ion-ios-undo" unicode="&#xf4c7;" horiz-adv-x="384"
+d="M384 80v-32h-10l-20 31c-20 33 -44 63 -75 77c-24 11 -47 19 -87 20v-80l-192 128l192 128v-80c63 -3 108 -21 143 -56c52 -53 49 -119 49 -136z" />
+ <glyph glyph-name="ion-ios-unlocked-outline" unicode="&#xf4c8;" horiz-adv-x="320"
+d="M160 160c18 0 32 -14 32 -32c0 -15 -10 -27 -24 -31v-33h-16v33c-14 4 -24 16 -24 31c0 18 14 32 32 32zM160 112c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM72 224h248v-240h-320v240h56v72c0 57 47 104 104 104s104 -47 104 -104v-8h-16v8
+c0 49 -39 88 -88 88s-88 -39 -88 -88v-72zM304 0v208h-288v-208h288z" />
+ <glyph glyph-name="ion-ios-unlocked" unicode="&#xf4c9;" horiz-adv-x="320"
+d="M160 144c9 0 16 -7 16 -16s-7 -16 -16 -16s-16 7 -16 16s7 16 16 16zM72 224h248v-240h-320v240h56v72c0 57 47 104 104 104s104 -47 104 -104v-8h-16v8c0 49 -39 88 -88 88s-88 -39 -88 -88v-72zM168 97c14 4 24 16 24 31c0 18 -14 32 -32 32s-32 -14 -32 -32
+c0 -15 10 -27 24 -31v-33h16v33z" />
+ <glyph glyph-name="ion-ios-upload-outline" unicode="&#xf4ca;" horiz-adv-x="320"
+d="M192 304h128v-304h-320v304h128v-16h-112v-272h288v272h-112v16zM97 330l-11 12l74 74l74 -74l-11 -12l-55 55v-243h-16v243z" />
+ <glyph glyph-name="ion-ios-upload" unicode="&#xf4cb;" horiz-adv-x="320"
+d="M168 304h152v-304h-320v304h152v-162h16v162zM168 385v-81h-16v81l-55 -55l-11 12l74 74l74 -74l-11 -12z" />
+ <glyph glyph-name="ion-ios-videocam-outline" unicode="&#xf4cc;" horiz-adv-x="418"
+d="M257 320c19 0 33 -14 33 -33v-188c0 -19 -14 -35 -33 -35h-221c-19 0 -36 16 -36 35v188c0 19 17 33 36 33h221zM273 99v188c0 9 -8 16 -17 16h-221c-9 0 -18 -7 -18 -16v-188c0 -9 10 -18 19 -18h221c9 0 16 9 16 18zM320 235l98 53v-192l-98 53v86zM401 258v0l-64 -33
+v-66l64 -33v132z" />
+ <glyph glyph-name="ion-ios-videocam" unicode="&#xf4cd;" horiz-adv-x="418"
+d="M257 320c19 0 33 -14 33 -33v-188c0 -19 -14 -35 -33 -35h-221c-19 0 -36 16 -36 35v188c0 19 17 33 36 33h221zM320 235l98 53v-192l-98 53v86z" />
+ <glyph glyph-name="ion-ios-volume-high" unicode="&#xf4ce;" horiz-adv-x="320"
+d="M278 320c26 -36 42 -80 42 -128s-16 -92 -42 -128l-14 10c24 33 39 74 39 118s-15 85 -39 118zM224 96l-14 10c18 24 29 54 29 86s-11 62 -29 86l14 10c20 -27 32 -60 32 -96s-12 -69 -32 -96zM177 128l-13 10c12 15 18 34 18 54s-6 39 -18 54l13 10
+c14 -18 22 -40 22 -64s-8 -46 -22 -64zM58 232l70 56v-192l-70 56h-58v80h58z" />
+ <glyph glyph-name="ion-ios-volume-low" unicode="&#xf4cf;" horiz-adv-x="128"
+d="M58 232l70 56v-192l-70 56h-58v80h58z" />
+ <glyph glyph-name="ion-ios-wineglass-outline" unicode="&#xf4d0;" horiz-adv-x="192"
+d="M104 139v-155h72v-16h-80h-80v16h72v155c0 22 -20 39 -40 55c-8 6 -16 13 -22 19c-27 28 -26 52 -26 71v4c0 44 31 125 32 128h64h64c1 -3 32 -84 32 -128v-4c0 -19 1 -43 -26 -71c-6 -6 -14 -13 -22 -19c-20 -16 -40 -33 -40 -55zM43 400c-5 -16 -20 -63 -25 -96h156
+c-5 33 -20 80 -25 96h-53h-53zM96 175c3 0 5 0 7 2v0c9 11 20 20 31 29c8 6 15 12 20 18c22 23 22 41 22 60v4h-160v-4c0 -19 0 -37 22 -60c5 -6 12 -12 20 -18c11 -9 22 -18 31 -29v0c2 -2 4 -2 7 -2z" />
+ <glyph glyph-name="ion-ios-wineglass" unicode="&#xf4d1;" horiz-adv-x="192"
+d="M104 139v-155h72v-16h-80h-80v16h72v155c0 22 -20 39 -40 55c-8 6 -16 13 -22 19c-27 28 -26 52 -26 71v4c0 44 31 125 32 128h64h64c1 -3 32 -84 32 -128v-4c0 -19 1 -43 -26 -71c-6 -6 -14 -13 -22 -19c-20 -16 -40 -33 -40 -55zM43 400c-5 -16 -20 -63 -25 -96h156
+c-5 33 -20 80 -25 96h-53h-53z" />
+ <glyph glyph-name="ion-ios-world-outline" unicode="&#xf4d2;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208v0v0v0c-115 0 -208 93 -208 208s93 208 208 208v0v0v0zM216 276v-76h75c-1 31 -5 60 -11 84c-21 -5 -42 -7 -64 -8zM216 292c20 1 41 3 60 8c-14 46 -38 76 -60 82v-90zM200 382c-23 -6 -45 -36 -60 -82
+c19 -5 39 -7 60 -8v90zM200 276c-22 1 -44 3 -65 8c-6 -24 -10 -53 -11 -84h76v76zM108 200c1 32 4 62 11 88c-21 6 -41 15 -59 25c-26 -31 -41 -70 -43 -113h91zM108 184h-91c2 -43 17 -82 43 -113c19 10 38 19 59 25c-7 26 -10 56 -11 88zM124 184c1 -31 5 -60 11 -84
+c21 5 43 8 65 9v75h-76zM200 92c-21 -1 -41 -3 -60 -8c15 -46 37 -76 60 -82v90zM216 2c22 6 46 36 60 82c-19 5 -40 7 -60 8v-90zM216 109c22 -1 43 -4 64 -9c6 24 10 53 11 84h-75v-75zM308 184c-1 -32 -5 -62 -12 -88c21 -6 41 -15 60 -25c26 31 41 70 43 113h-91z
+M308 200v0h91c-2 43 -17 82 -43 113c-19 -10 -38 -19 -59 -25c7 -26 10 -56 11 -88zM344 326c-25 25 -56 44 -91 52c16 -17 29 -43 39 -74c18 6 35 13 52 22zM163 378c-35 -8 -67 -27 -91 -52c16 -9 34 -15 52 -21c10 31 23 56 39 73zM72 58c25 -25 56 -44 91 -52
+c-16 17 -30 43 -40 74c-18 -6 -35 -13 -51 -22zM253 6c35 8 66 27 91 52c-17 9 -34 16 -52 22c-10 -31 -23 -57 -39 -74z" />
+ <glyph glyph-name="ion-ios-world" unicode="&#xf4d3;" horiz-adv-x="416"
+d="M208 400c115 0 208 -93 208 -208s-93 -208 -208 -208v0v0v0c-115 0 -208 93 -208 208s93 208 208 208v0v0v0zM208 1c106 0 191 85 191 191s-85 191 -191 191v0v0v0c-106 0 -191 -85 -191 -191s86 -191 191 -191v0v0v0zM274 276c6 -22 9 -48 10 -76h-68v68c20 1 39 4 58 8
+zM216 366c20 -6 41 -34 54 -75c-17 -4 -36 -6 -54 -7v82zM145 291c13 42 35 69 55 75v-82c-19 1 -37 3 -55 7zM333 315c-15 -8 -31 -15 -48 -20c-9 29 -21 52 -36 67c32 -8 61 -24 84 -47zM299 200c-1 29 -4 56 -10 80c19 6 37 14 54 23c23 -28 38 -64 40 -103h-84zM132 200
+c1 28 3 54 9 76c19 -5 39 -7 59 -8v-68h-68zM284 184c-1 -28 -4 -54 -10 -76c-19 5 -38 7 -58 8v68h68zM141 108c-6 22 -8 48 -9 76h68v-68c-20 -1 -40 -3 -59 -8zM200 18c-20 6 -42 33 -55 75c18 4 36 6 55 7v-82zM249 22c15 15 27 38 36 67c17 -5 33 -11 48 -19
+c-23 -23 -52 -40 -84 -48zM167 362c-15 -15 -27 -39 -36 -67c-16 5 -33 11 -48 19c22 23 52 40 84 48zM289 104c6 24 9 51 10 80h84c-2 -39 -17 -75 -40 -103c-17 9 -35 17 -54 23zM216 100c18 -1 37 -3 54 -7c-13 -42 -34 -69 -54 -75v82zM127 280c-6 -24 -11 -51 -11 -80
+h-83c2 39 17 75 40 103c17 -9 35 -17 54 -23zM116 184c1 -29 4 -56 10 -80c-19 -6 -36 -14 -53 -23c-23 28 -38 64 -40 103h83zM83 70c15 8 32 14 48 19c9 -28 21 -52 36 -67c-32 8 -62 25 -84 48z" />
+ <glyph glyph-name="ion-ipad" unicode="&#xf1f9;" horiz-adv-x="288"
+d="M0 375c0 5 4 9 9 9h270c5 0 9 -4 9 -9v-366c0 -5 -4 -9 -9 -9h-270c-5 0 -9 4 -9 9v366zM144 10c8 0 14 6 14 14s-7 14 -14 14c-8 0 -14 -6 -14 -14s6 -14 14 -14zM32 329v-275c0 -4 3 -6 6 -6h211c3 0 7 2 7 6v275c0 4 -4 7 -7 7h-211c-3 0 -6 -3 -6 -7z" />
+ <glyph glyph-name="ion-iphone" unicode="&#xf1fa;" horiz-adv-x="192"
+d="M168 384c13 0 24 -11 24 -24v-336c0 -13 -11 -24 -24 -24h-144c-13 0 -24 11 -24 24v336c0 13 11 24 24 24h144zM80 348v0c0 -2 2 -4 4 -4h24c2 0 4 2 4 4v0c0 2 -2 4 -4 4h-24c-2 0 -4 -2 -4 -4zM68 352c-2 0 -4 -2 -4 -4s2 -4 4 -4s4 2 4 4s-2 4 -4 4zM96 16
+c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM176 64v256h-160v-256h160z" />
+ <glyph glyph-name="ion-ipod" unicode="&#xf1fb;" horiz-adv-x="224"
+d="M112 137c18 0 32 -14 32 -32s-14 -32 -32 -32s-32 14 -32 32s14 32 32 32zM196 384c15 0 28 -12 28 -28v-328c0 -16 -13 -28 -28 -28h-168c-15 0 -28 12 -28 28v328c0 16 13 28 28 28h168zM112 32c40 0 72 32 72 72s-32 72 -72 72s-72 -32 -72 -72s32 -72 72 -72z
+M192 221v118c-1 7 -6 12 -12 13h-136c-7 -1 -12 -7 -12 -15v-114c0 -8 6 -15 14 -15h131c8 0 14 5 15 13z" />
+ <glyph glyph-name="ion-jet" unicode="&#xf295;" horiz-adv-x="326"
+d="M222 80l-2 -13l53 -58l-18 -27l-74 9l-18 -55l-19 55l-73 -9l-18 27l53 58l-2 13l-104 -35l3 53l114 103s26 173 28 192c5 40 18 55 18 55s13 -15 18 -55c2 -19 28 -192 28 -192l114 -103l3 -53z" />
+ <glyph glyph-name="ion-key" unicode="&#xf296;" horiz-adv-x="192"
+d="M144 147c28 -17 48 -48 48 -83c0 -53 -43 -96 -96 -96s-96 43 -96 96c0 36 19 67 48 84c0 0 7 16 12 41c0 4 11 6 11 12v20c0 5 -7 9 -7 11v8v8c0 2 0 4 1 6c0 1 1 1 1 2l2 1l4 4v1c2 2 3 4 3 6c0 1 1 8 1 9c0 3 -2 6 -4 8l-1 1l-4 4v0l-1 1v0c-2 2 -3 5 -3 8v7
+c0 3 2 7 4 9v0l5 5v0c2 2 4 3 4 6v24c0 3 -2 6 -4 8v1l-4 4l-1 1c-2 2 -3 5 -3 8v18c0 11 0 19 9 23c3 1 14 3 23 3c20 0 30 -8 32 -36c0 0 7 -81 9 -143s7 -90 7 -90zM96 0c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-knife" unicode="&#xf297;" horiz-adv-x="64"
+d="M62 416c2 0 2 -1 2 -6v-412c0 -15 -10 -30 -24 -30v0v0c-14 0 -24 15 -24 30c1 19 14 83 16 130v0c1 30 -32 31 -32 70c0 134 35 191 54 214c2 2 5 4 8 4z" />
+ <glyph glyph-name="ion-laptop" unicode="&#xf1fc;" horiz-adv-x="512"
+d="M480 342v-262h-448v262c0 6 4 10 10 10h428c6 0 10 -4 10 -10zM448 112v208h-384v-208h384zM0 59v5h512v-5c-70 -20 -116 -27 -256 -27s-186 7 -256 27z" />
+ <glyph glyph-name="ion-leaf" unicode="&#xf1fd;" horiz-adv-x="422"
+d="M412 69c18 -3 10 -41 -5 -39c0 0 -21 -1 -63 12c0 0 -16 -19 -39 -30c-26 -12 -118 -33 -197 38c-108 97 -120 354 -100 333c86 -90 197 -47 270 -106c55 -44 88 -127 77 -192c0 0 5 -8 57 -16zM316 65c5 5 10 16 10 24c-161 52 -252 160 -252 160s104 -143 242 -184z
+" />
+ <glyph glyph-name="ion-levels" unicode="&#xf298;" horiz-adv-x="350"
+d="M46 349c11 -5 18 -16 18 -29s-7 -24 -18 -29v-275c0 -9 -7 -16 -16 -16s-16 7 -16 16v278c-8 6 -14 15 -14 26s6 20 14 26v22c0 9 7 16 16 16s16 -7 16 -16v-19zM142 155c9 -6 15 -16 15 -27s-6 -21 -15 -27v-85c0 -9 -7 -16 -16 -16s-16 7 -16 16v84
+c-10 5 -17 16 -17 28s7 23 17 28v212c0 9 7 16 16 16s16 -7 16 -16v-213zM238 285c10 -6 16 -16 16 -28s-6 -22 -16 -28v-213c0 -9 -7 -16 -16 -16s-16 7 -16 16v213c-10 6 -16 16 -16 28s6 22 16 28v83c0 9 7 16 16 16s16 -7 16 -16v-83zM350 65c0 -12 -6 -22 -16 -28v-21
+c0 -9 -7 -16 -16 -16s-16 7 -16 16v21c-10 6 -16 16 -16 28s6 22 16 28v275c0 9 7 16 16 16s16 -7 16 -16v-275c10 -6 16 -16 16 -28z" />
+ <glyph glyph-name="ion-lightbulb" unicode="&#xf299;" horiz-adv-x="256"
+d="M128 416c71 0 128 -56 128 -124c0 -5 0 -9 -1 -14s-2 -11 -3 -16v-2c-17 -63 -45 -71 -59 -167v-1c-2 -9 -10 -12 -20 -12h-90c-10 0 -18 3 -20 12v1c-14 96 -42 104 -59 167v2c-1 5 -2 11 -3 16s-1 9 -1 14c0 68 57 124 128 124zM190 52v-1c-2 -3 -3 -4 -3 -7s1 -5 3 -8
+v-1c1 -2 2 -3 2 -5s-1 -4 -2 -6v-1c-2 -3 -3 -4 -3 -7s1 -5 3 -8v-1c1 -2 2 -4 2 -6c0 -5 -4 -9 -10 -11h-1c-6 -1 -13 -2 -19 -3h-2c-6 -1 -11 -5 -14 -9v0c-4 -5 -10 -10 -18 -10s-15 6 -19 11v0c-3 4 -7 7 -13 8h-2c-6 1 -13 2 -19 3h-1c-6 2 -10 6 -10 11c0 2 1 4 2 6v1
+c2 2 3 4 3 7s-1 5 -3 8v1c-1 2 -2 4 -2 6s1 3 2 5v1c2 3 3 5 3 8s-1 4 -3 7v1v0c-1 2 -2 4 -2 6c0 4 -1 6 7 6h114c8 0 7 -2 7 -6c0 -2 -1 -4 -2 -6v0z" />
+ <glyph glyph-name="ion-link" unicode="&#xf1fe;" horiz-adv-x="384"
+d="M192 240v0v0v0zM304 288c44 0 80 -36 80 -80v-32c0 -44 -36 -80 -80 -80h-112c-33 0 -60 20 -73 48c-4 10 -7 20 -7 32v32h48v-32c0 -18 14 -32 32 -32h112c18 0 32 14 32 32v32c0 18 -14 32 -32 32v0h-16c-6 31 -32 48 -32 48h48zM266 240c4 -10 6 -21 6 -32v-32v0h-48
+v0v32c0 18 -14 32 -32 32v0h-112c-18 0 -32 -14 -32 -32v-32c0 -18 14 -32 32 -32h16c6 -31 32 -48 32 -48h-48c-44 0 -80 36 -80 80v32c0 44 36 80 80 80h112c33 0 62 -20 74 -48z" />
+ <glyph glyph-name="ion-load-a" unicode="&#xf29a;" horiz-adv-x="384"
+d="M144 352c0 43 21 64 64 64s64 -21 64 -64s-21 -64 -64 -64s-64 21 -64 64zM0 192c0 32 16 48 48 48s48 -16 48 -48s-16 -48 -48 -48s-48 16 -48 48zM312 304c0 5 3 8 8 8s8 -3 8 -8s-3 -8 -8 -8s-8 3 -8 8zM132 340c10 -10 15 -22 15 -36s-5 -26 -15 -36s-22 -15 -36 -15
+s-26 5 -36 15s-15 22 -15 36s5 26 15 36s22 15 36 15s26 -5 36 -15zM352 192c0 11 5 16 16 16s16 -5 16 -16s-5 -16 -16 -16s-16 5 -16 16zM297 79c0 16 8 24 24 24s24 -8 24 -24s-8 -24 -24 -24s-24 8 -24 24zM176 32c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32
+s-32 11 -32 32zM56 80c0 27 13 40 40 40s40 -13 40 -40s-13 -40 -40 -40s-40 13 -40 40z" />
+ <glyph glyph-name="ion-load-b" unicode="&#xf29b;"
+d="M256 288c0 -18 -14 -32 -32 -32v0c-18 0 -32 14 -32 32v96c0 18 14 32 32 32v0c18 0 32 -14 32 -32v-96zM224 128v0c18 0 32 -14 32 -32v-96c0 -18 -14 -32 -32 -32s-32 14 -32 32v96c0 18 14 32 32 32zM416 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32h-96
+c-18 0 -32 14 -32 32s14 32 32 32h96zM128 224v0c18 0 32 -14 32 -32s-14 -32 -32 -32h-96c-18 0 -32 14 -32 32s14 32 32 32h96zM314 237c-12 -12 -33 -12 -45 0v0c-12 12 -12 34 0 46l68 67c12 12 33 12 45 0v0c12 -12 12 -33 0 -45zM179 147v0c12 -12 12 -33 0 -46
+l-68 -67c-12 -12 -33 -12 -45 0s-12 33 0 45l67 68c12 12 34 12 46 0zM382 79v0c12 -12 12 -33 0 -45s-33 -12 -45 0l-68 68c-12 12 -12 33 0 45s33 12 45 0zM179 282v0c12 -12 12 -33 0 -45s-34 -12 -46 0l-67 68c-12 12 -12 33 0 45s33 12 45 0z" />
+ <glyph glyph-name="ion-load-c" unicode="&#xf29c;"
+d="M448 222c0 -3 0 -6 -1 -9c-4 -8 -15 -12 -23 -7c-4 2 -6 7 -7 11c-1 5 -1 9 -2 14c-4 20 -12 40 -22 58c-12 21 -28 41 -47 56c-18 15 -40 26 -62 33c-21 6 -42 9 -64 9h-4c-3 0 -6 -1 -9 -1c-6 0 -14 -1 -20 -2c-13 -2 -25 -6 -37 -11c-21 -8 -40 -20 -57 -35
+s-31 -33 -42 -52c-12 -22 -20 -45 -24 -70c-2 -11 -2 -23 -2 -34c0 -6 0 -11 1 -16c1 -6 2 -13 3 -19c5 -24 14 -47 28 -67c13 -20 29 -38 48 -52c20 -15 42 -26 65 -33c25 -7 50 -9 76 -7c25 2 50 9 73 20c11 5 22 12 32 19s19 15 27 24c4 4 8 9 12 14s7 10 10 15
+c6 10 12 20 17 31c4 8 8 16 11 25c2 4 3 9 4 13s1 7 2 11c1 -9 1 -18 -1 -26c-1 -5 -2 -11 -4 -16c-1 -5 -3 -10 -5 -15c-4 -10 -8 -19 -13 -28c-6 -11 -12 -21 -20 -30s-16 -18 -25 -26c-18 -15 -40 -27 -62 -36c-23 -9 -48 -14 -73 -15s-51 3 -75 11c-23 7 -45 19 -65 33
+c-19 14 -36 31 -50 50c-7 10 -13 20 -18 31s-9 21 -13 33c-6 18 -9 37 -10 56c-1 20 1 39 5 58c5 24 15 47 28 68c12 19 26 35 42 50s35 27 55 36c23 11 48 19 74 21c10 1 19 1 29 1c13 0 26 -2 38 -4c24 -5 47 -14 68 -26s41 -29 57 -48c15 -18 27 -37 36 -58
+c4 -10 7 -21 10 -32c2 -8 5 -17 6 -26z" />
+ <glyph glyph-name="ion-load-d" unicode="&#xf29d;" horiz-adv-x="384"
+d="M368 208c9 0 16 -7 16 -16s-7 -16 -16 -16h-80c-9 0 -16 7 -16 16s7 16 16 16h80zM112 192c0 -9 -7 -16 -16 -16h-80c-9 0 -16 7 -16 16s7 16 16 16h80c9 0 16 -7 16 -16zM192 112c9 0 16 -7 16 -16v-80c0 -9 -7 -16 -16 -16s-16 7 -16 16v80c0 9 7 16 16 16zM192 384
+c9 0 16 -7 16 -16v-80c0 -9 -7 -16 -16 -16s-16 7 -16 16v80c0 9 7 16 16 16zM261 232c-4 8 -2 18 6 22l69 40c8 4 18 2 22 -6s2 -18 -6 -22l-69 -40c-8 -4 -18 -2 -22 6zM123 152c4 -8 2 -18 -6 -22l-69 -40c-8 -4 -18 -2 -22 6s-2 18 6 22l69 40c8 4 18 2 22 -6zM254 117
+l40 -69c4 -8 2 -18 -6 -22s-18 -2 -22 6l-40 69c-4 8 -2 18 6 22s18 2 22 -6zM118 352l40 -69c4 -8 2 -18 -6 -22s-18 -2 -22 6l-40 69c-4 8 -2 18 6 22s18 2 22 -6zM232 261c-8 4 -10 14 -6 22l40 69c4 8 14 10 22 6s10 -14 6 -22l-40 -69c-4 -8 -14 -10 -22 -6zM152 123
+c8 -4 10 -14 6 -22l-40 -69c-4 -8 -14 -10 -22 -6s-10 14 -6 22l40 69c4 8 14 10 22 6zM352 118c8 -4 10 -14 6 -22s-14 -10 -22 -6l-69 40c-8 4 -10 14 -6 22s14 10 22 6zM32 266c-8 4 -10 14 -6 22s14 10 22 6l69 -40c8 -4 10 -14 6 -22s-14 -10 -22 -6z" />
+ <glyph glyph-name="ion-location" unicode="&#xf1ff;" horiz-adv-x="239"
+d="M119 384c66 0 120 -54 120 -120c0 -115 -120 -264 -120 -264s-119 149 -119 264c0 66 53 120 119 120zM119 206c31 0 57 25 57 56s-26 57 -57 57s-56 -26 -56 -57s25 -56 56 -56z" />
+ <glyph glyph-name="ion-lock-combination" unicode="&#xf4d4;" horiz-adv-x="384"
+d="M320 271c39 -35 64 -86 64 -143c0 -106 -86 -192 -192 -192s-192 86 -192 192c0 57 25 108 64 143v49c0 71 57 128 128 128s128 -57 128 -128v-49zM96 320v-26c28 16 61 26 96 26s68 -10 96 -26v26c0 53 -43 96 -96 96s-96 -43 -96 -96zM192 -32c88 0 160 72 160 160
+s-72 160 -160 160s-160 -72 -160 -160s72 -160 160 -160zM192 272c80 0 144 -64 144 -144s-64 -144 -144 -144s-144 64 -144 144s64 144 144 144zM315 95c2 9 4 18 4 29h-7v7h8c0 11 -2 20 -5 30l-25 -7l-4 12l25 8c-4 10 -8 18 -14 26l-11 -8l-4 6l11 8c-6 8 -13 16 -21 22
+l-15 -21l-11 8l15 20c-8 6 -17 11 -27 14l-4 -13l-6 2l5 13c-9 3 -20 5 -29 5v-13v-6h-16v6v13c-11 -1 -19 -2 -29 -5l4 -12l-6 -2l-4 12c-10 -3 -19 -8 -27 -14l15 -20l-10 -8l-15 21c-8 -6 -16 -14 -22 -22l11 -8l-4 -5l-10 8c-6 -8 -10 -17 -14 -27l24 -8l-5 -12l-25 7
+c-3 -10 -3 -19 -3 -30h6v-7h-5c0 -11 2 -20 4 -29l24 7l4 -12l-24 -8c4 -10 8 -19 14 -27l9 7l4 -5l-9 -7c6 -8 13 -16 21 -22l15 21l10 -8l-15 -20c8 -5 17 -11 27 -14l3 11l7 -2l-4 -11c10 -3 18 -4 29 -5v13v6h16v-6v-13c9 1 19 2 29 5l-5 12l6 2l4 -12c10 3 19 8 27 14
+l-15 20l11 8l15 -21c8 6 15 14 21 22l-11 7l4 6l10 -8c6 8 11 17 15 27l-25 8l4 12zM111 128c0 54 27 81 81 81s81 -27 81 -81s-27 -81 -81 -81s-81 27 -81 81z" />
+ <glyph glyph-name="ion-locked" unicode="&#xf200;" horiz-adv-x="384"
+d="M22 -32c-12 0 -22 10 -22 22v212c0 12 10 22 22 22h3h19v31c0 42 17 87 43 115s64 46 105 46v0v0c41 0 79 -18 105 -46s43 -73 43 -115v-31h22c12 0 22 -10 22 -22v-212c0 -12 -10 -22 -22 -22h-340zM97 255v-31h17h155h18v31c0 27 -10 61 -28 80v0v1
+c-18 19 -42 29 -67 29v0v0c-25 0 -49 -10 -67 -29v-1v0c-18 -19 -28 -53 -28 -80z" />
+ <glyph glyph-name="ion-log-in" unicode="&#xf29e;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224c-96 0 -177 60 -209 144h34c9 -20 23 -40 39 -56c36 -36 85 -56 136 -56s100 20 136 56s56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56c-16 -16 -30 -36 -39 -56h-34c32 84 113 144 209 144z
+M175 124l52 52h-227v32h227l-52 52l22 23l91 -91l-91 -91z" />
+ <glyph glyph-name="ion-log-out" unicode="&#xf29f;"
+d="M335 124l52 52h-227v32h227l-52 52l22 23l91 -91l-91 -91zM359 56c3 3 6 5 8 8h41c-40 -58 -108 -96 -184 -96c-124 0 -224 100 -224 224s100 224 224 224c76 0 144 -38 184 -96h-41c-2 3 -5 5 -8 8c-36 36 -84 56 -135 56s-100 -20 -136 -56s-56 -85 -56 -136
+s20 -100 56 -136s85 -56 136 -56s99 20 135 56z" />
+ <glyph glyph-name="ion-loop" unicode="&#xf201;" horiz-adv-x="334"
+d="M184 148v-58c49 8 86 50 86 102c0 16 -4 30 -10 44c-3 6 -5 12 -9 17l47 43c1 -1 2 -3 3 -4c21 -28 33 -62 33 -100v-4c-2 -72 -47 -131 -111 -154c-12 -4 -26 -8 -39 -9v-57l-76 67l-26 23l44 39zM0 196c2 72 48 133 113 155c12 4 24 7 37 8v57l76 -67l26 -23l-44 -39
+l-59 -51l1 58c-49 -8 -86 -51 -86 -102c0 -16 4 -31 10 -45c3 -6 5 -11 9 -16l-47 -44c-1 2 -2 3 -3 5c-20 28 -33 63 -33 100v4z" />
+ <glyph glyph-name="ion-magnet" unicode="&#xf2a0;" horiz-adv-x="384"
+d="M192 416c115 0 192 -78 192 -200c0 -49 -3 -77 -15 -128c-16 -66 -39 -113 -39 -113v-1c-2 -3 -6 -6 -10 -6c-1 0 -3 1 -4 1l-2 1l-50 20l-2 1c-3 2 -5 5 -5 9c0 1 0 3 1 4v1c7 16 27 59 37 101s13 63 13 108c0 71 -52 122 -116 122s-116 -51 -116 -122
+c0 -45 3 -66 13 -108s30 -85 37 -101v-1c1 -1 1 -3 1 -4c0 -4 -2 -7 -5 -9l-2 -1l-50 -20l-2 -1c-1 0 -3 -1 -4 -1c-4 0 -8 3 -10 6v1s-24 47 -40 113c-12 51 -14 79 -14 128c0 122 77 200 192 200zM109 4c-9 19 -27 59 -36 98l-42 -12c13 -53 30 -92 35 -104l43 17v1z
+M317 -14c5 12 23 51 36 104l-43 12c-9 -39 -26 -79 -35 -98v-1z" />
+ <glyph glyph-name="ion-male" unicode="&#xf2a1;"
+d="M448 256l-63 63l-69 -69c22 -30 36 -66 36 -106c0 -97 -79 -176 -176 -176s-176 79 -176 176s79 176 176 176c40 0 76 -14 106 -36l69 69l-63 63h160v-160zM266 54c24 24 38 56 38 90s-14 66 -38 90s-56 38 -90 38s-66 -14 -90 -38s-38 -56 -38 -90s14 -66 38 -90
+s56 -38 90 -38s66 14 90 38z" />
+ <glyph glyph-name="ion-man" unicode="&#xf202;" horiz-adv-x="168"
+d="M84 341c-21 0 -37 17 -37 38s16 37 37 37s37 -16 37 -37s-16 -38 -37 -38zM121 333c28 0 47 -24 47 -48v-114c0 -22 -32 -22 -32 0v105h-5v-286c0 -28 -41 -31 -43 0v165h-1h-7v-165c-1 -29 -43 -30 -43 0v286h-6v-105c0 -22 -31 -22 -31 0v114c0 24 19 48 47 48h37h37z
+" />
+ <glyph glyph-name="ion-map" unicode="&#xf203;"
+d="M441 311c4 -3 7 -8 7 -14v-281c0 -6 -2 -11 -7 -14c-2 -1 -5 -2 -7 -2c-3 0 -6 0 -8 2l-97 66l-97 -66c-5 -3 -10 -3 -15 0l-97 66l-97 -66c-5 -3 -10 -3 -15 0s-8 8 -8 14v281c0 6 3 11 7 14l105 71c5 3 10 3 15 0l97 -66l98 66c5 3 10 3 15 0zM103 95v242l-71 -50v-242
+zM135 95l73 -49v129l-4 -11c-7 2 -13 6 -20 10l8 13c5 -3 11 -6 16 -8v109l-73 49v-101c4 -2 9 -4 13 -7l-10 -13c-1 1 -2 1 -3 2v-123zM240 46l73 49v109c0 -1 -1 -1 -1 -2l-6 -6l-12 11l6 6c3 3 5 7 8 10l5 -5v119l-73 -49v-112h7l3 -15c-3 0 -6 -1 -9 -1h-1v-114zM416 46
+v242l-71 49v-88c3 1 5 1 8 2l4 -16c-4 -1 -8 -1 -12 -3v-137zM97 227c-3 -1 -11 -5 -14 -7l-11 12c4 3 8 6 12 8c3 2 6 3 9 4l5 -15c-2 -1 1 -1 -1 -2zM265 182c5 3 10 5 15 10l11 -12c-6 -6 -12 -10 -19 -13zM67 192v-1l-15 5v1c2 7 4 13 9 20l13 -9c-4 -5 -5 -10 -7 -16z
+M166 210c3 -4 7 -8 11 -11l-11 -12c-4 4 -8 9 -12 13l-3 3l12 11c1 -1 2 -3 3 -4zM376 218l-11 12l10 10l-10 10l11 12l10 -11l11 11l11 -12l-10 -10l10 -10l-11 -12l-11 11z" />
+ <glyph glyph-name="ion-medkit" unicode="&#xf2a2;"
+d="M440 304c4 0 8 -4 8 -8v-288c0 -4 -4 -8 -8 -8h-432c-4 0 -8 4 -8 8v288c0 4 4 8 8 8h120v31c1 28 22 49 51 49h45h45c30 0 50 -21 51 -49v-31h120zM160 331v-27h128v27v1v1c0 10 -9 19 -19 19h-45h-45c-10 0 -19 -9 -19 -19v-1v-1zM320 128v64h-64v64h-64v-64h-64v-64
+h64v-64h64v64h64z" />
+ <glyph glyph-name="ion-merge" unicode="&#xf33f;" horiz-adv-x="384"
+d="M320 224c35 0 64 -29 64 -64s-29 -64 -64 -64c-24 0 -44 13 -55 32h-10c-61 0 -115 25 -159 74v-115c19 -11 32 -31 32 -55c0 -35 -29 -64 -64 -64s-64 29 -64 64c0 24 13 44 32 55v210c-19 11 -32 31 -32 55c0 35 29 64 64 64s64 -29 64 -64c0 -19 -8 -37 -22 -49
+c4 -9 17 -35 37 -58c32 -35 70 -53 112 -53h10c11 19 31 32 55 32zM64 384c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM64 0c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM320 128c18 0 32 14 32 32s-14 32 -32 32
+s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-mic-a" unicode="&#xf204;" horiz-adv-x="288"
+d="M0 210c0 10 9 19 20 19s19 -9 19 -19v-14c0 -28 12 -53 31 -72s45 -31 74 -31s55 12 74 31s31 44 31 72v14c0 10 8 19 19 19s20 -9 20 -19v-14c0 -66 -46 -120 -108 -136c-1 0 -3 -1 -4 -1c-6 -2 -10 -7 -12 -13v-58c0 -11 -9 -20 -20 -20v0c-11 0 -20 9 -20 20v58
+c-2 6 -6 11 -12 13c-1 0 -3 1 -4 1c-62 16 -108 70 -108 136v14zM67 340c0 42 34 76 77 76s78 -34 78 -76v-144c0 -42 -35 -75 -78 -75s-77 33 -77 75v144z" />
+ <glyph glyph-name="ion-mic-b" unicode="&#xf205;" horiz-adv-x="160"
+d="M80 416c35 0 65 -23 76 -59c6 -18 4 -45 2 -55s-8 -20 -14 -28c-3 -4 -7 -7 -11 -9c-1 0 -1 -1 -2 -1c-3 -1 -6 -2 -10 -3c-12 -3 -25 -5 -39 -5v0h-1h-1v0c-14 0 -29 2 -41 5c-4 1 -7 2 -10 3c-1 0 -1 1 -2 1c-4 2 -8 5 -11 9c-6 8 -12 18 -14 28s-4 37 2 55
+c11 36 41 59 76 59zM119 247c6 0 12 -5 12 -12v-2c-5 -67 -18 -241 -19 -252c0 0 -3 -13 -32 -13v0c-29 0 -32 13 -32 13c-1 11 -13 185 -18 252v2c0 7 5 12 11 12h1c1 0 1 -1 2 -1c2 0 4 -1 6 -1c9 -2 21 -2 31 -2s20 0 29 2c2 0 4 1 6 1c1 0 1 1 2 1h1zM90 166v33
+c0 6 -4 11 -10 11s-10 -5 -10 -11v-33c0 -6 4 -11 10 -11s10 5 10 11z" />
+ <glyph glyph-name="ion-mic-c" unicode="&#xf206;" horiz-adv-x="256"
+d="M201 416c30 0 55 -23 55 -52v-28h-59v-37h59v-43h-59v-37h59v-43h-59v-37h59v-42c0 -29 -25 -52 -55 -52h-30v-77h-86v77h-30c-30 0 -55 23 -55 52v42h152v37h-152v43h152v37h-152v43h152v37h-152v28c0 29 25 52 55 52h146z" />
+ <glyph glyph-name="ion-minus-circled" unicode="&#xf207;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM352 176v32h-256v-32h256z" />
+ <glyph glyph-name="ion-minus-round" unicode="&#xf208;" horiz-adv-x="384"
+d="M353 224c17 0 31 -14 31 -32s-14 -32 -31 -32h-322c-17 0 -31 14 -31 32s14 32 31 32h322z" />
+ <glyph glyph-name="ion-minus" unicode="&#xf209;" horiz-adv-x="384"
+d="M0 160v64h384v-64h-384z" />
+ <glyph glyph-name="ion-model-s" unicode="&#xf2c1;" horiz-adv-x="512"
+d="M509 57v-8v0v-1v-3v0c0 -3 -1 -5 -1 -7c-1 -12 -2 -18 -6 -20c-3 -2 -6 -2 -10 -2h-43s-10 1 -11 16v8c20 1 39 1 52 0c10 0 13 0 16 6c2 3 2 7 3 11zM3 57c1 -4 1 -8 3 -11c3 -6 6 -6 16 -6c13 1 32 1 52 0v-8c-1 -15 -8 -16 -11 -16h-43s-7 0 -10 2c-4 2 -6 8 -7 20v7
+v0v3v1v0v8zM512 151c0 -31 -2 -58 -2 -68c0 -4 0 -11 -1 -18c-1 -4 -1 -8 -3 -11c-3 -6 -6 -6 -16 -6c-13 1 -32 1 -52 0c-13 0 -27 -2 -39 -2c-30 -1 -21 4 -34 4s-63 -2 -109 -2s-97 2 -110 2s-4 -5 -34 -4c-12 0 -25 2 -38 2c-20 1 -39 1 -52 0c-10 0 -13 0 -16 6
+c-2 3 -2 7 -3 11c-1 7 -1 14 -1 18c0 10 -2 37 -2 68s4 61 6 64c1 2 8 9 26 21s17 10 20 18c-3 1 -5 3 -7 3c-4 0 -4 -3 -12 -3s-24 1 -28 5c-4 3 -5 5 -5 8s2 9 5 13s19 6 27 7s10 0 12 -1c4 -2 3 -22 3 -22l9 -1c5 13 12 41 24 62c13 23 26 30 32 32s10 2 48 6s69 5 96 5
+s58 -1 96 -5s42 -4 48 -6s19 -9 32 -32c12 -21 19 -49 24 -62l9 1s-1 20 3 22c2 1 4 2 12 1s24 -3 27 -7s5 -10 5 -13s-1 -4 -5 -8s-20 -5 -28 -5s-8 3 -12 3c-2 0 -4 -2 -7 -3c3 -8 2 -6 20 -18s25 -19 26 -21c2 -3 6 -33 6 -64zM86 303c-5 -11 -11 -33 -10 -36
+s-1 -5 15 -4s117 3 165 3s149 -2 165 -3s14 1 15 4s-5 25 -10 36s-17 31 -26 37c-2 1 -17 7 -54 9c-34 2 -72 3 -90 3s-56 -1 -90 -3c-37 -2 -52 -8 -54 -9c-7 -4 -21 -26 -26 -37zM123 178c7 2 11 2 11 2s-17 16 -48 25s-49 11 -66 10c0 0 -3 -16 0 -27s8 -10 16 -12
+s13 -5 16 -4s7 4 12 4s29 -4 38 -4s14 4 21 6zM358 99c15 2 34 19 21 33c-18 19 -15 19 -55 24c-35 4 -61 4 -68 4s-33 0 -68 -4c-40 -5 -37 -5 -55 -24c-13 -14 6 -31 21 -33c14 -2 74 -3 102 -3s88 1 102 3zM492 188c3 11 0 27 0 27c-17 1 -35 -1 -66 -10s-48 -26 -48 -26
+s4 1 11 -1s12 -6 21 -6s33 4 38 4s9 -3 12 -4s8 2 16 4s13 1 16 12z" />
+ <glyph glyph-name="ion-monitor" unicode="&#xf20a;"
+d="M437 384c6 0 11 -5 11 -11v-266c0 -6 -5 -11 -11 -11h-426c-6 0 -11 5 -11 11v266c0 6 5 11 11 11h426zM416 128v224h-384v-224h384zM270 0h-92c-28 0 -42 3 -30 12s30 16 30 23c0 4 1 45 1 45h45h45s1 -41 1 -45c0 -7 18 -14 30 -23s-2 -12 -30 -12z" />
+ <glyph glyph-name="ion-more" unicode="&#xf20b;" horiz-adv-x="384"
+d="M50 144c-28 0 -50 21 -50 48c0 26 22 48 50 48s50 -22 50 -48c0 -27 -22 -48 -50 -48zM192 144c-28 0 -50 21 -50 48c0 26 22 48 50 48s50 -22 50 -48c0 -27 -22 -48 -50 -48zM334 144c-28 0 -50 21 -50 48c0 26 22 48 50 48s50 -22 50 -48c0 -27 -22 -48 -50 -48z" />
+ <glyph glyph-name="ion-mouse" unicode="&#xf340;" horiz-adv-x="256"
+d="M128 416h-1h5h-4zM251 255c2 1 2 1 4 1h1v-176c0 -37 -21 -71 -53 -91c-5 -3 -9 -5 -14 -7v-1v0c-18 -9 -39 -13 -61 -13c-71 0 -128 50 -128 112v176h1c2 0 3 0 5 -1v0c34 -13 76 -23 122 -23s88 10 122 23h1zM189 -18c5 2 10 4 14 7c-5 -3 -9 -5 -14 -7v0v-1v1v0z
+M203 -11c-4 -3 -9 -5 -14 -7c5 2 9 4 14 7zM132 416c69 -2 124 -51 124 -112v-23c-2 -2 -4 -4 -6 -5c-1 -1 -3 0 -4 -1c-23 -10 -50 -16 -82 -19h-1h-2c-11 0 -17 0 -17 10v86c0 9 -7 16 -16 16s-16 -7 -16 -16v-85c0 -11 -6 -11 -17 -11h-2c-32 3 -61 9 -84 19v0
+c-1 0 -1 1 -2 1c-3 1 -5 3 -7 5v23c0 61 57 111 127 112h5z" />
+ <glyph glyph-name="ion-music-note" unicode="&#xf20c;" horiz-adv-x="384"
+d="M362 416c12 0 22 -9 22 -21v-303s-3 -43 -12 -55v0c-9 -15 -25 -21 -43 -21h-37c-28 0 -52 20 -52 48s24 48 52 48h60v192l-208 -38v-232c0 -8 -3 -27 -13 -41c-1 -2 -2 -3 -3 -5c0 -1 -1 -1 -2 -2v0c-9 -11 -23 -18 -38 -18h-37c-28 0 -51 20 -51 48s23 48 51 48v0h61
+v286c1 14 13 28 27 32l218 33s3 1 5 1z" />
+ <glyph glyph-name="ion-navicon-round" unicode="&#xf20d;" horiz-adv-x="384"
+d="M353 224c17 0 31 -14 31 -32s-14 -32 -31 -32h-322c-17 0 -31 14 -31 32s14 32 31 32h322zM353 352c17 0 31 -14 31 -32s-14 -32 -31 -32h-322c-17 0 -31 14 -31 32s14 32 31 32h322zM353 96c17 0 31 -14 31 -32s-14 -32 -31 -32h-322c-17 0 -31 14 -31 32s14 32 31 32
+h322z" />
+ <glyph glyph-name="ion-navicon" unicode="&#xf20e;" horiz-adv-x="320"
+d="M0 175v32h320v-32h-320zM0 271v32h320v-32h-320zM0 79v32h320v-32h-320z" />
+ <glyph glyph-name="ion-navigate" unicode="&#xf2a3;"
+d="M448 416l-192 -448v256h-256z" />
+ <glyph glyph-name="ion-network" unicode="&#xf341;" horiz-adv-x="384"
+d="M384 352c0 -24 -13 -44 -32 -55v-93l-128 -64v-53c19 -11 32 -31 32 -55c0 -35 -29 -64 -64 -64s-64 29 -64 64c0 24 13 44 32 55v53l-128 64v93c-19 11 -32 31 -32 55c0 35 29 64 64 64s64 -29 64 -64c0 -24 -13 -44 -32 -55v-53l96 -48l96 48v53c-19 11 -32 31 -32 55
+c0 35 29 64 64 64s64 -29 64 -64zM64 384c-18 0 -32 -14 -32 -32s14 -32 32 -32s32 14 32 32s-14 32 -32 32zM192 0c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM320 320c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-no-smoking" unicode="&#xf2c2;"
+d="M328 144v48h16v-48h-16zM80 144v48h90l48 -48h-138zM332 388c69 -38 116 -112 116 -196c0 -124 -100 -224 -224 -224c-24 0 -47 4 -68 11c-2 1 -3 1 -5 2c-12 4 -24 9 -35 15h-1c-69 38 -115 112 -115 196c0 124 100 224 224 224c24 0 47 -4 68 -11c2 -1 3 -1 5 -2
+c12 -4 24 -9 35 -15v0zM224 22c37 0 72 12 100 32l-238 238c-20 -28 -32 -63 -32 -100c0 -65 36 -121 90 -150c6 -3 13 -7 19 -9c2 -1 3 -1 5 -2c9 -3 19 -5 29 -7c9 -2 18 -2 27 -2zM362 93c20 28 32 62 32 99c0 66 -37 123 -91 151c-6 3 -12 6 -18 8c-2 1 -3 1 -5 2
+c-9 3 -19 5 -29 7c-9 2 -18 2 -27 2c-37 0 -71 -12 -99 -32zM320 150l-42 42h42v-42zM352 144v48h16v-48h-16zM328 235c16 -7 16 -27 16 -34v-1h-16v1c0 8 -1 17 -7 20c-4 2 -13 4 -39 4h-3c-13 0 -24 0 -33 13c-5 8 -5 19 -2 29c-4 1 -8 1 -12 3c-17 7 -26 20 -26 38
+c0 33 27 44 39 44v-16c-1 0 -23 -2 -23 -28c0 -11 5 -19 16 -23c9 -4 18 -3 18 -3c3 0 6 -2 7 -5s2 -6 0 -8c-5 -7 -7 -18 -4 -22c4 -6 7 -6 20 -6h3c24 0 37 -2 46 -6zM368 200v0h-16c0 28 -4 41 -7 46c-6 10 -14 14 -25 14h-30c-3 0 -5 2 -6 4s-1 6 0 8c0 0 8 18 6 32
+c-1 8 -6 17 -27 17v16c24 0 40 -11 43 -30c2 -11 0 -23 -3 -31h17c16 0 30 -8 39 -22c6 -10 9 -28 9 -54z" />
+ <glyph glyph-name="ion-nuclear" unicode="&#xf2a4;"
+d="M176 176c0 32 16 48 48 48s48 -16 48 -48s-16 -48 -48 -48s-48 16 -48 48zM176 176c0 32 16 48 48 48s48 -16 48 -48s-16 -48 -48 -48s-48 16 -48 48zM448 176c0 -27 -5 -53 -15 -78s-23 -47 -40 -66s-36 -35 -59 -48l-79 136c22 12 33 31 33 56h160zM224 240
+c-12 0 -23 -3 -33 -9l-80 138c35 20 73 31 113 31s78 -10 113 -30l-81 -139c-10 6 -21 9 -32 9zM160 176c0 -25 11 -44 33 -56l-79 -136c-35 20 -62 46 -83 80s-31 71 -31 112h160z" />
+ <glyph glyph-name="ion-outlet" unicode="&#xf342;"
+d="M338 416c61 0 110 -51 110 -113v-222c0 -62 -49 -113 -110 -113h-228c-61 0 -110 51 -110 113v222c0 62 49 113 110 113h228zM143 197v102c0 11 -9 21 -20 21h-23c-11 0 -19 -9 -20 -20v-2v-101v-1c0 -11 9 -20 20 -20h23c11 0 20 9 20 20v1zM265 52v29
+c0 23 -18 42 -41 42s-41 -19 -41 -42v-29v0c0 -11 9 -20 20 -20h21h21c11 0 20 7 20 18v2zM368 197v102c0 11 -9 21 -20 21h-24c-11 0 -19 -9 -20 -20v-2v-101v-1c0 -11 9 -20 20 -20h24c11 0 20 9 20 20v1z" />
+ <glyph glyph-name="ion-paintbrush" unicode="&#xf4d5;"
+d="M118 165c52 0 102 -41 90 -102c-11 -52 -54 -71 -90 -77c-30 -5 -100 0 -118 35c24 9 34 26 34 49c0 49 32 95 84 95zM436 388c13 -13 17 -30 5 -45l-154 -175c2 -9 1 -17 -3 -23l-50 -58v0v0c-2 -2 -4 -2 -6 0c-1 1 -1 2 -1 3v1c2 53 -41 87 -89 90v0h-2s-2 0 -2 1
+c-2 2 -2 4 0 6l59 49c6 4 14 4 23 2l175 154c15 12 32 8 45 -5zM134 188v0v0v0z" />
+ <glyph glyph-name="ion-paintbucket" unicode="&#xf4d6;" horiz-adv-x="480"
+d="M112 384l32 32l275 -276l-58 -12l-163 -160l-198 192l152 152zM309 160l-110 110l-110 -110h220zM419 140c0 0 61 -66 61 -99s-27 -60 -61 -60s-60 27 -60 60s60 99 60 99z" />
+ <glyph glyph-name="ion-paper-airplane" unicode="&#xf2c3;"
+d="M0 176l448 240l-112 -448l-112 112l-80 -112l-16 160zM319 31l80 323l-322 -173l83 -31l192 154l-128 -176z" />
+ <glyph glyph-name="ion-paperclip" unicode="&#xf20f;" horiz-adv-x="160"
+d="M149 293c6 0 11 -5 11 -12v-195c0 -28 -10 -49 -24 -63c-15 -15 -36 -23 -56 -23c-40 0 -80 31 -80 88v234c0 24 11 44 29 54s39 11 57 0s29 -30 29 -54l-1 -225c0 -13 -3 -24 -9 -32s-16 -12 -25 -12c-17 0 -34 15 -34 44v173c0 6 6 12 12 12s11 -6 11 -12v-173
+c0 -14 5 -21 11 -21c2 0 5 2 7 4c3 4 5 10 5 17v225c0 15 -6 28 -17 34s-24 6 -35 0s-17 -19 -17 -34v-234c0 -44 29 -64 57 -64s57 19 57 63v195c0 6 6 11 12 11z" />
+ <glyph glyph-name="ion-pause" unicode="&#xf210;" horiz-adv-x="256"
+d="M96 12c0 -7 -5 -12 -12 -12h-72c-7 0 -12 5 -12 12v360c0 7 5 12 12 12h72c7 0 12 -5 12 -12v-360zM244 384c7 0 12 -5 12 -12v-360c0 -7 -5 -12 -12 -12h-72c-7 0 -12 5 -12 12v360c0 7 5 12 12 12h72z" />
+ <glyph glyph-name="ion-person-add" unicode="&#xf211;"
+d="M397 120h-42v51h-51v42h51v51h42v-51h51v-42h-51v-51zM384 0h-192h-192s0 26 2 40c2 11 17 25 81 49c63 23 60 12 60 55c0 28 -14 11 -23 64c-4 21 -6 7 -14 40c-4 17 3 19 2 27s-2 16 -4 33c-2 21 18 76 88 76s90 -55 88 -76c-2 -17 -3 -25 -4 -33s6 -10 2 -27
+c-8 -33 -10 -19 -14 -40c-9 -53 -23 -36 -23 -64c0 -43 -3 -32 60 -55c64 -24 79 -38 81 -49c2 -14 2 -40 2 -40z" />
+ <glyph glyph-name="ion-person-stalker" unicode="&#xf212;"
+d="M393 123c42 -16 52 -26 53 -33c2 -9 2 -90 2 -90h-98c0 18 0 71 -1 77c-1 10 -1 29 -55 50c-8 3 -14 5 -19 7c18 8 15 15 15 28c0 19 -9 11 -15 47c-2 14 -4 5 -9 28c-3 12 1 12 1 18s-1 10 -2 22c-1 14 11 52 57 52s59 -38 58 -52c-1 -12 -2 -16 -2 -22
+c-1 -6 4 -6 1 -18c-5 -23 -7 -14 -9 -28c-6 -36 -16 -28 -16 -47c0 -29 -2 -23 39 -39zM325 0h-163h-162s0 65 2 77c2 10 15 22 69 43c54 20 50 17 50 55c0 24 -12 8 -20 54c-3 18 -5 7 -11 36c-3 15 2 16 1 23s-2 14 -3 29c-2 19 15 67 74 67s77 -49 75 -67
+c-1 -15 -2 -22 -3 -29s5 -8 2 -23c-6 -29 -9 -18 -12 -36c-8 -46 -20 -30 -20 -54c0 -32 -2 -36 31 -48c6 -2 11 -4 19 -7c54 -21 67 -33 69 -43c1 -6 2 -28 2 -47v-30z" />
+ <glyph glyph-name="ion-person" unicode="&#xf213;" horiz-adv-x="384"
+d="M384 0h-192h-192s0 26 2 40c2 11 17 25 81 49c63 23 60 12 60 55c0 28 -14 11 -23 64c-4 21 -6 7 -14 40c-4 17 3 19 2 27s-2 16 -4 33c-2 21 18 76 88 76s90 -55 88 -76c-2 -17 -3 -25 -4 -33s6 -10 2 -27c-8 -33 -10 -19 -14 -40c-9 -53 -23 -36 -23 -64
+c0 -43 -3 -32 60 -55c64 -24 79 -38 81 -49c2 -14 2 -40 2 -40z" />
+ <glyph glyph-name="ion-pie-graph" unicode="&#xf2a5;"
+d="M1 192c0 5 -1 11 -1 16c0 115 93 208 208 208c5 0 11 -1 16 -1v-32v-191h-191h-32zM78 46c-26 32 -42 71 -45 114h223v223c43 -3 82 -19 114 -45c47 -38 78 -96 78 -162c0 -115 -93 -208 -208 -208c-66 0 -124 31 -162 78z" />
+ <glyph glyph-name="ion-pin" unicode="&#xf2a6;" horiz-adv-x="224"
+d="M188 220c20 -10 36 -31 36 -55c0 -17 -3 -21 -15 -21h-81l-12 -176h-8l-12 176h-81c-12 0 -15 5 -15 21c0 24 16 45 36 55v0c1 0 3 1 4 2c7 4 12 11 14 19l18 118v5c0 7 -4 10 -10 13v0c-1 0 -1 1 -2 1c-7 3 -12 9 -12 17c0 20 6 21 18 21h92c12 0 18 -1 18 -21
+c0 -8 -5 -14 -12 -17c-1 0 -1 -1 -2 -1v0c-6 -3 -10 -6 -10 -13v-5l18 -118c2 -8 7 -15 14 -19c1 -1 3 -2 4 -2v0z" />
+ <glyph glyph-name="ion-pinpoint" unicode="&#xf2a7;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c32 32 51 75 55 120l-63 8v16l63 8c-4 45 -23 88 -55 120s-75 51 -120 55l-8 -63h-16l-8 63c-45 -4 -88 -23 -120 -55s-51 -75 -55 -120l63 -8v-16l-63 -8
+c4 -45 23 -88 55 -120s75 -51 120 -55l8 63h16l8 -63c45 4 88 23 120 55z" />
+ <glyph glyph-name="ion-pizza" unicode="&#xf2a8;" horiz-adv-x="352"
+d="M315 318c10 -4 12 -13 9 -20l-148 -330s-143 320 -148 331s2 16 9 19c39 18 90 28 139 28s96 -9 139 -28zM112 256c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM176 109c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM240 224
+c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM342 382c6 -3 10 -6 10 -13c0 -1 0 -3 -1 -5l-8 -19c-3 -5 -8 -9 -14 -9c-1 0 -3 1 -6 2c-41 18 -95 30 -147 30s-102 -11 -147 -30c-3 -1 -4 -2 -6 -2c-6 0 -11 4 -14 9l-8 19s-1 2 -1 5c0 8 6 12 10 14
+c49 21 107 33 166 33s118 -13 166 -34z" />
+ <glyph glyph-name="ion-plane" unicode="&#xf214;"
+d="M250 136c0 -7 1 -69 -6 -102c-1 -4 3 -4 5 -7l51 -33c2 -2 3 -8 3 -8l1 -18l-68 16l-12 -32l-12 32l-68 -16l1 18s0 6 2 8l52 33c2 3 6 3 5 7c-7 33 -6 95 -6 102s-8 5 -8 5l-62 -13l-128 -49c0 23 2 26 9 31l183 131s5 63 5 113c0 24 12 78 27 78s27 -54 27 -78
+c0 -53 5 -113 5 -113l183 -131c6 -4 9 -7 9 -31l-128 49l-62 13s-8 2 -8 -5z" />
+ <glyph glyph-name="ion-planet" unicode="&#xf343;" horiz-adv-x="512"
+d="M96 182c39 -24 85 -48 134 -69c44 -19 87 -35 126 -46c-27 -22 -62 -35 -100 -35c-85 0 -155 66 -160 150zM107 251c1 4 3 8 5 11c10 21 26 40 44 55c27 22 62 35 100 35c85 0 155 -66 160 -150v-10c0 -21 -4 -41 -11 -59c-1 -4 -3 -8 -5 -11c-6 1 -13 3 -19 5
+c-39 11 -82 26 -126 45c-56 24 -108 52 -148 79zM430 163c57 -35 87 -62 81 -82c-4 -12 -19 -17 -44 -17c-50 0 -136 23 -231 64c-141 61 -246 140 -235 175c4 12 20 20 44 17c22 -3 47 -9 73 -18c-8 -9 -8 -12 -14 -22c-23 5 -44 8 -59 8h-6c2 -2 5 -6 8 -9
+c11 -11 27 -24 46 -37c41 -29 97 -59 156 -85c44 -19 89 -35 128 -46c36 -10 68 -15 90 -15h6c-2 2 -5 6 -8 9c-10 10 -24 22 -41 34c4 11 5 12 6 24z" />
+ <glyph glyph-name="ion-play" unicode="&#xf215;" horiz-adv-x="320"
+d="M309 215c7 -6 11 -14 11 -23s-4 -17 -11 -23l-278 -166c-4 -2 -7 -3 -11 -3c-11 0 -20 9 -20 20v0v344v0c0 11 9 20 20 20c4 0 8 -1 11 -3z" />
+ <glyph glyph-name="ion-playstation" unicode="&#xf30a;" horiz-adv-x="512"
+d="M400 245c0 -11 0 -22 -2 -33c-2 -10 -5 -20 -10 -28c-4 -7 -10 -13 -18 -17c-7 -4 -16 -6 -24 -6c-13 0 -31 4 -42 9v131v2c0 9 -7 17 -15 17h-1c-9 0 -16 -8 -16 -17v-3v-300l-80 26v358s28 -4 75 -18s67 -21 84 -31c8 -5 15 -11 21 -17c7 -7 13 -14 17 -23
+c8 -16 10 -33 11 -50zM87 90c-4 -2 -8 -3 -11 -6c-1 -1 -3 -3 -2 -5s4 -4 6 -5c6 -2 13 -3 19 -3c7 0 15 0 22 2c5 1 9 3 14 5c30 10 41 12 41 12v-42c-14 -2 -36 -4 -50 -4c-30 -1 -60 4 -88 13c-9 3 -19 6 -27 12c-4 3 -8 8 -10 13c-2 4 -1 9 1 13s5 8 9 11
+c9 6 18 10 28 14c8 4 17 7 26 10c35 12 111 37 111 37v-47s-62 -20 -89 -30zM512 102c0 -5 -2 -9 -5 -13c-6 -7 -14 -11 -22 -15s-17 -8 -26 -11c-54 -19 -171 -59 -171 -59v48s92 30 133 44c6 2 11 4 16 8c2 2 4 3 3 6c-1 2 -4 4 -6 5c-6 2 -13 3 -19 3
+c-10 0 -20 -2 -30 -5c-29 -10 -97 -32 -97 -32v49s45 14 67 16c8 1 23 1 31 1c26 0 54 -3 79 -11c5 -2 8 -3 14 -5c9 -3 18 -8 25 -14c4 -4 8 -9 8 -15z" />
+ <glyph glyph-name="ion-plus-circled" unicode="&#xf216;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM352 176v32h-112v112h-32v-112h-112v-32h112v-112h32v112h112z" />
+ <glyph glyph-name="ion-plus-round" unicode="&#xf217;" horiz-adv-x="384"
+d="M353 224c17 0 31 -14 31 -32s-14 -32 -31 -32h-129v-129c0 -17 -14 -31 -32 -31s-32 14 -32 31v129h-129c-17 0 -31 14 -31 32s14 32 31 32h129v129c0 17 14 31 32 31s32 -14 32 -31v-129h129z" />
+ <glyph glyph-name="ion-plus" unicode="&#xf218;" horiz-adv-x="384"
+d="M384 224v-64h-160v-160h-64v160h-160v64h160v160h64v-160h160z" />
+ <glyph glyph-name="ion-podium" unicode="&#xf344;"
+d="M0 0v192h128v-192h-128zM160 0v288h128v-288h-128zM320 0v128h128v-128h-128z" />
+ <glyph glyph-name="ion-pound" unicode="&#xf219;"
+d="M93 96h-93v54h101l13 84h-99v54h107l22 128h64l-22 -128h106l22 128h63l-22 -128h93v-54h-102l-12 -84h99v-54h-107l-22 -128h-63l22 128h-107l-22 -128h-63zM177 234l-12 -84h106l12 84h-106v0z" />
+ <glyph glyph-name="ion-power" unicode="&#xf2a9;"
+d="M224 192c-18 0 -32 14 -32 32v160c0 18 14 32 32 32s32 -14 32 -32v-160c0 -18 -14 -32 -32 -32zM347 379c61 -40 101 -109 101 -187c0 -124 -100 -224 -224 -224s-224 100 -224 224c0 78 40 147 101 187v0c5 3 11 5 17 5c18 0 32 -14 32 -32c0 -6 -2 -12 -5 -17
+c-2 -3 -4 -6 -7 -8c-1 -1 -3 -2 -4 -3c-8 -6 -16 -12 -23 -19c-30 -30 -47 -70 -47 -113s17 -83 47 -113s70 -47 113 -47s83 17 113 47s47 70 47 113s-17 83 -47 113c-7 7 -15 13 -23 19c-1 1 -3 2 -4 3c-3 2 -5 5 -7 8c-3 5 -5 11 -5 17c0 18 14 32 32 32c6 0 12 -2 17 -5
+v0z" />
+ <glyph glyph-name="ion-pricetag" unicode="&#xf2aa;"
+d="M439 187c12 -12 12 -31 0 -43l-165 -167c-11 -11 -30 -11 -42 -1l-3 3l-206 209l-6 5c-6 7 -9 15 -10 24v0v2v0l-7 98v4v0c0 12 4 24 13 33l49 49c8 9 20 13 31 13h4l100 -4v0c12 0 22 -4 30 -12v0l2 -2v0l210 -211v0v0zM112 256c26 0 48 22 48 48s-22 48 -48 48
+s-48 -22 -48 -48s22 -48 48 -48z" />
+ <glyph glyph-name="ion-pricetags" unicode="&#xf2ab;"
+d="M440 209c10 -11 11 -28 0 -39l-29 -29c11 11 10 28 0 39v0v0l-190 191v0l-1 1h-1c-8 7 -16 12 -27 12v0l-90 3h-4c-9 0 -19 -3 -26 -10l28 27c8 8 17 12 27 12h4l90 -4v0c11 0 19 -4 27 -11h1l1 -1v0l190 -191v0v0zM396 166v0c11 -11 11 -29 0 -40l-108 -109v1l-26 -27
+l-2 -2l-13 -13c-10 -10 -26 -10 -37 -1l-3 3l-186 188l-5 5c-5 6 -9 14 -10 22v0v2v0l-6 88v3v1c0 11 4 21 12 29l44 45l1 1l1 1c7 6 17 9 26 9h4l90 -3v0c11 0 19 -4 27 -11v0l2 -1v0l189 -191v0zM79 308c-12 -8 -21 -21 -21 -37c0 -24 19 -43 43 -43c16 0 29 9 37 21
+c4 7 7 14 7 22c0 24 -20 44 -44 44c-8 0 -15 -3 -22 -7z" />
+ <glyph glyph-name="ion-printer" unicode="&#xf21a;"
+d="M392 320c28 0 56 -19 56 -55v-131c0 -31 -28 -54 -56 -54h-40v-112h-8h-8h-224h-11h-5v112h-40c-28 0 -56 24 -56 62v123c0 38 28 55 56 55h40v64h256v-64h40zM336 -16v176h-224v-176h224zM336 320v48h-224v-48h224zM384 256v16h-17v-16h17zM128 112v16h192v-16h-192z
+M128 64v16h192v-16h-192zM128 16v16h192v-16h-192z" />
+ <glyph glyph-name="ion-pull-request" unicode="&#xf345;" horiz-adv-x="384"
+d="M64 384c35 0 64 -29 64 -64c0 -24 -13 -44 -32 -55v-178c19 -11 32 -31 32 -55c0 -35 -29 -64 -64 -64s-64 29 -64 64c0 24 13 44 32 55v178c-19 11 -32 31 -32 55c0 35 29 64 64 64zM64 0c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM64 288
+c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM351 88c20 -11 33 -32 33 -56c0 -35 -29 -64 -64 -64s-64 29 -64 64c0 23 12 44 31 55v156c0 16 -4 26 -11 33c-10 9 -26 12 -52 12v-64l-96 96l96 96v-64c42 1 74 -8 96 -29c21 -19 31 -46 31 -80v-155z
+M320 0c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32z" />
+ <glyph glyph-name="ion-qr-scanner" unicode="&#xf346;" horiz-adv-x="416"
+d="M48 324v-68h-48v68c0 33 28 60 61 60h67v-48h-68c-7 0 -12 -5 -12 -12zM356 384c33 0 60 -27 60 -60v-68h-48v68c0 7 -6 12 -13 12h-67v48h68zM368 61v67h48v-67c0 -33 -27 -61 -60 -61h-68v49h68c7 0 12 5 12 12zM60 49h68v-49h-67c-33 0 -61 28 -61 61v67h48v-67
+c0 -7 5 -12 12 -12z" />
+ <glyph glyph-name="ion-quote" unicode="&#xf347;" horiz-adv-x="384"
+d="M128 384c-41 0 -73 -11 -95 -33s-33 -54 -33 -95v-256h160v256h-96c0 23 5 39 15 49s26 15 49 15zM352 384c-41 0 -73 -11 -95 -33s-33 -54 -33 -95v-256h160v256h-96c0 23 5 39 15 49s26 15 49 15z" />
+ <glyph glyph-name="ion-radio-waves" unicode="&#xf2ac;"
+d="M160 192c0 43 21 64 64 64s64 -21 64 -64s-21 -64 -64 -64s-64 21 -64 64zM112 192c0 -18 5 -35 13 -50s19 -28 33 -37l-23 -25c-6 5 -13 10 -18 16c-25 26 -37 59 -37 96s12 70 37 96c5 6 12 11 18 16l23 -25c-14 -9 -25 -22 -33 -37s-13 -32 -13 -50zM336 192
+c0 18 -5 35 -13 50s-19 28 -33 37l23 25c6 -5 13 -10 18 -16c25 -26 37 -59 37 -96s-12 -70 -37 -96c-5 -6 -12 -11 -18 -16l-23 25c14 9 25 22 33 37s13 32 13 50zM32 192c0 -27 6 -53 17 -77s27 -43 47 -59l-23 -24c-6 5 -12 10 -17 16c-18 19 -31 41 -41 65
+c-10 25 -15 51 -15 79s5 54 15 79c10 24 23 46 41 65c5 6 11 11 17 16l23 -24c-10 -8 -18 -17 -26 -27s-14 -21 -20 -32s-10 -24 -13 -37s-5 -26 -5 -40zM416 192c0 27 -6 53 -17 77s-27 43 -47 59l23 24c6 -5 12 -10 17 -16c18 -19 31 -41 41 -65c10 -25 15 -51 15 -79
+s-5 -54 -15 -79c-10 -24 -23 -46 -41 -65c-4 -5 -10 -10 -17 -16l-23 24c20 16 36 35 47 59s17 50 17 77z" />
+ <glyph glyph-name="ion-record" unicode="&#xf21b;" horiz-adv-x="416"
+d="M208 -16c-115 0 -208 93 -208 208s93 208 208 208s208 -93 208 -208s-93 -208 -208 -208z" />
+ <glyph glyph-name="ion-refresh" unicode="&#xf21c;"
+d="M352 96l-104 112h74c-7 65 -64 112 -130 112c-71 0 -128 -57 -128 -128s57 -128 128 -128c28 0 53 8 75 24l6 5l43 -46l-7 -6c-34 -26 -74 -41 -117 -41c-91 0 -167 64 -187 149v0c0 1 -1 2 -1 3v1v2s-1 2 -1 3v1c0 1 -1 3 -1 4v0c-1 6 -2 13 -2 19v1v4v5v5v4v1
+c0 6 1 13 2 19v0c0 1 1 3 1 4v1c0 1 1 1 1 2v3v1c0 1 1 2 1 3v0c20 85 96 149 187 149v0v0c11 0 21 -1 31 -3h2h2c57 -10 106 -47 133 -96c13 -23 21 -49 23 -77h65z" />
+ <glyph glyph-name="ion-reply-all" unicode="&#xf21d;" horiz-adv-x="416"
+d="M257 256c153 0 159 -208 159 -208c-51 93 -91 102 -159 102v-92l-152 134l152 144v-80zM0 192l144 136v-57l-82 -79l82 -68v-58z" />
+ <glyph glyph-name="ion-reply" unicode="&#xf21e;" horiz-adv-x="384"
+d="M384 48c-53 93 -122 102 -224 102v-92l-160 134l160 144v-80c187 0 224 -208 224 -208z" />
+ <glyph glyph-name="ion-ribbon-a" unicode="&#xf348;" horiz-adv-x="352"
+d="M272 416l80 -96l-64 -134c-24 30 -59 49 -99 53zM80 416l83 -177c-40 -4 -75 -23 -99 -53l-64 134zM189 416h67l-53 -112h-27h-27l-53 112h80h13zM176 224c71 0 128 -57 128 -128s-57 -128 -128 -128s-128 57 -128 128s57 128 128 128zM176 0c53 0 96 43 96 96
+s-43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96zM176 184c49 0 88 -39 88 -88s-39 -88 -88 -88s-88 39 -88 88s39 88 88 88z" />
+ <glyph glyph-name="ion-ribbon-b" unicode="&#xf349;" horiz-adv-x="384"
+d="M192 376c49 0 88 -39 88 -88s-39 -88 -88 -88s-88 39 -88 88s39 88 88 88zM192 416c71 0 128 -57 128 -128s-57 -128 -128 -128s-128 57 -128 128s57 128 128 128zM192 192c53 0 96 43 96 96s-43 96 -96 96s-96 -43 -96 -96s43 -96 96 -96zM83 194c26 -30 65 -50 109 -50
+c12 0 23 1 34 4l-34 -74l-48 -106l-48 80h-96zM301 194l83 -146h-96l-48 -80l-40 88l45 98c22 9 41 23 56 40z" />
+ <glyph glyph-name="ion-sad-outline" unicode="&#xf4d7;"
+d="M367 164c3 -9 -2 -17 -11 -19c-3 -1 -7 0 -10 1c-5 2 -9 5 -11 10s-4 12 -13 15s-14 0 -19 -3c-4 -3 -10 -3 -15 -1c-3 1 -7 3 -9 6c-6 8 -3 17 5 22c15 9 29 13 49 6s29 -21 34 -37zM165 195c8 -5 10 -14 4 -22c-2 -3 -6 -5 -9 -6c-5 -2 -11 -2 -15 1c-5 3 -10 6 -19 3
+s-11 -10 -13 -15s-6 -8 -11 -10c-3 -1 -7 -2 -10 -1c-9 2 -14 10 -11 19c5 16 14 30 34 37s35 3 50 -6zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56
+s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136s85 -56 136 -56s100 20 136 56zM317 89c5 -7 3 -17 -4 -22c-3 -2 -6 -3 -9 -3c-5 0 -10 3 -13 7c0 0 -19 25 -67 25s-67 -25 -67 -25c-3 -4 -8 -7 -13 -7c-3 0 -6 1 -9 3c-7 5 -9 15 -4 22c1 2 28 39 93 39
+s92 -37 93 -39z" />
+ <glyph glyph-name="ion-sad" unicode="&#xf34a;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM113 156c2 5 4 12 13 15s14 0 19 -3c4 -3 10 -3 15 -1c3 1 7 3 9 6c6 8 4 17 -4 22c-15 9 -30 13 -50 6s-29 -21 -34 -37c-3 -9 2 -17 11 -19c3 -1 7 0 10 1c5 2 9 5 11 10z
+M313 67c7 5 9 15 4 22c-1 2 -28 39 -93 39s-92 -37 -93 -39c-5 -7 -3 -17 4 -22c3 -2 6 -3 9 -3c5 0 10 3 13 7c0 0 19 25 67 25s67 -25 67 -25c3 -4 8 -7 13 -7c3 0 6 1 9 3zM356 145c9 2 14 10 11 19c-5 16 -14 30 -34 37s-34 3 -49 -6c-8 -5 -11 -14 -5 -22
+c2 -3 6 -5 9 -6c5 -2 11 -2 15 1c5 3 10 6 19 3s11 -10 13 -15s6 -8 11 -10c3 -1 7 -2 10 -1z" />
+ <glyph glyph-name="ion-scissors" unicode="&#xf34b;" horiz-adv-x="384"
+d="M341 332c-13 -33 -117 -172 -117 -172l-32 -32s-31 -13 -50 -43s-33 -71 -33 -71v0c-7 -26 -28 -46 -53 -46c-31 0 -56 29 -56 64s25 64 56 64c13 0 25 -5 34 -13c2 -1 3 -3 4 -4v0l2 -2c4 -4 7 -2 14 11c8 15 17 35 27 54s38 59 38 59l17 23l144 192
+c23 -20 18 -51 5 -84zM56 0c15 0 28 14 28 32s-13 32 -28 32s-28 -14 -28 -32s13 -32 28 -32zM192 160c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM143 183c-30 41 -90 125 -100 149c-13 33 -18 64 5 84l134 -178l-3 -4v0v0l-17 -23v-1v0
+c-1 -1 -10 -13 -19 -27zM328 96c31 0 56 -29 56 -64s-25 -64 -56 -64c-25 0 -47 20 -54 46v0s-13 41 -32 71c-11 17 -26 28 -36 35l29 29l1 1h1c1 1 1 2 2 4c3 -4 5 -9 7 -12c10 -19 20 -39 28 -54c7 -13 10 -15 14 -11c1 1 0 1 1 2h1c1 1 2 3 4 4c9 8 21 13 34 13zM328 0
+c15 0 28 14 28 32s-13 32 -28 32s-28 -14 -28 -32s13 -32 28 -32z" />
+ <glyph glyph-name="ion-search" unicode="&#xf21f;" horiz-adv-x="384"
+d="M381 61c4 -4 4 -10 0 -14l-43 -44c-2 -2 -5 -3 -8 -3s-5 1 -7 3l-84 86c-25 -15 -52 -23 -80 -23c-87 0 -159 71 -159 159s72 159 159 159s158 -71 158 -159c0 -27 -7 -54 -21 -78zM159 322c-53 0 -97 -43 -97 -97s44 -97 97 -97s96 43 96 97s-43 97 -96 97z" />
+ <glyph glyph-name="ion-settings" unicode="&#xf2ad;" horiz-adv-x="416"
+d="M402 310c10 -6 15 -25 14 -36c-1 -17 -7 -36 -25 -54c-1 -1 -2 -1 -3 -2c-26 -25 -62 -30 -94 -20c-1 1 -2 2 -4 2c-5 1 -10 0 -13 -4l-36 -39c52 -50 107 -96 107 -96c2 -2 2 -5 0 -7l-50 -51c-2 -2 -5 -2 -7 0c0 0 -44 55 -93 107l-92 -98c-14 -16 -40 -15 -55 0
+c-15 16 -15 42 1 56l97 93l-12 12c-2 2 -3 7 -1 10l2 5c-25 26 -36 33 -56 32s-36 -13 -48 -28s-10 -52 -8 -62s-7 -6 -12 0c-9 10 -23 50 -6 93s42 69 48 75s16 15 24 21s21 -1 27 5c4 4 5 11 5 16l-4 4c-2 2 -2 5 0 7l31 31c2 2 5 2 7 0l50 -50c2 -2 2 -6 0 -8l-31 -31
+c-2 -2 -5 -2 -7 0l-8 9c-7 0 -15 -5 -17 -10c-3 -6 -6 -21 -3 -33c3 -11 13 -20 36 -43l5 3c4 2 8 1 10 -1c0 0 1 -2 13 -14l38 37c4 3 5 7 4 13c0 2 0 4 -1 5c-10 33 -6 69 19 96l2 2c18 18 36 25 53 26c10 1 30 -5 35 -15l-48 -48l-2 -3l-1 -1c-1 -1 -1 -2 -1 -4
+s0 -3 1 -5l2 -2l2 -2l41 -42l3 -3l1 -1c1 -1 2 -1 4 -1s3 0 4 1l2 1l2 3z" />
+ <glyph glyph-name="ion-share" unicode="&#xf220;" horiz-adv-x="384"
+d="M288 70v59l38 31v-109c0 -11 -8 -19 -19 -19h-288c-11 0 -19 9 -19 19v218c0 11 8 19 19 19h120c-29 -18 -43 -38 -43 -38h-58v-180h250zM256 224c-84 0 -116 -24 -160 -96c0 0 5 164 160 164v60l128 -96l-128 -96v64z" />
+ <glyph glyph-name="ion-shuffle" unicode="&#xf221;"
+d="M338 267c-52 0 -83 -43 -120 -92c-41 -55 -88 -120 -171 -120h-47v63h47c52 0 84 47 121 96c41 55 87 116 170 116h29v54l81 -81l-81 -84v48h-29zM121 230c-21 21 -42 35 -74 36c-34 1 -47 0 -47 0v63h47c48 0 83 -20 113 -48c-10 -12 -19 -24 -28 -36
+c-4 -5 -7 -10 -11 -15zM367 118v47l81 -84l-81 -81v54h-29c-50 0 -87 23 -117 53c12 14 22 28 32 41c2 3 5 6 7 9c22 -24 46 -39 78 -39h29z" />
+ <glyph glyph-name="ion-skip-backward" unicode="&#xf222;" horiz-adv-x="384"
+d="M12 352h8c7 0 12 -5 12 -12v-113l187 122c2 2 5 3 8 3c8 0 16 -7 16 -17v-63l118 78c2 2 5 2 8 2c8 0 15 -7 15 -17v-286c0 -10 -7 -17 -15 -17c-3 0 -5 1 -8 3l-118 78v-64c0 -10 -8 -17 -16 -17c-3 0 -5 1 -8 3l-187 122v-113c0 -7 -5 -12 -12 -12h-8
+c-7 0 -12 5 -12 12v296c0 7 5 12 12 12z" />
+ <glyph glyph-name="ion-skip-forward" unicode="&#xf223;" horiz-adv-x="384"
+d="M372 352c7 0 12 -5 12 -12v-296c0 -7 -5 -12 -12 -12h-8c-7 0 -12 5 -12 12v113l-187 -122c-3 -2 -5 -3 -8 -3c-8 0 -15 7 -15 17v64l-119 -78c-3 -2 -5 -3 -8 -3c-8 0 -15 7 -15 17v286c0 10 7 17 15 17c3 0 6 0 8 -2l119 -78v63c0 10 7 17 15 17c3 0 6 -1 8 -3
+l187 -122v113c0 7 5 12 12 12h8z" />
+ <glyph glyph-name="ion-social-android-outline" unicode="&#xf224;" horiz-adv-x="352"
+d="M272 240h-192v-60v-89h24h16v-15v-52c0 -4 4 -8 8 -8s8 4 8 8v52v15h17h49h15v-15v-52c0 -2 1 -4 3 -6h1v0c1 -1 2 -2 4 -2h1v0v0c4 0 7 4 7 8v52v15h17h22v89v60zM288 256v0v-76v-90c0 -7 -3 -15 -10 -15h-29v-51c0 -13 -10 -24 -23 -24v0h-1c-6 0 -11 2 -15 5
+c-5 4 -9 11 -9 19v51h-49v-51c0 -13 -11 -24 -24 -24s-24 11 -24 24v51h-28c-7 0 -12 8 -12 15v90v76h224zM328 256c-4 0 -8 -4 -8 -8v-96c0 -4 4 -8 8 -8s8 4 8 8v96c0 4 -4 8 -8 8zM328 272v0c13 0 24 -11 24 -24v-96c0 -13 -11 -24 -24 -24s-24 11 -24 24v96
+c0 13 11 24 24 24zM24 256c-4 0 -8 -4 -8 -8v-96c0 -4 4 -8 8 -8s8 4 8 8v96c0 4 -4 8 -8 8zM24 272v0c13 0 24 -11 24 -24v-96c0 -13 -11 -24 -24 -24s-24 11 -24 24v96c0 13 11 24 24 24zM175 354c-14 0 -27 -3 -38 -6l-10 -4c-28 -12 -40 -37 -44 -56h186
+c-4 18 -15 43 -44 56l-10 4c-12 4 -25 6 -39 6v0v0h-1zM105 384v0h1l19 -23c13 5 30 9 50 9h1c20 0 36 -4 50 -9l20 23v0s1 -1 2 -1c1 -1 2 -3 2 -3l-19 -22c48 -21 56 -71 57 -86h-224c1 15 9 66 57 87l-19 22c0 1 1 1 2 2zM127 309c-7 0 -14 6 -14 13s6 14 14 14
+c7 0 13 -7 13 -14s-5 -13 -13 -13zM225 309c-7 0 -13 6 -13 13s5 14 13 14c7 0 13 -7 13 -14s-6 -13 -13 -13z" />
+ <glyph glyph-name="ion-social-android" unicode="&#xf225;" horiz-adv-x="352"
+d="M64 180v76h224v-76v-90c0 -7 -4 -14 -11 -14h-28v-52c0 -13 -11 -24 -24 -24v0h-1c-6 0 -10 2 -14 5c-5 4 -9 11 -9 19v52h-49v-52c0 -13 -11 -24 -24 -24s-24 11 -24 24v52h-29c-7 0 -11 7 -11 14v90zM328 272c13 0 24 -11 24 -24v-96c0 -13 -11 -24 -24 -24
+s-24 11 -24 24v96c0 13 11 24 24 24zM24 272c13 0 24 -11 24 -24v-96c0 -13 -11 -24 -24 -24s-24 11 -24 24v96c0 13 11 24 24 24zM231 359c48 -21 56 -72 57 -87h-224c1 15 8 66 56 87l-18 22c0 1 0 1 1 2s3 1 3 1l19 -23c14 5 31 9 51 9s36 -4 50 -9l20 23c0 1 1 0 2 -1
+l2 -2zM127 309c8 0 13 6 13 13s-6 14 -13 14c-8 0 -14 -7 -14 -14s7 -13 14 -13zM225 309c7 0 14 6 14 13s-7 14 -14 14c-8 0 -13 -7 -13 -14s6 -13 13 -13z" />
+ <glyph glyph-name="ion-social-angular-outline" unicode="&#xf4d8;"
+d="M224 384l-188 -69l39 -230l149 -80l149 80l39 230zM224 416v0l224 -80l-46 -272l-178 -96l-178 96l-46 272zM312 96l-27 56h-122l-27 -56h-40l128 280l128 -280h-40zM182 192h84l-42 89z" />
+ <glyph glyph-name="ion-social-angular" unicode="&#xf4d9;"
+d="M182 192l42 89l42 -89h-84zM224 416l224 -80l-46 -272l-178 -96l-178 96l-46 272zM312 96h40l-128 280l-128 -280h40l27 56h122z" />
+ <glyph glyph-name="ion-social-apple-outline" unicode="&#xf226;" horiz-adv-x="320"
+d="M238 278c-15 0 -26 -4 -37 -8c-10 -4 -21 -8 -35 -8s-25 4 -37 8c-11 4 -22 8 -34 8c-11 0 -23 -3 -34 -10c-12 -7 -23 -18 -31 -31c-12 -18 -16 -47 -13 -77c3 -34 16 -69 35 -99c13 -21 30 -45 50 -45h1c8 0 13 3 20 6c10 5 23 10 44 10v0c21 0 34 -5 44 -10
+c7 -3 12 -6 19 -6v0c22 0 44 35 52 48c8 12 12 20 17 31c-12 7 -22 16 -30 28c-10 15 -17 33 -18 52c-1 18 2 37 10 53c6 12 14 22 24 30c-14 13 -31 20 -47 20zM238 294v0c25 0 52 -14 71 -39c-63 -36 -53 -128 11 -153c-9 -20 -13 -28 -24 -46c-16 -25 -37 -56 -65 -56h-1
+c-24 0 -31 16 -63 16v0c-33 0 -40 -16 -64 -16h-1c-28 0 -48 28 -64 53c-44 69 -48 150 -21 193c19 30 50 48 78 48c29 0 47 -16 71 -16c23 0 38 16 72 16zM214 364c-11 -5 -21 -13 -28 -22c-4 -5 -9 -13 -13 -23c-1 -3 -2 -6 -2 -9c11 4 21 11 28 21c4 5 12 18 15 33z
+M230 384v0c3 -23 -6 -46 -18 -62c-13 -17 -35 -30 -56 -30h-1c-4 22 6 44 18 60c14 17 37 31 57 32z" />
+ <glyph glyph-name="ion-social-apple" unicode="&#xf227;" horiz-adv-x="320"
+d="M238 294v0c25 0 52 -14 71 -39c-63 -36 -53 -128 11 -153c-9 -20 -13 -28 -24 -46c-16 -25 -37 -56 -65 -56h-1c-24 0 -31 16 -63 16v0c-33 0 -40 -16 -64 -16h-1c-28 0 -48 28 -64 53c-44 69 -48 150 -21 193c19 30 50 48 78 48c29 0 47 -16 71 -16c23 0 38 16 72 16z
+M230 384v0c3 -23 -6 -46 -18 -62c-13 -17 -35 -30 -56 -30h-1c-4 22 6 44 18 60c14 17 37 31 57 32z" />
+ <glyph glyph-name="ion-social-bitcoin-outline" unicode="&#xf2ae;" horiz-adv-x="320"
+d="M184 400h-8v-48v-16h-16h-32h-16v16v48h-9v-48v-16h-16h-72v-16h13c11 0 19 0 25 -3s10 -7 13 -13s3 -8 3 -20v-178c0 -11 0 -18 -3 -24v-1c-1 -3 -4 -10 -12 -14h-1c-5 -3 -8 -3 -17 -3h-13l-3 -16h67h16v-16v-48h9v48v16h16h32h16v-16v-48h8v49v16h15c23 1 41 5 55 10
+c16 6 28 15 37 26c8 11 12 29 13 42c1 14 -1 29 -4 36s-8 16 -21 23c-7 4 -14 6 -21 8l-46 11l43 19c4 2 7 4 12 9c6 5 9 12 11 16c2 5 4 13 3 22c-1 17 -4 29 -10 37c-7 9 -17 16 -31 21c-12 5 -24 7 -41 8l-15 1v15v47zM200 416v0v-63c20 -1 32 -4 45 -9
+c16 -6 29 -15 38 -27s12 -28 13 -45c1 -10 0 -20 -3 -28s-8 -16 -16 -23c-6 -6 -11 -9 -16 -11c9 -2 17 -6 25 -10c15 -8 24 -18 29 -30c4 -10 6 -30 5 -44c-1 -16 -6 -37 -16 -51c-11 -14 -26 -24 -45 -31c-15 -6 -33 -10 -59 -11v-65h-40v64h-32v-64h-41v64h-87l8 48h28
+c9 0 8 1 11 2s4 3 5 6s1 9 1 18v178c0 9 0 10 -1 12s-3 4 -6 6s-9 2 -18 2h-28v48h87v64h41v-64h32v64h40zM160 298v-74h-32v74h32zM160 176v0v-90h-32v90h32zM200 294v0c6 -2 10 -7 14 -12c4 -6 6 -13 6 -21s-2 -15 -7 -21c-4 -5 -7 -9 -13 -12v66zM200 174v0
+c5 -1 8 -1 12 -3c8 -3 14 -7 19 -13s8 -15 8 -24c0 -11 -2 -19 -10 -26s-13 -11 -23 -15c-2 -1 -4 0 -6 -1v82z" />
+ <glyph glyph-name="ion-social-bitcoin" unicode="&#xf2af;" horiz-adv-x="320"
+d="M314 169c4 -10 7 -30 6 -44c-1 -16 -5 -37 -16 -51s-26 -24 -45 -31c-15 -6 -33 -10 -59 -11v-64h-40v64h-32v-64h-41v64h-87l9 48h26c9 0 9 0 12 1s4 4 5 7s2 8 2 17v173c0 9 -1 16 -2 18s-3 4 -6 6s-9 2 -18 2h-28v48h87v64h41v-64h32v64h40v-64c20 -1 33 -4 46 -9
+c16 -6 28 -15 37 -27s12 -28 13 -45c1 -10 0 -20 -3 -28c-2 -8 -8 -16 -16 -23c-6 -6 -11 -9 -16 -11c9 -2 17 -6 25 -10c15 -8 23 -18 28 -30zM128 298v-74h32v74h-32zM128 86h32v90h-32v-90zM200 294v-66c6 3 9 7 13 12c5 6 7 12 7 20s-2 15 -6 21c-4 5 -8 11 -14 13z
+M229 107c8 7 10 15 10 26c0 9 -3 19 -8 25s-12 10 -20 13c-4 2 -6 2 -11 3v-82c2 0 5 1 7 2c10 4 14 6 22 13z" />
+ <glyph glyph-name="ion-social-buffer-outline" unicode="&#xf228;" horiz-adv-x="384"
+d="M7 284c-9 4 -9 11 0 15l169 82c4 2 10 3 16 3s12 -1 16 -3l169 -82c9 -4 9 -11 0 -15l-169 -82c-4 -2 -10 -3 -16 -3s-12 1 -16 3zM183 366l-156 -75l156 -75c2 -1 5 -1 9 -1s7 0 9 1l156 75l-156 75c-2 1 -5 2 -9 2s-7 -1 -9 -2zM377 200c9 -4 9 -12 0 -16l-169 -81
+c-4 -2 -10 -4 -16 -4s-12 2 -16 4l-169 81c-9 4 -9 12 0 16c0 0 27 13 33 16c5 3 7 3 13 0s123 -60 123 -60c4 -2 10 -3 16 -3s12 1 16 3c0 0 121 59 125 61s5 2 9 0s35 -17 35 -17zM201 117l156 75l-19 9l-123 -59c-6 -3 -15 -5 -23 -5s-17 2 -23 5l-123 59l-19 -9l156 -75
+c2 -1 5 -2 9 -2s7 1 9 2zM377 100c9 -4 9 -11 0 -15l-169 -82c-4 -2 -10 -3 -16 -3s-12 1 -16 3l-169 82c-9 4 -9 11 0 15c0 0 27 14 33 17c5 3 7 2 13 -1s123 -59 123 -59c4 -2 10 -3 16 -3s12 1 16 3c0 0 121 58 125 60s5 2 9 0s35 -17 35 -17zM201 18l156 75l-19 9
+l-123 -60c-6 -3 -15 -4 -23 -4s-17 1 -23 4l-123 60l-19 -9l156 -75c2 -1 5 -2 9 -2s7 1 9 2z" />
+ <glyph glyph-name="ion-social-buffer" unicode="&#xf229;" horiz-adv-x="384"
+d="M7 284c-9 4 -9 11 0 15l169 82c4 2 10 3 16 3s12 -1 16 -3l169 -82c9 -4 9 -11 0 -15l-169 -82c-4 -2 -10 -3 -16 -3s-12 1 -16 3zM377 200c9 -4 9 -12 0 -16l-169 -81c-4 -2 -10 -4 -16 -4s-12 2 -16 4l-169 81c-9 4 -9 12 0 16c0 0 27 13 33 16c5 3 7 3 13 0
+s123 -60 123 -60c4 -2 10 -3 16 -3s12 1 16 3c0 0 121 59 125 61s5 2 9 0s35 -17 35 -17zM377 100c9 -4 9 -11 0 -15l-169 -82c-4 -2 -10 -3 -16 -3s-12 1 -16 3l-169 82c-9 4 -9 11 0 15c0 0 27 14 33 17c5 3 7 2 13 -1s123 -59 123 -59c4 -2 10 -3 16 -3s12 1 16 3
+c0 0 121 58 125 60s5 2 9 0s35 -17 35 -17z" />
+ <glyph glyph-name="ion-social-chrome-outline" unicode="&#xf4da;"
+d="M224 416c123 0 224 -101 224 -224s-101 -224 -224 -224s-224 101 -224 224s101 224 224 224zM224 371c-57 0 -109 -27 -141 -68l54 -93c8 40 43 72 87 72h155c-30 54 -89 89 -155 89zM291 192c0 37 -30 67 -67 67s-67 -30 -67 -67s30 -67 67 -67s67 30 67 67zM45 192
+c0 -91 67 -166 154 -177l54 93c-9 -3 -19 -6 -29 -6c-34 0 -61 18 -77 45v0l-78 135c-16 -27 -24 -58 -24 -90zM224 13c99 0 179 80 179 179c0 24 -4 46 -13 67h-108c19 -17 32 -40 32 -67c0 -17 -5 -32 -13 -45v0z" />
+ <glyph glyph-name="ion-social-chrome" unicode="&#xf4db;"
+d="M157 192c0 37 30 67 67 67s67 -30 67 -67s-30 -67 -67 -67s-67 30 -67 67zM445 230c2 -12 3 -25 3 -38c0 -106 -74 -195 -174 -218c-10 -2 -20 -4 -30 -5c-7 -1 -13 -1 -20 -1c-8 0 -17 0 -25 1v0v0v0v1l102 177c8 13 13 28 13 45c0 27 -13 50 -32 67h156
+c3 -9 5 -19 7 -29v0c-2 10 -4 20 -7 29v0c3 -9 5 -19 7 -29v0zM224 103c10 0 20 2 29 5l-78 -135v0c-42 9 -79 30 -108 59c-42 41 -67 97 -67 160c0 31 6 61 18 88c7 16 16 31 26 45v0l103 -178c16 -27 43 -44 77 -44zM59 343v0v1c24 26 55 47 90 59c23 8 49 13 75 13
+c73 0 138 -36 179 -90h1c10 -14 18 -29 25 -44v0c-7 15 -15 30 -25 44h-1c10 -14 19 -29 26 -44h-205c-44 0 -79 -32 -87 -72z" />
+ <glyph glyph-name="ion-social-codepen-outline" unicode="&#xf4dc;"
+d="M356 244c5 -3 7 -6 7 -12v-81c0 -6 -3 -10 -8 -13c-41 -27 -82 -55 -123 -82c-6 -4 -11 -4 -17 0c-41 27 -81 55 -122 82c-5 3 -8 7 -8 13v80c0 6 3 11 8 14c41 27 81 54 122 81c6 4 11 4 17 0c41 -27 83 -55 124 -82zM236 296v-54c0 -1 1 -2 2 -3c16 -11 31 -21 47 -32
+c1 -1 3 -1 4 0l40 26zM212 295c0 0 -62 -41 -93 -62c14 -9 27 -17 40 -26c1 -1 3 -1 4 0c15 10 31 21 46 31c1 1 3 4 3 6v51zM109 211v-40l30 20zM212 87v53c0 1 -2 3 -3 4c-15 10 -31 21 -46 31c-2 1 -3 1 -5 0l-39 -26c31 -21 93 -62 93 -62zM227 165l39 26s-34 23 -40 27
+c-1 1 -4 0 -5 -1c-5 -3 -9 -6 -14 -9c-8 -6 -25 -17 -25 -17l39 -26c2 -1 4 -1 6 0zM236 87l93 62l-38 26c-2 2 -5 2 -7 0c-15 -10 -30 -21 -45 -31c-2 -2 -3 -3 -3 -6v-51zM338 171v40l-30 -20zM224 384c-51 0 -100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136
+s85 -56 136 -56s100 20 136 56s56 85 56 136s-20 100 -56 136s-85 56 -136 56zM224 416v0c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224z" />
+ <glyph glyph-name="ion-social-codepen" unicode="&#xf4dd;"
+d="M209 144c1 -1 3 -3 3 -4v-53s-62 41 -93 62l39 26c2 1 3 1 5 0c15 -10 31 -21 46 -31zM163 207c-1 -1 -3 -1 -4 0c-13 9 -26 17 -40 26c31 21 93 62 93 62v-51c0 -2 -2 -5 -3 -6c-15 -10 -31 -21 -46 -31zM238 239c-1 1 -2 2 -2 3v54l93 -63l-40 -26c-1 -1 -3 -1 -4 0
+c-16 11 -31 21 -47 32zM226 218c6 -4 40 -27 40 -27l-39 -26c-2 -1 -4 -1 -6 0l-39 26s17 11 25 17c5 3 9 6 14 9c1 1 4 2 5 1zM109 211l30 -20l-30 -20v40zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM363 151v81
+c0 6 -2 9 -7 12c-41 27 -83 55 -124 82c-6 4 -11 4 -17 0c-41 -27 -81 -54 -122 -81c-5 -3 -8 -8 -8 -14v-80c0 -6 3 -10 8 -13c41 -27 81 -55 122 -82c6 -4 11 -4 17 0c41 27 82 55 123 82c5 3 8 7 8 13zM284 175c2 2 5 2 7 0l38 -26l-93 -62v51c0 3 1 4 3 6
+c15 10 30 21 45 31zM338 171l-30 20l30 20v-40z" />
+ <glyph glyph-name="ion-social-css3-outline" unicode="&#xf4de;" horiz-adv-x="384"
+d="M291 81l-99 -28l-98 28l-7 78h48l4 -40l53 -15v0v0l54 15l5 64h-112l-4 50h121l4 51h-184l-4 49h241zM0 416h384l-35 -403l-157 -45l-157 45zM319 37l30 347h-314l30 -347l127 -36z" />
+ <glyph glyph-name="ion-social-css3" unicode="&#xf4df;" horiz-adv-x="384"
+d="M192 109v0zM0 416h384l-35 -403l-157 -45l-157 45zM291 81l22 252h-241l4 -49h184l-4 -51h-121l4 -50h112l-5 -64l-54 -15v0v0l-53 15l-4 40h-48l7 -78l98 -28z" />
+ <glyph glyph-name="ion-social-designernews-outline" unicode="&#xf22a;"
+d="M259 302v-53l-65 103zM0 188zM297 352l151 -119v-201h-248l-200 156h63c46 0 77 33 77 82c0 20 -5 37 -15 51l-3 3l37 -29v-107h41l-2 98l63 -98h36v84v80zM432 48v178l-119 92v1v-47v-83v-17h-15h-37h-9l-4 8l-33 50l1 -42v-16h-16h-41h-16v16v29c-3 -6 -7 -12 -12 -17
+c-8 -9 -18 -16 -30 -21s-24 -7 -38 -7h-16l159 -124h226zM59 298h-1h-3v-57h4c8 0 13 2 17 6c5 6 6 15 6 22c0 26 -12 29 -23 29zM59 314v0c25 0 39 -16 39 -45c0 -28 -14 -44 -40 -44h-19v89h20z" />
+ <glyph glyph-name="ion-social-designernews" unicode="&#xf22b;"
+d="M258 303l1 -53l-64 102zM297 352l151 -118v-202h-248l-200 157v0h63c46 0 77 33 77 82c0 20 -5 37 -15 51l-3 3l37 -29v-107h40l-2 99l64 -99h36v83v80zM98 270c0 -28 -14 -44 -40 -44h-19v89h19c26 0 40 -16 40 -45z" />
+ <glyph glyph-name="ion-social-dribbble-outline" unicode="&#xf22c;" horiz-adv-x="384"
+d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM314 296c-17 -25 -47 -47 -85 -64c5 -10 9 -20 13 -31c33 3 75 4 110 2c-2 35 -16 68 -38 93zM192 352c-14 0 -26 -2 -39 -5c23 -23 43 -53 62 -87c34 14 62 33 79 55
+c-28 23 -63 37 -102 37zM120 334c-41 -21 -71 -58 -83 -103h25c44 0 85 6 121 17c-19 34 -40 63 -63 86zM32 200v-8c0 -40 15 -78 40 -106c24 45 67 83 122 106c4 2 8 3 14 4c-3 8 -6 16 -10 24c-40 -13 -88 -20 -138 -21c-9 0 -19 1 -28 1zM192 32c20 0 39 3 57 10
+c-3 25 -8 53 -15 79c-4 17 -10 33 -16 49c-7 -2 -13 -4 -17 -6c-48 -22 -86 -56 -107 -98c27 -21 61 -34 98 -34zM278 58c40 26 68 67 73 116c-30 2 -68 3 -99 0c4 -12 9 -25 12 -38c7 -27 11 -52 14 -78z" />
+ <glyph glyph-name="ion-social-dribbble" unicode="&#xf22d;" horiz-adv-x="384"
+d="M192 384c106 0 192 -86 192 -192s-86 -192 -192 -192s-192 86 -192 192s86 192 192 192zM192 32c88 0 160 72 160 160s-72 160 -160 160s-160 -72 -160 -160s72 -160 160 -160zM242 201c-4 11 -8 21 -13 31c25 11 47 24 63 39c15 -19 26 -42 28 -67c-26 0 -55 -1 -78 -3z
+M271 292c-15 -12 -34 -23 -56 -32c-12 22 -24 41 -38 59c5 1 10 1 15 1c30 0 57 -11 79 -28zM142 310c15 -18 28 -39 41 -62c-34 -10 -72 -16 -113 -17c11 36 38 65 72 79zM319 176c-4 -33 -21 -63 -46 -83c-3 14 -5 28 -9 43c-3 13 -8 26 -12 38c21 2 45 3 67 2zM194 192
+c-43 -18 -79 -46 -104 -78c-16 22 -26 49 -26 78v7c49 1 95 8 134 21c4 -8 7 -16 10 -24c-6 -1 -10 -2 -14 -4zM219 170c6 -16 11 -32 15 -49c4 -15 7 -31 10 -46c-16 -7 -34 -11 -52 -11c-31 0 -59 11 -81 29c22 30 53 54 90 71c4 2 11 4 18 6z" />
+ <glyph glyph-name="ion-social-dropbox-outline" unicode="&#xf22e;" horiz-adv-x="384"
+d="M113 371l79 -66l-114 -71l-78 63zM27 295l52 -42l86 53l-53 46zM306 235l78 -63l-78 -51v-39l-114 -69l-114 68v39l-78 52l78 63l114 -71l-79 -66l-19 12v-20l98 -59l98 59v20l-19 -12l-79 66zM79 217l-52 -44l85 -55l53 44zM219 162l53 -44l85 56l-52 43zM384 297
+l-78 -63l-114 71l79 66zM219 305l86 -52l52 42l-85 56z" />
+ <glyph glyph-name="ion-social-dropbox" unicode="&#xf22f;" horiz-adv-x="384"
+d="M113 371l79 -66l-114 -71l-78 63zM0 172l78 62l114 -70l-79 -66zM192 164l114 70l78 -62l-113 -74zM384 297l-78 -63l-114 71l79 66zM192 150l80 -66l34 22v-25l-114 -68l-114 68v25l34 -22z" />
+ <glyph glyph-name="ion-social-euro-outline" unicode="&#xf4e0;" horiz-adv-x="320"
+d="M214 384c-53 0 -91 -9 -115 -27c-22 -16 -33 -40 -33 -74v-11v-17h-16h-34v-16h34h16v-15v-48v-17h-16h-34v-16h34h16v-15v-27c0 -34 11 -58 33 -74c24 -18 62 -27 115 -27c31 0 59 2 88 8l-5 35c-30 -4 -55 -7 -80 -7c-36 0 -59 6 -74 19c-19 16 -21 40 -21 60v13v15h16
+h103l3 16h-106h-16v17v48v15h16h118l2 16h-120h-16v17v2c0 16 2 39 21 55c16 13 39 19 74 19c24 0 51 -3 80 -7l5 35c-29 6 -57 8 -88 8zM214 400v0c35 0 68 -3 106 -12l-9 -65c-37 6 -68 9 -94 9c-64 0 -79 -22 -79 -58v-3h139l-8 -48h-131v-48h124l-7 -48h-117v-12
+c0 -44 15 -63 79 -63c26 0 57 3 94 9l9 -65c-38 -9 -71 -12 -106 -12c-115 0 -164 41 -164 117v26h-50v48h50v48h-50v48h50v12c0 76 49 117 164 117z" />
+ <glyph glyph-name="ion-social-euro" unicode="&#xf4e1;" horiz-adv-x="320"
+d="M138 176h124l-7 -48h-117v-13c0 -44 15 -63 79 -63c26 0 56 3 93 9l10 -65c-38 -9 -71 -12 -106 -12c-115 0 -164 41 -164 117v27h-50v48h50v48h-50v48h50v11c0 76 49 117 164 117c35 0 68 -3 106 -12l-10 -65c-37 6 -67 9 -93 9c-64 0 -79 -22 -79 -58v-2h138l-7 -48
+h-131v-48z" />
+ <glyph glyph-name="ion-social-facebook-outline" unicode="&#xf230;" horiz-adv-x="192"
+d="M128 256h64l-8 -64h-56v-192h-83v192h-45v64h45v43c0 54 23 85 91 85h56v-64h-34c-27 0 -30 -9 -30 -26v-38zM170 208l4 32h-45h-17v17v37c0 10 1 21 9 30c10 11 25 12 37 12h18v32h-40c-28 0 -49 -6 -60 -18c-10 -11 -15 -27 -15 -51v-43v-16h-15h-30v-32h30h15v-16
+v-176h51v176v16h17h41z" />
+ <glyph glyph-name="ion-social-facebook" unicode="&#xf231;" horiz-adv-x="192"
+d="M128 256h64l-8 -64h-56v-192h-83v192h-45v64h45v43c0 54 23 85 91 85h56v-64h-34c-27 0 -30 -9 -30 -26v-38z" />
+ <glyph glyph-name="ion-social-foursquare-outline" unicode="&#xf34c;" horiz-adv-x="320"
+d="M302 284c-12 -60 -25 -131 -27 -138zM281 416c35 0 45 -20 37 -57c-3 -16 -10 -44 -16 -75l-27 -137c-3 -13 -8 -35 -39 -35h-72c-3 0 -3 0 -6 -3c-2 -2 -115 -133 -115 -133c-9 -10 -23 -8 -28 -6s-15 8 -15 26v380s10 40 43 40h238zM280 352c6 31 6 32 -24 32h-195
+c-29 0 -29 -3 -29 -28v-297c0 -38 1 -38 3 -38s10 8 29 31c0 0 78 89 79 90c2 2 3 2 6 2h62c26 0 28 6 33 31c4 21 36 177 36 177zM302 284c6 31 13 59 16 75zM233 352c5 0 9 -5 8 -11l-8 -44c-1 -4 -6 -9 -11 -9h-75c-8 0 -8 -5 -8 -13v-6c0 -8 0 -13 8 -13h64
+s11 -6 10 -12s-11 -51 -12 -54s-4 -9 -11 -9h-62c-9 0 -11 -1 -17 -8l-54 -63c-1 -1 -1 -1 -1 0v231c0 5 5 11 11 11h158z" />
+ <glyph glyph-name="ion-social-foursquare" unicode="&#xf34d;" horiz-adv-x="320"
+d="M281 416c35 0 45 -20 37 -57c-10 -49 -40 -202 -43 -213c-3 -13 -8 -34 -39 -34h-72c-3 0 -3 0 -6 -3c-2 -2 -115 -133 -115 -133c-9 -10 -23 -8 -28 -6s-15 8 -15 26v380s10 40 43 40h238zM275 146c3 11 33 164 43 213zM267 351c2 9 -5 16 -12 16h-191
+c-9 0 -15 -8 -15 -15v-296c0 -1 1 -1 2 0c0 0 70 84 78 94s11 11 23 11h64c9 0 14 8 15 12s8 43 10 51s-6 16 -13 16h-82c-10 0 -18 8 -18 18v13c0 10 8 17 18 17h96s14 6 15 12z" />
+ <glyph glyph-name="ion-social-freebsd-devil" unicode="&#xf2c4;" horiz-adv-x="512"
+d="M503 333c19 -37 8 -81 -20 -108s-60 -33 -60 -33c2 -32 16 -59 -41 -102c-43 -32 2 -90 2 -90c10 -14 23 -19 32 -32h-272s15 14 -7 32c0 0 -20 17 -18 29s6 13 9 15s0 7 0 7l-19 19s-13 -13 -44 -13c-38 0 -65 39 -65 39h46s-6 -8 -7 -13c-1 -4 1 -5 1 -5s11 -6 22 -6
+c17 0 33 12 33 12l-24 22l-15 -4l-16 37l39 -10l-1 -15l28 -18s9 9 7 27s-9 26 -9 26s-4 0 -9 -4s-6 -6 -6 -6l-10 44s43 -19 50 -63c3 -20 -6 -35 -6 -35l17 -10s6 5 17 7s23 2 29 -8s5 -12 4 -19s0 -9 6 -11s6 -6 11 -8s15 -6 21 -2s8 11 8 18v16s-9 8 -32 20
+s-54 22 -66 40s-12 44 0 57c9 10 23 25 26 35c4 14 4 42 4 42s-10 16 -8 40c2 30 22 84 96 114c0 0 -40 -55 -20 -80c0 0 37 11 77 9c31 -2 56 -12 73 -28s25 -23 47 -17s28 17 28 33c0 19 -16 51 -16 51s36 -7 58 -51zM195 245c14 4 21 -11 21 -11c14 25 30 60 22 64
+s-64 -25 -66 -88c0 0 6 31 23 35zM232 230c5 7 34 8 37 -17c4 -35 -24 -57 -24 -57s7 -2 23 2c17 4 43 29 43 70s-21 66 -41 62s-38 -60 -38 -60z" />
+ <glyph glyph-name="ion-social-github-outline" unicode="&#xf232;"
+d="M224 416c124 0 224 -103 224 -230c0 -101 -64 -188 -153 -218h-4c-8 0 -12 7 -12 12c0 8 1 31 1 62c0 21 -8 36 -16 43c50 6 103 25 103 113c0 25 -9 46 -23 62c2 6 10 29 -2 61h-5c-8 0 -27 -3 -57 -24c-18 5 -37 8 -56 8s-38 -3 -56 -8c-30 21 -49 24 -57 24h-5
+c-12 -32 -4 -55 -2 -61c-14 -16 -23 -37 -23 -62c0 -88 52 -107 102 -113c-6 -6 -12 -16 -14 -31c-6 -3 -16 -6 -26 -6c-13 0 -28 5 -39 25c0 0 -13 22 -35 24v0c-2 0 -21 0 -1 -14c0 0 15 -8 25 -34c0 0 10 -33 53 -33c7 0 14 0 22 2v-39c0 -5 -3 -11 -11 -11h-4
+c-89 30 -153 116 -153 218c0 127 100 230 224 230zM146 -0c-15 0 -28 4 -38 9c14 -10 28 -17 44 -23v6v8h-6zM157 73c-16 4 -35 10 -52 24c6 -6 11 -11 13 -16c7 -12 14 -17 25 -17c4 0 9 1 12 2c1 2 1 5 2 7zM347 14c17 13 32 28 45 46c26 37 40 80 40 126
+c0 29 -5 58 -16 84c-10 25 -26 48 -45 68s-41 34 -66 45c-26 11 -53 17 -81 17s-55 -6 -81 -17c-25 -11 -47 -25 -66 -45s-35 -42 -45 -68c-11 -26 -16 -55 -16 -84c0 -46 14 -89 40 -126c10 -14 22 -27 35 -38c-7 8 -11 16 -13 22c-7 18 -15 24 -17 25h-2v1
+c-5 3 -20 13 -15 28c3 9 12 15 25 15h1v0v0c13 -1 24 -6 32 -13c-21 19 -37 48 -37 98c0 24 7 47 21 66c-3 13 -6 34 5 62l3 8l7 2c2 0 5 1 10 1c12 0 31 -3 60 -22c17 4 35 6 53 6v0v0c18 0 36 -2 53 -6c29 19 48 22 60 22c5 0 8 -1 10 -1l7 -2l3 -7c11 -27 8 -50 5 -63
+c14 -19 21 -41 21 -66c0 -92 -55 -117 -92 -125c3 -8 5 -18 5 -30v-51v-6c18 7 35 16 51 28z" />
+ <glyph glyph-name="ion-social-github" unicode="&#xf233;"
+d="M224 416c124 0 224 -103 224 -230c0 -101 -64 -188 -153 -218h-4c-8 0 -12 7 -12 12c0 8 1 31 1 62c0 21 -8 36 -16 43c50 6 103 25 103 113c0 25 -9 46 -23 62c2 6 10 29 -2 61h-5c-8 0 -27 -3 -57 -24c-18 5 -37 8 -56 8s-38 -3 -56 -8c-30 21 -49 24 -57 24h-5
+c-12 -32 -4 -55 -2 -61c-14 -16 -23 -37 -23 -62c0 -88 52 -107 102 -113c-6 -6 -12 -16 -14 -31c-6 -3 -16 -6 -26 -6c-13 0 -28 5 -39 25c0 0 -13 22 -35 24v0c-2 0 -21 0 -1 -14c0 0 15 -8 25 -34c0 0 10 -33 53 -33c7 0 14 0 22 2v-39c0 -5 -3 -11 -11 -11h-4
+c-89 30 -153 116 -153 218c0 127 100 230 224 230z" />
+ <glyph glyph-name="ion-social-google-outline" unicode="&#xf34e;" horiz-adv-x="256"
+d="M191 366c12 -10 37 -30 37 -68c0 -37 -21 -55 -43 -72c-7 -7 -15 -13 -15 -24s8 -17 14 -22l18 -14c23 -19 43 -36 43 -71c0 -47 -47 -95 -135 -95c-74 0 -110 35 -110 72c0 18 10 44 40 62c32 19 75 21 98 23c-7 9 -16 18 -16 34c0 9 2 14 5 20c-6 0 -11 -1 -16 -1
+c-54 0 -85 40 -85 79c0 23 11 48 33 67c29 24 63 28 91 28h106l-33 -18h-32zM155 142c-4 1 -7 1 -12 1s-32 -1 -54 -8c-11 -4 -44 -16 -44 -52s36 -62 91 -62c49 0 75 24 75 55c0 26 -17 39 -56 66zM170 238c12 12 13 28 13 37c0 36 -22 92 -65 92c-13 0 -28 -6 -36 -16
+c-9 -11 -11 -25 -11 -38c0 -34 20 -89 64 -89c13 0 27 6 35 14z" />
+ <glyph glyph-name="ion-social-google" unicode="&#xf34f;" horiz-adv-x="288"
+d="M210 172c22 -18 45 -36 45 -73c0 -49 -48 -99 -140 -99c-80 0 -115 39 -115 77c0 10 3 42 42 65c27 16 61 20 85 22c-4 7 -8 16 -8 27c0 4 0 7 1 10h-4c-19 0 -46 4 -67 26c-15 15 -24 36 -24 57c0 26 13 53 35 71v0c32 25 70 29 95 29h133l-60 -33h-13
+c11 -13 23 -31 23 -58c0 -40 -25 -59 -45 -74v-1c-6 -6 -11 -10 -11 -17c0 -6 4 -10 10 -15v0zM85 308c0 -13 4 -33 14 -51c7 -12 20 -27 41 -27c10 0 21 4 28 11c10 10 10 25 10 30c0 18 -6 38 -15 54c-7 13 -20 27 -40 27c-11 0 -22 -5 -29 -13c-6 -7 -9 -18 -9 -31z
+M206 80c0 20 -13 31 -50 56c-3 0 -4 1 -8 1c-6 0 -32 -2 -51 -8c-16 -6 -37 -16 -37 -42c0 -31 32 -51 80 -51c41 0 66 17 66 44z" />
+ <glyph glyph-name="ion-social-googleplus-outline" unicode="&#xf234;"
+d="M192 366c12 -10 36 -30 36 -68c0 -37 -21 -55 -43 -72c-7 -7 -15 -13 -15 -24s8 -18 14 -22l18 -14c23 -19 43 -36 43 -71c0 -47 -47 -95 -135 -95c-74 0 -110 35 -110 72c0 18 10 44 40 62c32 19 75 21 98 23c-7 9 -16 18 -16 34c0 9 3 14 5 20c-6 0 -11 -1 -16 -1
+c-54 0 -85 40 -85 79c0 23 10 48 32 67c29 24 64 28 92 28h106l-33 -18h-31zM155 142c-4 0 -7 1 -12 1s-32 -1 -54 -8c-11 -4 -44 -16 -44 -52s36 -62 91 -62c49 0 75 24 75 55c0 26 -17 39 -56 66zM170 238c12 12 13 28 13 37c0 36 -22 92 -65 92c-13 0 -28 -6 -36 -16
+c-9 -11 -11 -24 -11 -37c0 -34 20 -90 64 -90c13 0 27 6 35 14zM448 306v-18h-78v-81h-18v81h-80v18h80v78h18v-78h78z" />
+ <glyph glyph-name="ion-social-googleplus" unicode="&#xf235;"
+d="M210 172c22 -18 45 -36 45 -73c0 -49 -47 -99 -139 -99c-80 0 -116 39 -116 77c0 10 3 42 42 65c27 16 61 21 85 23c-4 7 -8 15 -8 26c0 4 0 7 1 10h-4c-19 0 -46 4 -67 26c-15 15 -24 36 -24 57c0 26 13 53 35 71v0c32 25 69 29 94 29h134l-60 -33h-13
+c11 -13 23 -31 23 -58c0 -40 -25 -59 -45 -74v-1c-6 -6 -11 -10 -11 -17c0 -6 4 -10 10 -15v0zM85 308c0 -13 4 -33 14 -51c7 -12 21 -27 41 -27c10 0 21 4 28 11c10 10 10 25 10 30c0 18 -6 37 -15 53c-8 13 -20 28 -40 28c-11 0 -23 -5 -29 -13c-6 -7 -9 -18 -9 -31z
+M206 80c0 20 -13 31 -50 56c-3 0 -4 1 -8 1c-6 0 -31 -2 -50 -8c-16 -6 -38 -16 -38 -42c0 -31 32 -51 80 -51c41 0 66 17 66 44zM370 306h78v-34h-78v-81h-34v81h-80v34h80v78h34v-78z" />
+ <glyph glyph-name="ion-social-hackernews-outline" unicode="&#xf236;" horiz-adv-x="384"
+d="M352 352h-320v-320h320v320zM384 384v0v-384h-384v384h384zM233 289h45l-64 -120v-72h-40v72l-66 120h47l40 -84z" />
+ <glyph glyph-name="ion-social-hackernews" unicode="&#xf237;" horiz-adv-x="384"
+d="M0 384h384v-384h-384v384zM214 169l64 120h-45l-38 -84l-40 84h-47l66 -120v-72h40v72z" />
+ <glyph glyph-name="ion-social-html5-outline" unicode="&#xf4e2;" horiz-adv-x="384"
+d="M0 416h384l-35 -403l-157 -45l-157 45zM319 37l30 347h-314l30 -347l127 -36zM84 184l-13 150h241l-4 -50h-184l4 -51h176l-14 -151l-98 -28l-99 28l-6 77h48l3 -39l54 -15l53 15l6 64h-167z" />
+ <glyph glyph-name="ion-social-html5" unicode="&#xf4e3;" horiz-adv-x="384"
+d="M0 416h384l-35 -403l-157 -45l-157 45zM308 284l4 50h-241l13 -150h167l-6 -64l-53 -15l-54 15l-3 39h-48l6 -78l99 -27l98 28l14 151h-176l-4 51h184z" />
+ <glyph glyph-name="ion-social-instagram-outline" unicode="&#xf350;" horiz-adv-x="384"
+d="M384 336v-289c0 -26 -22 -47 -48 -47h-288c-26 0 -48 21 -48 47v289c0 26 22 48 48 48h288c26 0 48 -22 48 -48zM192 272c-44 0 -80 -36 -80 -80s36 -80 80 -80s80 36 80 80s-36 80 -80 80zM352 288v48c0 9 -7 16 -16 16h-48c-9 0 -16 -7 -16 -16v-48c0 -9 7 -16 16 -16
+h48c9 0 16 7 16 16zM337 32c9 0 15 7 15 16v176h-52c3 -10 4 -21 4 -32c0 -30 -11 -58 -32 -79s-50 -33 -80 -33s-58 12 -79 33s-33 49 -33 79c0 11 2 22 5 32h-53v-176c0 -9 8 -16 17 -16h288z" />
+ <glyph glyph-name="ion-social-instagram" unicode="&#xf351;" horiz-adv-x="384"
+d="M112 192c0 53 27 80 80 80s80 -27 80 -80s-27 -80 -80 -80s-80 27 -80 80zM113 271c-14 -14 -23 -29 -28 -47h-85v112c0 13 4 25 14 34s22 14 35 14h288c13 0 24 -5 33 -14s14 -21 14 -34v-112h-84c-5 18 -14 33 -28 47c-22 22 -49 33 -80 33s-57 -11 -79 -33zM352 300
+v39c0 4 -2 7 -4 9s-5 4 -9 4h-38c-4 0 -7 -2 -9 -4s-4 -5 -4 -9v-39c0 -4 2 -7 4 -9s5 -3 9 -3h38c4 0 7 1 9 3s4 5 4 9zM272 113c22 22 32 48 32 79h80v-144c0 -13 -5 -24 -14 -34s-20 -14 -33 -14h-288c-13 0 -24 4 -34 14s-15 21 -15 34v144h81c0 -31 10 -57 32 -79
+s48 -33 79 -33s58 11 80 33z" />
+ <glyph glyph-name="ion-social-javascript-outline" unicode="&#xf4e4;"
+d="M160 344h-48v-196c0 -30 -6 -50 -17 -64c-11 -13 -26 -20 -48 -20c-9 0 -18 1 -25 2l-4 -30c11 -2 25 -4 37 -4c34 0 59 8 76 25c19 18 29 48 29 90v197zM176 360v0v-213c0 -97 -49 -131 -121 -131c-18 0 -40 3 -55 8l8 62c10 -4 24 -6 39 -6c31 0 49 15 49 68v212h80z
+M350 352c-34 0 -62 -9 -82 -26c-19 -15 -28 -36 -28 -60c0 -20 7 -36 21 -51c14 -14 34 -26 61 -36c23 -8 38 -15 48 -24c12 -11 18 -23 18 -38c0 -16 -7 -31 -20 -40c-12 -9 -28 -14 -48 -14c-28 0 -52 8 -70 15l-7 -32c18 -8 44 -14 72 -14c38 0 70 9 90 27
+c18 16 27 38 27 63c0 21 -5 36 -17 50s-31 27 -58 37v0v0c-38 15 -72 28 -72 63c0 14 7 27 19 36c11 9 26 13 45 13c24 0 43 -5 57 -11l10 32c-19 6 -42 10 -66 10zM350 368v0c38 0 65 -7 85 -16l-19 -64c-13 7 -35 17 -67 17s-48 -16 -48 -33c0 -22 19 -31 62 -48
+c58 -22 85 -53 85 -102c0 -57 -42 -106 -133 -106c-38 0 -72 10 -91 21l15 63v0c20 -11 49 -21 81 -21c34 0 52 15 52 38c0 21 -15 33 -55 47c-55 20 -93 52 -93 102c0 58 49 102 126 102z" />
+ <glyph glyph-name="ion-social-javascript" unicode="&#xf4e5;"
+d="M176 360v0v-213c0 -97 -49 -131 -121 -131c-18 0 -40 3 -55 8l8 62c10 -4 24 -6 39 -6c31 0 49 15 49 68v212h80zM350 368v0c38 0 65 -7 85 -16l-19 -64c-13 7 -35 17 -67 17s-48 -16 -48 -33c0 -22 19 -31 62 -48c58 -22 85 -53 85 -102c0 -57 -42 -106 -133 -106
+c-38 0 -72 10 -91 21l15 63v0c20 -11 49 -21 81 -21c34 0 52 15 52 38c0 21 -15 33 -55 47c-55 20 -93 52 -93 102c0 58 49 102 126 102z" />
+ <glyph glyph-name="ion-social-linkedin-outline" unicode="&#xf238;" horiz-adv-x="384"
+d="M119 64v0h-55v171h55v-171zM93 261v0v0c-18 0 -29 13 -29 29c0 17 12 30 30 30s29 -13 29 -30c0 -16 -12 -29 -30 -29zM257 239c36 0 63 -24 63 -75v-100h-55v94c0 22 -8 37 -28 37c-15 0 -24 -10 -28 -20c-2 -4 -2 -9 -2 -14v-97h-55v171h55v-24c8 11 21 28 50 28z
+M353 384c18 0 31 -13 31 -30v-321c0 -17 -13 -33 -31 -33h-320c-18 0 -33 16 -33 33v321c0 17 15 30 33 30h320zM350 32c1 0 2 1 2 2v316c0 1 -1 2 -2 2h-316s-2 -1 -2 -2v-315s1 -3 3 -3h315z" />
+ <glyph glyph-name="ion-social-linkedin" unicode="&#xf239;" horiz-adv-x="384"
+d="M353 384c18 0 31 -13 31 -30v-321c0 -17 -13 -33 -31 -33h-320c-18 0 -33 16 -33 33v321c0 17 15 30 33 30h320zM119 64v171h-55v-171h55zM93 261c18 0 30 13 30 29c0 17 -11 30 -29 30s-30 -13 -30 -30c0 -16 11 -29 29 -29v0zM320 64v100c0 51 -27 75 -63 75
+c-29 0 -42 -17 -50 -28v24h-55v-171h55v97c0 5 0 10 2 14c4 10 13 20 28 20c20 0 28 -15 28 -37v-94h55z" />
+ <glyph glyph-name="ion-social-markdown" unicode="&#xf4e6;"
+d="M416 352c18 0 32 -14 32 -32v-256c0 -18 -14 -32 -32 -32h-384c-18 0 -32 14 -32 32v256c0 18 14 32 32 32h384zM252 96v0v192h-56l-42 -68l-42 68h-56v-192h56v96l42 -54l42 54v-96h56zM336 96v0l70 96h-42v96h-56v-96h-42z" />
+ <glyph glyph-name="ion-social-nodejs" unicode="&#xf4e7;" horiz-adv-x="384"
+d="M192 -32c-6 0 -12 2 -17 5l-53 32c-8 5 -4 6 -1 7c11 4 14 5 25 12c1 1 3 1 4 0l39 -23c1 -1 4 -1 5 0l156 92c1 1 2 2 2 4v187c0 2 0 4 -2 5l-156 94c-1 1 -3 1 -4 0l-155 -94c-2 -1 -3 -3 -3 -5v-187c0 -2 0 -3 2 -4l40 -24c24 -12 38 1 38 15v183c0 3 2 5 5 5h22
+c3 0 5 -2 5 -5v-183c0 -33 -19 -52 -49 -52c-9 0 -17 1 -37 11l-41 24c-10 6 -17 18 -17 30v190c0 12 7 24 17 30l158 95c10 6 24 6 34 0l158 -95c10 -6 17 -18 17 -30v-190c0 -12 -7 -24 -17 -30l-158 -94c-5 -3 -11 -5 -17 -5v0zM241 96c-65 0 -84 31 -84 59c0 3 1 5 4 5
+h21c2 0 5 -2 5 -4c3 -22 16 -31 54 -31c33 0 47 11 47 29c0 11 -3 18 -55 23c-43 4 -71 15 -71 51c0 33 28 52 73 52c46 0 76 -14 79 -51c0 -1 -1 -2 -2 -3s-2 -2 -3 -2h-20c-2 0 -5 2 -5 4c-4 17 -16 23 -49 23c-36 0 -41 -12 -41 -22c0 -12 5 -16 54 -23s72 -16 72 -51
+c0 -36 -29 -59 -79 -59v0v0z" />
+ <glyph glyph-name="ion-social-octocat" unicode="&#xf4e8;"
+d="M146 161c9 0 16 -4 22 -13s10 -20 10 -32s-4 -22 -10 -31s-14 -13 -22 -13c-9 0 -17 4 -23 13s-9 19 -9 31s3 24 9 32c6 9 14 13 23 13zM303 161c9 0 16 -4 22 -13s9 -20 9 -32s-3 -22 -9 -31s-13 -13 -22 -13s-18 4 -24 13s-9 19 -9 31s3 24 9 32c6 9 15 13 24 13z
+M414 276c24 -27 34 -66 34 -96c0 -24 -1 -46 -6 -65c-6 -19 -13 -35 -21 -47c-9 -12 -19 -23 -32 -32s-24 -17 -34 -21s-22 -8 -36 -10c-13 -2 -24 -4 -31 -4c0 0 -28 -1 -64 -1s-64 1 -64 1c-7 0 -18 2 -31 4c-14 2 -26 6 -36 10s-22 12 -34 21c-13 9 -23 20 -32 32
+c-8 12 -15 28 -21 47c-5 19 -6 41 -6 65c0 31 10 70 34 96c0 0 -2 14 0 39s7 48 16 69c30 -3 67 -20 112 -51c15 4 36 6 62 6c28 0 48 -2 62 -6c20 14 39 24 58 33c19 8 33 13 41 15s13 3 13 3c9 -21 14 -44 16 -69s0 -39 0 -39v0zM348 42c28 13 42 40 42 81
+c0 24 -8 43 -26 59c-9 9 -20 13 -32 15s-31 1 -56 -1s-40 -4 -52 -4s-25 2 -42 3s-30 3 -39 3c-10 0 -20 1 -31 -2s-21 -7 -28 -14c-17 -15 -25 -35 -25 -59c0 -41 13 -68 41 -81c27 -13 69 -18 123 -18h2c54 0 95 5 123 18z" />
+ <glyph glyph-name="ion-social-pinterest-outline" unicode="&#xf2b0;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c36 36 56 85 56 136s-20 100 -56 136s-85 56 -136 56s-100 -20 -136 -56s-56 -85 -56 -136s20 -100 56 -136c14 -14 31 -25 48 -34c1 6 2 10 3 16c4 18 29 122 29 122
+s-8 15 -8 36c0 33 20 58 44 58c20 0 30 -16 30 -34c0 -20 -13 -51 -20 -79c-6 -24 12 -43 35 -43c42 0 71 54 71 119c0 49 -33 85 -93 85c-68 0 -110 -50 -110 -107c0 -20 6 -33 15 -44c4 -5 5 -6 3 -12c-1 -4 -4 -14 -5 -18c-2 -6 -6 -8 -11 -6c-31 13 -46 48 -46 86
+c0 64 54 140 160 140c86 0 142 -63 142 -129c0 -88 -49 -153 -121 -153c-24 0 -47 13 -55 28c0 0 -12 -52 -15 -62c-2 -6 -4 -13 -7 -19c15 -4 31 -6 47 -6c51 0 100 20 136 56z" />
+ <glyph glyph-name="ion-social-pinterest" unicode="&#xf2b1;"
+d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224c-22 0 -44 3 -64 9c8 14 18 31 23 48c3 10 16 62 16 62c8 -15 30 -28 54 -28c72 0 121 65 121 153c0 66 -56 129 -142 129c-106 0 -160 -76 -160 -140c0 -39 15 -73 46 -86c5 -2 10 0 12 6c1 4 3 14 4 18
+c2 6 1 7 -3 12c-9 11 -15 24 -15 44c0 57 42 107 110 107c60 0 94 -36 94 -85c0 -65 -29 -119 -71 -119c-24 0 -42 19 -36 43c7 28 20 59 20 79c0 18 -10 34 -30 34c-24 0 -43 -25 -43 -58c0 -21 7 -36 7 -36s-25 -104 -29 -122c-4 -17 -5 -35 -4 -51
+c-79 35 -134 113 -134 205c0 124 100 224 224 224z" />
+ <glyph glyph-name="ion-social-python" unicode="&#xf4e9;" horiz-adv-x="384"
+d="M129 199c-29 -5 -49 -30 -49 -57v-43v-3h-15c-29 0 -54 29 -62 69c-2 9 -3 17 -3 27v1c0 53 29 95 65 95h127v16h-96v29c0 26 7 40 46 47c13 2 29 4 45 4s39 -1 55 -4c25 -4 46 -22 46 -47v-57v-31c0 -21 -14 -38 -33 -43c-4 -1 -8 -2 -13 -2h-104h3c-4 0 -8 0 -12 -1z
+M140 321c10 0 17 7 17 17s-7 18 -17 18s-18 -8 -18 -18s8 -17 18 -17zM380 225c3 -10 4 -21 4 -33c0 -16 -3 -30 -7 -43c-11 -31 -33 -53 -58 -53h-127v-16h96v-26c0 -26 -23 -40 -46 -47c-35 -10 -68 -9 -97 0c-25 7 -49 22 -49 47v54v33c0 21 14 36 33 41c4 1 8 2 13 2
+h104c3 0 6 1 9 1c27 4 49 28 49 62v38v3h15c28 0 52 -26 61 -63zM244 65c-10 0 -18 -7 -18 -17s8 -18 18 -18s17 8 17 18s-7 17 -17 17z" />
+ <glyph glyph-name="ion-social-reddit-outline" unicode="&#xf23a;" horiz-adv-x="449"
+d="M259 160c0 21 11 31 32 31s32 -10 32 -31s-11 -32 -32 -32s-32 11 -32 32zM127 160c0 21 11 31 32 31s32 -10 32 -31s-11 -32 -32 -32s-32 11 -32 32zM449 197c0 -20 -9 -36 -27 -45c1 -5 1 -9 1 -14c0 -38 -19 -71 -58 -98s-85 -40 -140 -40s-102 13 -141 40
+s-58 59 -58 97c0 5 0 10 1 15c-18 9 -27 24 -27 45c0 14 5 25 15 35s21 15 35 15c13 0 24 -4 33 -13c36 25 79 39 129 41h7l29 98l86 -17c8 19 21 28 41 28c12 0 22 -4 31 -13s13 -20 13 -32s-4 -23 -13 -32s-19 -13 -31 -13s-23 4 -32 13s-13 19 -13 31l-69 14l-24 -77
+c50 -2 94 -16 129 -41c10 9 21 13 34 13c9 0 16 -3 24 -7s14 -10 18 -18s7 -16 7 -25zM375 366c-4 0 -8 -1 -11 -2s-6 -4 -8 -6s-5 -6 -6 -9s-2 -6 -2 -10c0 -8 3 -14 8 -19s12 -8 19 -8c5 0 9 1 13 3s8 6 10 10s4 9 4 14c0 8 -3 14 -8 19s-12 8 -19 8zM18 197
+c0 -11 5 -20 14 -27c7 19 19 37 37 53c-6 4 -12 6 -19 6c-3 0 -7 0 -10 -1s-6 -3 -9 -5s-5 -4 -7 -7s-4 -6 -5 -9s-1 -6 -1 -10zM355 55c34 23 50 51 50 83v9c-1 6 -3 12 -5 18c-6 16 -15 30 -30 43c-5 4 -10 9 -15 12v0c-36 25 -79 37 -130 37s-95 -12 -131 -37v0
+c-5 -3 -10 -8 -15 -12c-15 -13 -24 -27 -30 -43c-2 -6 -4 -12 -5 -18v-9c0 -32 16 -60 50 -83c36 -25 80 -37 131 -37s94 12 130 37zM417 170c9 6 14 16 14 27c0 9 -3 17 -9 23s-13 9 -22 9c-7 0 -14 -2 -20 -6c18 -16 30 -34 37 -53zM289 90l13 -12
+c-20 -20 -45 -30 -77 -30s-58 10 -78 30l13 12c16 -16 38 -24 65 -24s48 8 64 24z" />
+ <glyph glyph-name="ion-social-reddit" unicode="&#xf23b;" horiz-adv-x="449"
+d="M449 197c0 -20 -11 -37 -27 -45c1 -5 1 -9 1 -14c0 -76 -89 -138 -199 -138s-198 61 -198 137c0 5 0 10 1 15c-16 8 -27 25 -27 45c0 28 23 50 50 50c13 0 24 -5 33 -13c33 23 79 39 129 41h2l31 103l90 -18c8 14 22 24 39 24v0h1c25 0 44 -20 44 -45s-19 -45 -44 -45h-1
+v0c-23 0 -42 17 -44 40l-67 14l-22 -74c49 -3 93 -17 125 -40c9 8 21 13 34 13c27 0 49 -22 49 -50zM34 177c5 15 15 29 29 41c-4 3 -9 5 -15 5c-14 0 -25 -11 -25 -25c0 -9 4 -17 11 -21zM358 339c0 -9 7 -17 16 -17s17 8 17 17s-8 17 -17 17s-16 -8 -16 -17zM127 160
+c0 -18 14 -32 32 -32s32 14 32 32s-14 31 -32 31s-32 -13 -32 -31zM224 48c48 0 77 29 78 30l-13 12s-25 -24 -65 -24c-41 0 -64 24 -64 24l-13 -12c1 -1 29 -30 77 -30zM291 128c18 0 32 14 32 32s-14 31 -32 31s-32 -13 -32 -31s14 -32 32 -32zM415 176c7 5 11 13 11 22
+c0 14 -11 25 -25 25c-6 0 -11 -2 -15 -5c14 -12 24 -27 29 -42z" />
+ <glyph glyph-name="ion-social-rss-outline" unicode="&#xf23c;" horiz-adv-x="384"
+d="M56 112c31 0 56 -25 56 -56s-25 -56 -56 -56s-56 25 -56 56s25 56 56 56zM56 16c22 0 40 18 40 40s-18 40 -40 40s-40 -18 -40 -40s18 -40 40 -40zM0 256c140 0 256 -116 256 -256h-80c0 48 -14 94 -48 128s-80 48 -128 48v80zM240 16c-2 26 -8 52 -19 77
+c-12 28 -30 54 -52 76s-48 40 -76 52c-25 10 -51 16 -77 18v-47c50 -3 92 -22 123 -53s50 -73 53 -123h48zM0 384c212 0 384 -172 384 -384h-80c0 171 -133 304 -304 304v80zM227 228c56 -56 89 -131 93 -212h48c-8 190 -162 344 -352 352v-48c81 -4 155 -36 211 -92z" />
+ <glyph glyph-name="ion-social-rss" unicode="&#xf23d;" horiz-adv-x="384"
+d="M56 112c31 0 56 -25 56 -56s-25 -56 -56 -56s-56 25 -56 56s25 56 56 56zM0 256c140 0 256 -116 256 -256h-80c0 48 -14 94 -48 128s-80 48 -128 48v80zM0 384c212 0 384 -172 384 -384h-80c0 171 -133 304 -304 304v80z" />
+ <glyph glyph-name="ion-social-sass" unicode="&#xf4ea;" horiz-adv-x="512"
+d="M512 119v-8c-1 -9 -7 -17 -15 -22s-12 -4 -13 -3s1 3 4 5c13 8 17 20 10 33c-5 10 -15 16 -26 20c-24 8 -48 7 -72 0c4 -12 7 -23 -2 -34c-10 -12 -23 -19 -39 -22c-7 -2 -14 2 -15 9c-3 19 17 36 30 47c-7 11 -11 24 -14 37c-15 -17 -31 -40 -26 -61
+c3 -14 -1 -27 -14 -36s-30 -14 -46 -11c-4 1 -6 5 -5 8c2 14 25 32 35 43c2 2 3 4 1 7c-6 12 -10 23 -14 36c-13 -29 -30 -80 -57 -98c-9 -6 -17 -4 -21 5c-3 8 -2 20 -1 29c-6 -13 -11 -27 -20 -38c-7 -8 -24 -7 -30 1c-16 21 -13 50 -5 73l-29 -15c7 -16 8 -32 4 -49
+c-5 -19 -17 -35 -35 -46c-19 -12 -64 -24 -77 4c-7 16 -4 30 6 44c17 24 48 37 74 50c-32 23 -80 42 -96 80c-15 35 17 68 43 89c59 48 166 95 244 59c15 -7 36 -24 31 -52c-4 -24 -13 -39 -28 -54c-32 -32 -152 -77 -176 -15c-1 1 -1 4 1 4c2 -1 20 -15 43 -16
+c17 -1 36 3 52 8c33 11 71 33 80 67c4 13 -2 28 -15 34c-49 24 -116 -4 -159 -26c-33 -17 -84 -45 -82 -87c1 -37 56 -60 81 -82c15 7 42 15 52 27c11 13 26 25 44 26c8 0 14 -3 16 -10c2 -6 1 -11 0 -19c5 4 11 4 15 -1c12 -14 -22 -50 -10 -66c14 14 21 42 30 59
+c4 8 17 51 26 53c7 2 18 4 25 0c2 -1 3 -3 2 -5c-7 -19 -7 -33 3 -52c14 20 29 43 34 67c1 2 3 3 5 4c7 2 18 3 25 0c3 -1 3 -2 2 -5c-7 -22 -6 -38 6 -58c31 11 69 15 97 -5c-3 2 -7 5 0 0c5 -4 3 -2 0 0c12 -8 19 -18 21 -32zM113 94v0c1 7 -1 13 -3 20
+c-24 -8 -66 -35 -64 -62c1 -10 8 -13 17 -12s19 7 27 13c14 11 22 24 23 41zM216 166c1 3 -2 5 -5 4c-29 -8 -43 -57 -33 -81c1 -3 4 -3 6 -1c17 16 28 56 32 78zM286 84c8 -3 27 17 26 27c-8 -9 -18 -18 -26 -27zM367 102c11 6 16 19 12 30c-8 -6 -21 -19 -20 -31
+c0 -2 6 0 8 1z" />
+ <glyph glyph-name="ion-social-skype-outline" unicode="&#xf23e;" horiz-adv-x="384"
+d="M106 352c-41 0 -74 -33 -74 -73c0 -13 4 -25 10 -36l6 -11l-2 -12c-2 -10 -3 -20 -3 -30c0 -40 16 -77 44 -105s67 -44 107 -44c9 0 19 1 28 3l11 2l9 -5c11 -6 24 -9 36 -9c41 0 74 33 74 73c0 11 -3 22 -8 32l-5 10l3 11c2 10 3 21 3 32c0 40 -16 77 -44 105
+s-67 43 -107 43c-9 0 -18 0 -26 -2l-12 -2l-10 7c-12 7 -26 11 -40 11zM106 384v0c21 0 40 -6 56 -16c10 2 21 2 32 2c101 0 183 -80 183 -180c0 -13 -1 -27 -4 -39c7 -14 11 -29 11 -46c0 -58 -47 -105 -106 -105c-18 0 -35 4 -50 12c-11 -2 -22 -3 -34 -3
+c-101 0 -183 81 -183 181c0 12 2 24 4 36c-9 16 -15 34 -15 53c0 58 47 105 106 105zM288 104c-8 -12 -21 -21 -37 -28s-36 -10 -58 -10c-26 0 -48 5 -65 14c-12 7 -22 15 -30 26s-12 22 -12 33c0 7 3 12 8 17s11 7 19 7c6 0 12 -2 16 -6s7 -8 10 -15s7 -13 11 -18
+s8 -9 15 -12s16 -5 27 -5c15 0 28 4 37 10s13 13 13 22c0 7 -2 13 -7 17c-5 5 -11 9 -19 11c-8 3 -20 5 -34 8c-19 4 -35 9 -48 14c-13 6 -24 13 -32 23s-11 22 -11 36s4 25 12 36c8 10 20 19 36 25c15 6 34 8 54 8c16 0 30 -1 42 -5s23 -9 31 -15s14 -13 18 -20
+s5 -14 5 -21c0 -6 -2 -12 -7 -17s-11 -8 -19 -8c-7 0 -12 2 -16 5c-3 3 -7 7 -11 14c-5 8 -10 15 -16 20s-17 8 -31 8c-13 0 -23 -3 -31 -8s-12 -11 -12 -18c0 -4 2 -7 4 -10c3 -3 6 -6 11 -8s10 -5 15 -6s13 -3 25 -6c15 -3 28 -6 40 -10s23 -8 32 -14s15 -13 20 -22
+s8 -20 8 -32c0 -15 -5 -28 -13 -40z" />
+ <glyph glyph-name="ion-social-skype" unicode="&#xf23f;" horiz-adv-x="384"
+d="M373 151c7 -14 11 -29 11 -46c0 -58 -47 -105 -106 -105c-18 0 -35 4 -50 12c-11 -2 -22 -3 -34 -3c-101 0 -183 81 -183 181c0 12 2 24 4 36c-9 16 -15 34 -15 53c0 58 47 105 106 105c21 0 41 -6 57 -16c10 2 20 2 31 2c101 0 183 -80 183 -180c0 -13 -1 -27 -4 -39z
+M288 104c9 12 12 25 12 40c0 12 -2 23 -7 32s-12 16 -21 22s-19 10 -31 14s-26 7 -41 10c-12 3 -20 5 -25 6s-10 4 -15 6s-7 5 -10 8c-2 3 -4 6 -4 10c0 7 3 13 11 18s19 7 32 7c14 0 25 -2 31 -7s11 -12 16 -20c4 -7 8 -11 11 -14c4 -3 9 -5 16 -5c8 0 13 3 18 8s8 11 8 17
+c0 7 -2 14 -6 21s-10 14 -18 20s-18 11 -30 15s-27 5 -43 5c-20 0 -38 -2 -53 -8c-16 -6 -28 -15 -36 -25c-8 -11 -12 -22 -12 -36s3 -26 11 -36s19 -17 32 -23c13 -5 29 -10 48 -14c14 -3 26 -5 34 -8c8 -2 14 -6 19 -11c5 -4 7 -10 7 -17c0 -9 -4 -17 -13 -23
+s-22 -9 -37 -9c-11 0 -20 2 -27 5s-11 6 -15 11s-8 12 -11 19s-6 11 -10 15s-10 6 -16 6c-8 0 -14 -2 -19 -7s-8 -10 -8 -17c0 -11 4 -22 12 -33s18 -19 30 -26c17 -9 39 -14 65 -14c22 0 42 3 58 10s29 16 37 28z" />
+ <glyph glyph-name="ion-social-snapchat-outline" unicode="&#xf4eb;" horiz-adv-x="480"
+d="M240 400v0v0c-71 0 -128 -54 -118 -128c2 -15 3 -32 4 -45c0 0 -2 -5 -12 -5c-6 0 -15 2 -28 7c-2 1 -4 1 -6 1c-8 0 -13 -6 -14 -12c0 -5 4 -11 8 -13c14 -7 47 -10 47 -33s-23 -47 -41 -64s-64 -21 -64 -21s0 -21 32 -29s32 -5 33 -13c2 -15 1 -22 11 -22c2 0 4 1 6 1
+c8 1 20 3 32 3c11 0 23 -2 34 -9c23 -15 41 -34 76 -34s53 19 76 34c11 7 24 9 35 9c12 0 23 -2 31 -3c2 0 4 -1 6 -1c10 0 9 7 11 22c1 8 1 5 33 13s32 29 32 29s-46 4 -64 21s-41 41 -41 64s33 26 47 33c4 2 9 8 9 13c-1 6 -6 12 -14 12c-2 0 -5 0 -7 -1
+c-13 -5 -21 -6 -27 -6c-10 0 -13 4 -13 4c1 13 2 30 4 45c10 74 -47 128 -118 128zM240 416v0c41 0 80 -16 105 -45c24 -28 34 -63 29 -101c-1 -11 -2 -22 -3 -31c4 1 10 2 18 5c4 1 8 2 12 2c16 0 29 -12 30 -27c1 -13 -9 -25 -18 -29c-4 -2 -9 -3 -14 -5
+c-7 -2 -14 -5 -19 -8c-4 -3 -5 -4 -5 -5c0 -16 20 -37 36 -52c11 -10 39 -16 54 -17l15 -1v-14c0 -2 0 -11 -6 -21c-5 -8 -16 -19 -38 -24c-6 -1 -11 -3 -15 -4c-2 -1 -5 -1 -7 -1v-1c-1 -7 -1 -13 -4 -18c-2 -5 -9 -12 -22 -12c-2 0 -6 0 -9 1c-2 0 -3 1 -5 1
+c-7 1 -15 2 -23 2c-10 0 -19 -2 -26 -6c-4 -3 -9 -7 -14 -10c-18 -13 -38 -27 -71 -27s-53 14 -71 27c-5 3 -9 7 -14 10c-7 4 -15 6 -25 6c-8 0 -17 -1 -24 -2c-2 0 -3 -1 -5 -1c-3 -1 -7 -1 -9 -1c-13 0 -20 7 -22 12c-3 5 -3 11 -4 18v1c-2 0 -4 0 -6 1c-4 1 -10 3 -16 4
+c-22 5 -33 16 -38 24c-6 10 -6 18 -6 20v15l15 1c16 1 44 7 54 17c29 27 36 43 36 52c0 1 0 2 -4 5c-5 3 -13 6 -20 8c-5 2 -10 3 -14 5c-9 4 -18 16 -17 29c1 15 14 27 30 27c4 0 8 0 12 -2c8 -3 13 -4 17 -5c-1 9 -2 19 -3 30c-5 38 5 74 29 102c25 29 64 45 105 45v0z
+M240 219c-21 0 -41 8 -56 23c-3 3 -3 9 0 12s9 3 12 0c12 -12 27 -19 44 -19c16 0 32 7 44 19c3 3 9 3 12 0s3 -9 0 -12c-15 -15 -35 -23 -56 -23zM176 296c0 16 5 24 16 24s16 -8 16 -24s-5 -24 -16 -24s-16 8 -16 24zM272 296c0 16 5 24 16 24s16 -8 16 -24
+s-5 -24 -16 -24s-16 8 -16 24z" />
+ <glyph glyph-name="ion-social-snapchat" unicode="&#xf4ec;" horiz-adv-x="480"
+d="M480 88c0 -2 0 -11 -6 -21c-5 -8 -16 -19 -38 -24c-6 -1 -11 -3 -15 -4c-2 -1 -5 -1 -7 -1v-1c-1 -7 -1 -13 -4 -18c-2 -5 -9 -12 -22 -12c-2 0 -6 0 -9 1c-2 0 -3 1 -5 1c-7 1 -15 2 -23 2c-10 0 -19 -2 -26 -6c-4 -3 -9 -7 -14 -10c-18 -13 -38 -27 -71 -27
+s-53 14 -71 27c-5 3 -9 7 -14 10c-7 4 -15 6 -25 6c-8 0 -17 -1 -24 -2c-2 0 -3 -1 -5 -1c-3 -1 -7 -1 -9 -1c-13 0 -20 7 -22 12c-3 5 -3 11 -4 18v1c-2 0 -4 0 -6 1c-4 1 -10 3 -16 4c-22 5 -33 16 -38 24c-6 10 -6 18 -6 20v15l15 1c16 1 44 7 54 17c29 27 36 43 36 52
+c0 1 0 2 -4 5c-5 3 -13 6 -20 8c-5 2 -10 3 -14 5c-9 4 -18 16 -17 29c1 15 14 27 30 27c4 0 8 0 12 -2c8 -3 13 -4 17 -5c-1 9 -2 19 -3 30c-5 38 5 74 29 102c25 29 64 45 105 45v0c41 0 80 -16 105 -45c24 -28 34 -63 29 -101c-1 -11 -2 -22 -3 -31c4 1 10 2 18 5
+c4 1 8 2 12 2c16 0 29 -12 30 -27c1 -13 -9 -25 -18 -29c-4 -2 -9 -3 -14 -5c-7 -2 -14 -5 -19 -8c-4 -3 -5 -4 -5 -5c0 -16 20 -37 36 -52c11 -10 39 -16 54 -17l15 -1v-14zM192 320c-9 0 -16 -11 -16 -24s7 -24 16 -24s16 11 16 24s-7 24 -16 24zM296 242c3 3 3 9 0 12
+s-9 3 -12 0c-12 -12 -28 -19 -44 -19c-17 0 -32 7 -44 19c-3 3 -9 3 -12 0s-3 -9 0 -12c15 -15 35 -23 56 -23s41 8 56 23zM288 272c9 0 16 11 16 24s-7 24 -16 24s-16 -11 -16 -24s7 -24 16 -24z" />
+ <glyph glyph-name="ion-social-tumblr-outline" unicode="&#xf240;" horiz-adv-x="256"
+d="M193 52c21 0 42 6 63 20v-65c-18 -8 -34 -15 -48 -18s-28 -5 -45 -5c-19 0 -35 2 -50 7c-14 5 -28 12 -38 21s-17 18 -21 28s-6 25 -6 44v140h-48v58c16 5 30 14 42 24s19 21 26 35s11 37 14 59h62v-112h96v-64h-96v-101c0 -24 1 -40 4 -47c2 -7 7 -12 14 -16
+c9 -6 19 -8 31 -8zM240 17v29c-15 -6 -31 -10 -47 -10c-15 0 -28 3 -40 10c-10 6 -17 15 -21 25c-2 6 -4 17 -4 52v117h96v32h-96v112h-32c-2 -16 -7 -36 -14 -50c-8 -16 -17 -29 -30 -40c-11 -9 -23 -17 -36 -23v-31h48v-156c0 -21 2 -32 4 -38c3 -8 10 -15 18 -22
+c9 -8 19 -14 31 -18c13 -4 29 -6 46 -6c16 0 28 2 41 5c11 2 23 6 36 12z" />
+ <glyph glyph-name="ion-social-tumblr" unicode="&#xf241;" horiz-adv-x="256"
+d="M193 52c21 0 42 6 63 20v-65c-18 -8 -34 -15 -48 -18s-28 -5 -45 -5c-19 0 -35 2 -50 7c-14 5 -28 12 -38 21s-17 18 -21 28s-6 25 -6 44v140h-48v58c16 5 30 14 42 24s19 21 26 35s11 37 14 59h62v-112h96v-64h-96v-101c0 -24 1 -40 4 -47c2 -7 7 -12 14 -16
+c9 -6 19 -8 31 -8z" />
+ <glyph glyph-name="ion-social-tux" unicode="&#xf2c5;" horiz-adv-x="383"
+d="M189 347c2 2 -1 -1 0 0c2 2 4 4 6 5c-3 -2 -5 -4 -7 -8c0 1 0 2 1 3zM361 52c7 -4 23 -11 21 -22c-2 -10 -17 -15 -24 -19c-15 -8 -28 -14 -41 -25c-9 -8 -17 -15 -29 -17c-11 -2 -25 -1 -33 8c-5 5 -7 11 -15 12c-25 5 -54 4 -79 0c-13 -2 -21 -11 -32 -17
+c-10 -5 -20 -5 -30 -1c-13 5 -27 10 -41 13s-29 5 -43 9c-31 8 -5 30 -11 50c-3 12 -10 29 8 30c9 1 27 -1 31 11c2 7 -2 15 2 22s-1 17 1 25c4 18 19 32 25 49c5 14 8 25 18 37c9 11 22 22 29 34c10 18 9 35 8 55c-1 17 -1 33 -2 50c0 33 20 60 58 60h14
+c38 0 63 -32 64 -69c0 -19 -5 -38 5 -67c15 -27 36 -48 52 -73c10 -16 16 -31 20 -49c3 -14 9 -31 7 -45c-1 -6 -2 -9 -4 -11c3 -1 7 -2 9 -5c3 -4 2 -11 0 -26c-1 -8 5 -15 12 -19zM137 -3c2 20 -15 39 -25 56c-10 16 -21 43 -39 52c-8 4 -19 5 -23 -5c-2 -7 0 -19 -2 -22
+c-4 -9 -14 -10 -23 -11c-6 0 -17 0 -17 -8c1 -10 10 -20 7 -30c-2 -7 -8 -12 -8 -19c0 -14 38 -15 47 -17c19 -4 37 -14 57 -16c12 -1 25 7 26 20zM253 62c-2 10 2 -10 0 0s-5 28 1 35c4 5 10 6 17 5c0 4 1 9 3 12c8 13 29 8 39 0l-1 2c-3 4 -8 9 -13 10c0 0 4 12 2 34
+c-4 40 -33 62 -33 62c27 -30 27 -58 27 -72c0 -6 -1 -18 -4 -24c-4 -1 -7 -2 -11 -4c-10 -5 -8 2 -8 10c0 18 -2 36 -7 54c-3 9 -7 17 -13 24c-4 5 -4 9 -5 15c-3 12 -9 22 -16 32c-7 9 -7 17 -5 28c1 7 2 14 -6 17c-6 2 -26 5 -27 14c-1 6 -1 16 5 20c16 14 30 -11 17 -24
+c-3 -3 7 -4 8 -4c4 1 4 7 5 10c1 4 1 9 1 13c0 17 -18 32 -34 21c-6 -4 -9 -11 -10 -17c0 -2 -1 -20 0 -20c-4 0 -7 5 -11 5c-3 0 -7 0 -10 -1c0 0 2 14 -2 22c-4 9 -18 16 -24 4s-3 -25 0 -31s4 -6 4 -6c2 1 5 4 5 4s-6 3 -7 11c-1 9 3 14 7 15s10 -2 12 -8s0 -13 0 -13
+c-7 -6 -30 -18 -22 -28c14 -18 33 -15 52 -9c8 3 18 5 24 12c3 3 11 2 8 -4c-2 -5 -18 -7 -22 -9c-9 -4 -18 -8 -28 -10c-6 -1 -13 -5 -28 9c7 -6 8 -16 17 -20c13 -6 33 9 44 15c1 1 16 5 14 0c-1 -4 -11 -7 -15 -9c-11 -6 -23 -21 -36 -22c-8 -1 -21 16 -25 22
+c-1 1 -5 9 -6 4c-1 -8 2 -14 -3 -21c-6 -9 -11 -18 -13 -29c-1 -6 0 -11 -3 -16c-11 -15 -17 -33 -19 -51c0 -4 3 -43 -5 -41c-18 5 -17 33 -14 47c-3 -12 -8 -30 2 -44c12 -15 99 -55 53 -80c7 -14 14 -25 12 -41c8 7 2 20 -1 28c0 0 17 -12 38 -10c17 2 32 7 46 16
+c6 4 11 9 16 14c1 2 4 6 6 7l1 -11c2 -17 -12 -27 -10 -34c4 8 11 14 13 24c3 12 0 24 -2 36zM155 323v0v-3c2 0 2 5 1 8c-1 4 -3 6 -4 6h-2c3 -2 5 -6 5 -11zM210 335c3 -2 0 0 0 0c3 -2 5 -5 5 -10v-3c2 0 3 4 2 7s-3 6 -5 6h-2zM347 15c24 11 -24 -10 0 0
+c24 11 35 17 20 26c-17 10 -26 13 -26 29c0 5 4 16 2 22c-1 4 -6 5 -9 5c-10 -10 -17 -25 -34 -25c-14 0 -25 11 -28 24c-4 2 -10 1 -13 -4c-6 -12 1 -29 3 -41c2 -18 -4 -35 -2 -53c2 -21 26 -22 40 -13c16 10 29 22 47 30z" />
+ <glyph glyph-name="ion-social-twitch-outline" unicode="&#xf4ed;" horiz-adv-x="416"
+d="M32 416h384v-272l-112 -112h-80l-64 -64h-64v64h-96v304zM368 160v208h-304v-272h80v-64l64 64h96zM272 176v129h48v-129h-48zM160 176v129h48v-129h-48z" />
+ <glyph glyph-name="ion-social-twitch" unicode="&#xf4ee;" horiz-adv-x="416"
+d="M32 416h384v-272l-112 -112h-80l-64 -64h-64v64h-96v304zM208 176v129h-48v-129h48zM320 176v129h-48v-129h48z" />
+ <glyph glyph-name="ion-social-twitter-outline" unicode="&#xf242;" horiz-adv-x="472"
+d="M472 338c-13 -20 -29 -36 -48 -50v-12c0 -128 -98 -276 -276 -276c-55 0 -105 16 -148 44c8 -1 15 -2 23 -2c45 0 87 16 120 42c-42 1 -78 29 -90 67c6 -1 12 -2 18 -2c9 0 18 2 26 4c-44 9 -78 48 -78 95v1c13 -7 28 -12 44 -12c-26 17 -43 47 -43 81c0 18 5 34 13 48
+c48 -59 119 -97 199 -101c-2 7 -2 14 -2 22c0 54 43 97 97 97c28 0 52 -12 70 -31c22 4 43 13 62 24c-7 -23 -23 -42 -43 -54c20 2 39 7 56 15zM414 301c3 2 8 6 11 8c-2 0 -11 -2 -19 -1s-21 5 -21 5s14 13 18 17l11 11c-4 -1 -10 -2 -14 -3l-8 -2l-6 6
+c-15 16 -37 26 -59 26c-45 0 -81 -37 -81 -81c0 -6 1 -12 2 -18l5 -21l-22 1c-42 2 -81 13 -118 32c-28 14 -53 34 -75 56c-1 -6 -2 -13 -2 -19c0 -27 14 -53 36 -68c0 0 33 -23 46 -29c-24 -2 -56 0 -56 0c-8 0 -16 1 -24 3c8 -28 32 -50 62 -56l61 -10l-61 -21
+c-7 -2 -14 -3 -21 -3c15 -20 38 -34 64 -34l45 -1l-35 -28c-18 -14 -38 -25 -60 -33c-10 -3 -19 -6 -29 -8c27 -9 55 -14 84 -14c40 0 78 8 112 24c31 14 58 34 81 60c22 24 38 53 50 84c11 30 17 62 17 92v12l-1 8z" />
+ <glyph glyph-name="ion-social-twitter" unicode="&#xf243;" horiz-adv-x="472"
+d="M472 338c-13 -20 -29 -36 -48 -50v-12c0 -128 -98 -276 -276 -276c-55 0 -105 16 -148 44c8 -1 15 -2 23 -2c45 0 87 16 120 42c-42 1 -78 29 -90 67c6 -1 12 -2 18 -2c9 0 18 2 26 4c-44 9 -78 48 -78 95v1c13 -7 28 -12 44 -12c-26 17 -43 47 -43 81c0 18 5 34 13 48
+c48 -59 119 -97 199 -101c-2 7 -2 14 -2 22c0 54 43 97 97 97c28 0 52 -12 70 -31c22 4 43 13 62 24c-7 -23 -23 -42 -43 -54c20 2 39 7 56 15z" />
+ <glyph glyph-name="ion-social-usd-outline" unicode="&#xf352;" horiz-adv-x="320"
+d="M125 345c11 2 19 3 19 3v-131l-22 6c-15 5 -27 11 -36 19c-12 10 -19 25 -19 43c0 13 4 24 11 33c6 8 13 14 22 19c7 4 17 6 25 8zM128 238v92c-7 -2 -15 -4 -21 -7c-7 -4 -12 -9 -17 -15s-7 -14 -7 -23c0 -13 4 -24 13 -31c8 -7 20 -12 32 -16zM252 151
+c10 -10 15 -24 15 -42c0 -9 -1 -18 -5 -27s-11 -17 -20 -24c-8 -6 -18 -11 -31 -15c-6 -2 -11 -3 -17 -4s-18 -1 -18 -1v145l20 -5c10 -3 19 -6 28 -9c10 -4 20 -10 28 -18zM247 89c3 7 4 13 4 20c0 14 -3 24 -10 31s-15 11 -23 14s-16 5 -26 8v-107c6 1 10 2 14 3
+c11 3 20 8 27 13s11 11 14 18zM315 145c3 -10 5 -19 5 -29c0 -21 -5 -38 -14 -53s-20 -26 -35 -35s-31 -17 -50 -21c-10 -2 -19 -3 -29 -4v-35h-64v35c-9 1 -19 4 -28 6c-20 5 -36 12 -51 23s-26 24 -35 41c-8 16 -13 34 -14 55h69c0 -12 2 -24 7 -33c5 -10 12 -17 21 -23
+s20 -11 31 -14v120c-8 2 -18 4 -27 6c-17 4 -30 9 -41 16s-20 15 -27 23s-11 17 -14 26s-4 18 -4 28c0 18 4 34 12 48s19 25 33 34s29 16 46 20c7 2 15 3 22 4v33h64v-33c9 -1 16 -4 24 -6c18 -5 34 -12 48 -22s25 -22 33 -37c7 -13 11 -28 12 -46h-69c-3 21 -12 37 -26 46
+c-7 4 -13 8 -22 10v-106c9 -2 16 -4 25 -6c12 -3 22 -6 27 -7c13 -4 23 -9 33 -15c10 -7 18 -14 24 -22s11 -17 14 -27zM293 72c7 12 11 27 11 44c0 8 -1 16 -4 24s-7 15 -12 22s-12 13 -20 19c-8 5 -18 10 -29 13c-5 1 -13 3 -24 6h-1l-4 1c-7 2 -13 4 -21 6l-13 3v137
+s9 -1 19 -4s19 -6 28 -12c15 -9 25 -24 30 -43h38c-2 8 -4 15 -8 22c-7 13 -16 24 -28 32c-12 9 -27 16 -43 20c-8 2 -16 4 -23 5l-13 2v31h-32v-31l-14 -2c-7 -1 -14 -2 -20 -4c-15 -4 -29 -10 -41 -18s-21 -16 -28 -28c-7 -11 -10 -24 -10 -40c0 -8 1 -15 3 -23
+c2 -7 6 -14 11 -21s14 -13 23 -19c10 -6 22 -10 37 -14v0v0c4 -1 8 -2 11 -3c5 -1 11 -3 16 -4l12 -3v-151s-8 1 -20 4s-26 8 -36 15c-11 8 -20 18 -26 30c-4 7 -6 16 -8 24h-36c2 -11 5 -23 10 -32c8 -14 17 -26 30 -35c13 -10 28 -16 46 -21c8 -2 17 -4 26 -5l14 -2v-33
+h32v33l15 1c9 1 17 3 26 5c17 4 32 10 45 18s23 19 31 31z" />
+ <glyph glyph-name="ion-social-usd" unicode="&#xf353;" horiz-adv-x="320"
+d="M315 145c3 -10 5 -19 5 -29c0 -21 -5 -38 -14 -53s-20 -26 -35 -35s-31 -17 -50 -21c-10 -2 -19 -3 -29 -4v-35h-64v35c-9 1 -19 4 -28 6c-20 5 -36 12 -51 23s-26 24 -35 41c-8 16 -13 34 -14 55h69c0 -12 2 -24 7 -33c5 -10 12 -17 21 -23s20 -11 31 -14v120
+c-8 2 -18 4 -27 6c-17 4 -30 9 -41 16s-20 15 -27 23s-11 17 -14 26s-4 18 -4 28c0 18 4 34 12 48s19 25 33 34s29 16 46 20c7 2 15 3 22 4v33h64v-33c9 -1 16 -4 24 -6c18 -5 34 -12 48 -22s25 -22 33 -37c7 -13 11 -28 12 -46h-69c-3 21 -12 37 -26 46c-7 4 -13 8 -22 10
+v-106c9 -2 16 -4 25 -6c12 -3 22 -6 27 -7c13 -4 23 -9 33 -15c10 -7 18 -14 24 -22s11 -17 14 -27zM128 238v92c-7 -2 -15 -4 -21 -7c-7 -4 -12 -9 -17 -15s-7 -14 -7 -23c0 -13 4 -24 13 -31c8 -7 20 -12 32 -16zM247 89c3 7 4 13 4 20c0 14 -3 24 -10 31s-15 11 -23 14
+s-16 5 -26 8v-107c6 1 10 2 14 3c11 3 20 8 27 13s11 11 14 18z" />
+ <glyph glyph-name="ion-social-vimeo-outline" unicode="&#xf244;"
+d="M445 334c7 -33 1 -66 -13 -97s-31 -59 -51 -87c-26 -36 -52 -71 -85 -101c-19 -18 -41 -35 -66 -44c-10 -4 -19 -5 -27 -5c-17 0 -31 9 -44 27c-14 19 -22 40 -28 63c-12 45 -25 90 -38 134c-4 12 -9 22 -15 33c-3 5 -8 10 -12 14c-2 2 -5 3 -8 3s-6 -1 -9 -3
+c-10 -6 -28 -18 -28 -18l-21 27c26 24 82 71 82 71c11 9 33 25 48 27h8c18 0 32 -7 42 -22c11 -17 15 -37 18 -57c7 -41 12 -82 24 -122c3 -10 7 -20 12 -29c4 -7 9 -10 14 -10c4 0 7 2 11 5s7 6 10 10c20 24 37 52 48 81c3 9 3 17 3 27c0 13 -10 25 -25 26h-7
+c-11 0 -20 -2 -32 -7c6 24 24 62 54 84c20 14 45 20 67 20c10 0 20 -2 27 -4c23 -8 36 -23 41 -46zM418 244c13 30 17 59 11 87c-4 19 -13 28 -30 34c-6 2 -14 3 -22 3c-21 0 -42 -6 -57 -17c-16 -12 -29 -30 -38 -48h6h8c23 -1 39 -19 40 -41c0 -10 0 -22 -4 -34
+c-11 -29 -29 -58 -51 -85c-4 -4 -7 -9 -12 -13c-7 -6 -15 -8 -22 -8c-8 0 -18 3 -27 18c-7 11 -11 22 -14 32c-10 31 -14 64 -19 95c-2 10 -3 19 -5 29c-3 17 -6 36 -16 51c-7 10 -16 15 -28 15h-6c-8 -1 -25 -11 -40 -23c-2 -2 -43 -37 -70 -61l2 -3c5 4 12 7 16 10
+c6 3 12 5 18 5c7 0 13 -3 18 -7c8 -7 13 -12 16 -18c6 -11 12 -24 16 -37c13 -44 26 -88 38 -133c5 -19 13 -41 26 -59s23 -20 31 -20c6 0 13 1 21 4c23 8 43 25 61 41c32 29 57 63 83 99v0c21 28 37 55 50 84z" />
+ <glyph glyph-name="ion-social-vimeo" unicode="&#xf245;"
+d="M445 334c7 -33 1 -66 -13 -97s-31 -59 -51 -87c-26 -36 -52 -71 -85 -101c-19 -18 -41 -35 -66 -44c-31 -11 -52 -5 -71 22c-14 19 -22 40 -28 63c-12 45 -25 90 -38 134c-4 12 -9 22 -15 33c-3 5 -8 10 -12 14c-5 4 -11 3 -17 0c-10 -6 -28 -18 -28 -18l-21 27
+c26 24 82 71 82 71c11 9 33 25 48 27c21 3 38 -4 50 -22c11 -17 15 -37 18 -57c7 -41 11 -82 23 -122c3 -10 8 -20 13 -29c7 -11 15 -13 25 -5c4 3 7 6 10 10c20 24 37 52 48 81c3 9 3 17 3 27c0 13 -10 25 -25 26s-24 -1 -39 -7c6 24 24 62 54 84c29 21 71 24 94 16
+s36 -23 41 -46z" />
+ <glyph glyph-name="ion-social-whatsapp-outline" unicode="&#xf4ef;"
+d="M178 294c4 -11 15 -39 16 -42s2 -6 0 -10s-3 -6 -6 -9s-6 -7 -9 -9c-3 -3 -6 -6 -3 -12s14 -24 30 -39c21 -20 38 -27 44 -30s9 -3 12 1s15 16 19 21s8 5 13 3s31 -17 37 -20s10 -5 11 -7s0 -13 -5 -26s-28 -24 -38 -25s-11 -8 -67 16s-90 84 -93 88s-22 31 -21 58
+s17 41 22 46s11 7 15 7h10s9 0 13 -11zM228 384c-50 0 -97 -20 -133 -55c-35 -35 -55 -81 -55 -131c0 -34 9 -67 27 -96l8 -13l-5 -14l-19 -57l61 19l13 4l12 -6c28 -15 59 -23 91 -23c50 0 97 19 133 54c35 35 55 82 55 132s-20 96 -55 131c-36 35 -83 55 -133 55zM228 416
+v0c121 0 220 -97 220 -218s-99 -218 -220 -218c-39 0 -74 10 -106 27l-122 -39l40 117c-20 33 -32 72 -32 113c0 121 99 218 220 218z" />
+ <glyph glyph-name="ion-social-whatsapp" unicode="&#xf4f0;"
+d="M228 416c121 0 220 -97 220 -218s-99 -218 -220 -218c-39 0 -74 10 -106 27l-122 -39l40 117c-20 33 -32 72 -32 113c0 121 99 218 220 218zM337 115c5 13 6 24 5 26s-5 4 -11 7s-32 18 -37 20s-9 2 -13 -3s-16 -17 -19 -21s-6 -4 -12 -1s-23 10 -44 30
+c-16 15 -27 33 -30 39s0 9 3 12c3 2 6 6 9 9s4 5 6 9s1 7 0 10s-12 31 -16 42s-10 11 -13 11h-10s-10 -2 -15 -7s-21 -19 -22 -46s18 -54 21 -58s37 -64 93 -88s57 -17 67 -16s33 12 38 25z" />
+ <glyph glyph-name="ion-social-windows-outline" unicode="&#xf246;"
+d="M432 167h-216v-149l216 -32v181zM448 183v0v-215l-248 36v179h248zM168 167h-152v-120l152 -22v142zM184 183v0v-177l-184 27v150h184zM432 398v0l-216 -31v-152h216v183zM448 416v0v-217h-248v182zM168 360v0l-152 -22v-123h152v145zM184 378v0v-179h-184v153z" />
+ <glyph glyph-name="ion-social-windows" unicode="&#xf247;"
+d="M448 183v0v-215l-248 36v179h248zM184 183v0v-177l-184 27v150h184zM448 416v0v-217h-248v182zM184 378v0v-179h-184v153z" />
+ <glyph glyph-name="ion-social-wordpress-outline" unicode="&#xf248;" horiz-adv-x="384"
+d="M192 384c106 0 192 -86 192 -192c0 -9 -1 -18 -2 -26c-12 -85 -79 -153 -165 -164c-8 -1 -17 -2 -25 -2c-106 0 -192 86 -192 192s86 192 192 192zM19 192c0 -68 40 -127 98 -155l-83 225c-10 -21 -15 -45 -15 -70zM214 21c12 2 24 4 35 8c0 1 -1 2 -1 3l-53 145l-33 -96
+v0l-19 -55c15 -5 32 -7 49 -7c8 0 15 1 22 2zM216 273l62 -186l17 58c9 22 13 41 13 56c0 21 -7 35 -14 47c-9 14 -17 27 -17 41c0 16 12 30 29 30h2c-31 28 -71 45 -116 45c-60 0 -113 -30 -144 -77c4 0 8 -1 11 -1c18 0 46 3 46 3c9 1 10 -14 1 -15c0 0 -10 -1 -20 -1
+l63 -187l38 113l-27 74c-9 0 -18 1 -18 1c-9 0 -8 16 1 15c0 0 28 -3 45 -3c18 0 46 3 46 3c9 1 11 -14 2 -15c0 0 -10 -1 -20 -1zM279 43c45 26 77 71 84 125c1 8 2 16 2 24c0 30 -8 58 -22 83c1 -6 1 -12 1 -18c0 -18 -3 -37 -13 -62l-39 -113z" />
+ <glyph glyph-name="ion-social-wordpress" unicode="&#xf249;" horiz-adv-x="384"
+d="M195 177l53 -146c0 -1 6 -13 9 -19c-3 -1 -5 -2 -8 -3v0c-10 -3 -21 -6 -32 -7c-8 -1 -17 -2 -25 -2c-17 0 -34 2 -50 6v0c-2 0 -3 2 -5 2l25 73v0zM17 268c6 0 7 -1 15 -1l93 -255c-3 1 -5 2 -8 3c-63 27 -109 87 -116 158c-1 6 -1 13 -1 19c0 25 7 53 17 76zM366 273
+c11 -24 18 -52 18 -81c0 -9 -1 -18 -2 -26c-9 -65 -50 -120 -107 -147c-2 -1 -3 -1 -5 -2l22 65l39 113c10 25 13 45 13 62v19v0c-1 18 -10 44 -36 43h-2c-17 0 -29 -14 -29 -30c0 -14 8 -27 17 -41c7 -12 14 -26 14 -47c0 -15 -4 -34 -13 -56l-17 -58l-62 186
+c10 0 20 1 20 1c9 1 7 16 -2 15c0 0 -28 -3 -46 -3c-17 0 -45 3 -45 3c-9 1 -10 -15 -1 -15c0 0 9 -1 18 -1l27 -74l-38 -113l-63 187c10 0 20 2 20 2c9 1 8 15 -1 14c0 0 -28 -2 -46 -2h-34c5 9 11 17 17 25c35 44 90 72 150 72c24 0 48 -5 69 -13c34 -13 63 -36 85 -65
+c2 -2 3 -5 5 -7c6 -8 11 -17 15 -26z" />
+ <glyph glyph-name="ion-social-yahoo-outline" unicode="&#xf24a;" horiz-adv-x="320"
+d="M289 380c11 0 21 1 31 4l-128 -213v-171c-10 4 -21 4 -32 4s-22 0 -32 -4v171l-128 213c10 -4 21 -4 32 -4s22 0 32 4l96 -160l96 160c10 -4 22 -4 33 -4zM178 180l111 184h-1c-7 0 -15 0 -24 2l-90 -150l-14 -23l-14 23l-89 150c-9 -2 -17 -2 -25 -2h-1l111 -184l2 -4
+v-5v-151c6 1 11 0 16 0s11 1 16 0v151v5z" />
+ <glyph glyph-name="ion-social-yahoo" unicode="&#xf24b;" horiz-adv-x="320"
+d="M289 380c11 0 21 1 31 4l-128 -213v-171c-10 4 -21 4 -32 4s-22 0 -32 -4v171l-128 213c10 -4 21 -4 32 -4s22 0 32 4l96 -160l96 160c10 -4 22 -4 33 -4z" />
+ <glyph glyph-name="ion-social-yen-outline" unicode="&#xf4f1;" horiz-adv-x="384"
+d="M384 416l-112 -208h48v-48h-73l-15 -31v-17h88v-48h-88v-96h-80v96h-88v48h88v17l-14 31h-74v48h48l-112 208h80l112 -221l112 221h80zM304 192h-59l13 24l99 184v0h-43l-122 -240l-122 240h-43l99 -184l13 -24h-59v-16h68l20 -44v-36h-88v-16h88v-96h48v96h88v16h-88v37
+l21 43h67v16z" />
+ <glyph glyph-name="ion-social-yen" unicode="&#xf4f2;" horiz-adv-x="384"
+d="M384 416l-112 -208h48v-48h-73l-15 -31v-17h88v-48h-88v-96h-80v96h-88v48h88v17l-14 31h-74v48h48l-112 208h80l112 -221l112 221h80z" />
+ <glyph glyph-name="ion-social-youtube-outline" unicode="&#xf24c;" horiz-adv-x="512"
+d="M265 352v0h-9h-9c-65 0 -118 -2 -168 -4h-1h-1c-23 0 -42 -22 -42 -49v-1v-1c-2 -34 -3 -70 -3 -105v0v0c0 -35 1 -70 3 -104v-2v-1c0 -14 5 -26 14 -36c8 -9 17 -13 28 -13h1h1c52 -2 108 -4 166 -4h11v0v0h11c58 0 113 2 166 4h1h1c11 0 20 4 28 13c9 10 14 22 14 36v1
+v2c2 34 3 68 3 104v0v0c0 36 -1 71 -3 105v1v2c0 27 -19 49 -42 49h-1h-1c-49 2 -103 3 -168 3zM265 384v0c58 0 115 0 170 -3c41 0 74 -36 74 -81c2 -36 3 -72 3 -108s-1 -71 -3 -107c0 -45 -33 -81 -74 -81c-55 -3 -111 -4 -168 -4h-11h-11c-57 0 -113 1 -168 4
+c-41 0 -74 36 -74 81c-2 36 -3 71 -3 107s2 71 4 107c0 45 32 82 73 82c55 2 112 3 170 3h9h9zM207 94v197l145 -99z" />
+ <glyph glyph-name="ion-social-youtube" unicode="&#xf24d;" horiz-adv-x="512"
+d="M509 299c2 -36 3 -71 3 -107s-1 -71 -3 -107c0 -45 -33 -81 -74 -81c-58 -3 -118 -4 -179 -4s-121 1 -179 4c-41 0 -74 36 -74 81c-2 36 -3 71 -3 107s2 71 4 107c0 45 32 81 73 81c55 3 112 4 170 4h9h9c58 0 115 -1 170 -4c41 0 74 -36 74 -81zM207 94l145 98l-145 99
+v-197z" />
+ <glyph glyph-name="ion-soup-can-outline" unicode="&#xf4f3;" horiz-adv-x="320"
+d="M160 304c-88 0 -160 29 -160 64s72 64 160 64s160 -29 160 -64s-72 -64 -160 -64zM160 415c-70 0 -126 -19 -126 -43s56 -43 126 -43s126 19 126 43s-56 43 -126 43zM161 288c88 0 158 29 159 64c0 -5 0 -33 -8 -40v-240c0 -35 -64 -64 -152 -64s-152 29 -152 64v240
+c-8 6 -8 40 -8 40c0 -35 73 -64 161 -64zM280 72v80c-18 -10 -43 -17 -72 -21h-2c-6 -20 -24 -35 -46 -35s-40 15 -46 35h-2c-29 4 -54 11 -72 21v-80c1 -2 9 -10 30 -18c24 -9 55 -14 90 -14s67 5 91 14c21 8 29 16 29 18zM280 184v91c-33 -12 -75 -19 -119 -19
+c-45 0 -87 7 -121 19v-91c18 -10 43 -17 73 -21h3c7 17 24 29 44 29s37 -12 44 -29h3c30 4 55 11 73 21zM178 -16zM160 -16h1h-1v0zM312 32l8 -16c0 -7 -3 -14 -8 -20c-21 -26 -81 -44 -152 -44s-131 18 -152 44c-5 6 -8 13 -8 20l8 16v16c0 -35 63 -64 152 -64
+s152 28 152 64v-16z" />
+ <glyph glyph-name="ion-soup-can" unicode="&#xf4f4;" horiz-adv-x="320"
+d="M0 368c0 43 53 64 160 64s160 -21 160 -64s-53 -64 -160 -64s-160 21 -160 64zM160 8c-44 0 -80 6 -109 18s-43 28 -43 46v128c0 -9 4 -19 13 -27s21 -15 37 -21s33 -10 54 -13c1 -12 7 -23 16 -31s20 -12 32 -12s23 4 32 12s15 19 16 31c31 4 56 12 75 23s29 24 29 38
+v-128c0 -18 -14 -34 -43 -46s-65 -18 -109 -18zM160 288c44 0 82 6 113 18s47 28 47 46v-8c0 -5 -1 -11 -2 -18s-3 -11 -6 -14v-96c0 -14 -10 -27 -29 -38s-44 -19 -76 -23c-2 11 -8 19 -17 26s-19 11 -30 11s-21 -4 -30 -11s-15 -15 -17 -26c-32 4 -57 12 -76 23
+s-29 24 -29 38v96c-5 5 -8 18 -8 40c0 -18 16 -34 47 -46s69 -18 113 -18zM312 56v-24l8 -16c0 -7 -3 -14 -8 -20c-11 -13 -30 -24 -58 -32s-59 -12 -94 -12s-66 4 -94 12s-47 19 -58 32c-5 6 -8 13 -8 20l8 16v24c0 -18 14 -34 43 -46s65 -18 109 -18s80 6 109 18
+s43 28 43 46z" />
+ <glyph glyph-name="ion-speakerphone" unicode="&#xf2b2;"
+d="M39 266c0 -37 20 -69 50 -86c-1 0 -2 1 -3 1s-4 1 -5 1v0c-35 3 -62 33 -69 69c-6 0 -12 7 -12 16c0 8 5 15 11 16c6 42 40 75 81 75h8c-36 -15 -61 -51 -61 -92zM433 357c10 -25 15 -56 15 -88s-5 -63 -15 -88l-3 -9c-6 -14 -15 -26 -24 -34c-10 -10 -22 -19 -34 -20h-3
+c-7 0 -15 2 -22 5c-3 2 -10 5 -10 5c-22 10 -84 28 -115 29c-4 -8 -10 -20 -12 -30c-2 -9 -6 -27 -7 -61c-1 -32 1 -59 3 -82c0 -2 1 -5 1 -7c0 -6 -2 -9 -9 -9h-77c-6 0 -9 3 -9 6v7c2 72 25 140 26 145c2 9 5 17 7 30c2 12 -27 13 -40 24c-29 17 -47 49 -47 86
+c0 41 25 77 59 92h42h19c58 3 114 21 163 50c1 1 3 1 4 2v0c8 4 16 6 24 6c13 0 26 -6 37 -16c9 -9 18 -21 24 -35c1 -3 2 -5 3 -8zM410 180c9 22 15 54 15 89s-6 66 -15 88c-8 18 -19 29 -30 29s-21 -11 -29 -29c-9 -22 -15 -53 -15 -88s6 -67 15 -89c8 -19 18 -33 29 -33
+s22 15 30 33z" />
+ <glyph glyph-name="ion-speedometer" unicode="&#xf2b3;"
+d="M312 192l8 -8l-64 -84v-4c0 -18 -14 -32 -32 -32s-32 14 -32 32s14 32 32 32h4zM224 352c124 0 224 -100 224 -224c0 -34 -8 -67 -22 -96h-36c15 27 25 57 26 88h-32v16h32c-1 29 -9 56 -22 81l-27 -15l-8 13l27 16c-8 12 -16 23 -26 33s-21 18 -33 26l-16 -27l-14 8
+l16 27c-25 13 -52 21 -81 22v-32h-16v32c-29 -1 -56 -9 -81 -22l16 -27l-14 -8l-16 27c-12 -8 -23 -16 -33 -26s-19 -21 -26 -33l28 -16l-8 -13l-28 15c-13 -25 -21 -52 -22 -81h32v-16h-32c1 -31 11 -61 26 -88h-36c-14 29 -22 62 -22 96c0 124 100 224 224 224z" />
+ <glyph glyph-name="ion-spoon" unicode="&#xf2b4;" horiz-adv-x="128"
+d="M128 288c0 64 -26 128 -64 128s-64 -64 -64 -128v0c1 -25 16 -54 37 -64l1 -1v0c3 -2 10 -6 10 -10c0 0 -16 -199 -16 -210s4 -20 10 -26s14 -9 22 -9v0v0c8 0 16 3 22 9s10 13 10 26s-16 210 -16 210c0 4 7 8 10 10l1 1c22 10 37 38 37 64z" />
+ <glyph glyph-name="ion-star" unicode="&#xf24e;"
+d="M448 248l-139 -104l55 -176l-140 112l-140 -112l55 176l-139 104h172l52 168l53 -168h171z" />
+ <glyph glyph-name="ion-stats-bars" unicode="&#xf2b5;" horiz-adv-x="352"
+d="M96 32v320h64v-320h-64zM0 32v96h64v-96h-64zM192 32v160h64v-160h-64zM288 32v224h64v-224h-64z" />
+ <glyph glyph-name="ion-steam" unicode="&#xf30b;" horiz-adv-x="512"
+d="M480 240c0 -20 -16 -37 -37 -37c-20 0 -37 16 -37 37c0 20 16 37 37 37c20 0 37 -17 37 -37zM443 309c38 0 69 -31 69 -69s-31 -70 -69 -70l-67 -48c-2 -26 -24 -47 -51 -47c-25 0 -46 18 -51 41l-196 78c-8 -5 -16 -7 -26 -7c-28 0 -52 24 -52 52s24 52 52 52
+c25 0 45 -18 50 -41l196 -79c8 5 17 8 27 8c2 0 3 -1 5 -1l43 62c0 38 32 69 70 69zM443 286c-26 0 -47 -20 -47 -46s21 -47 47 -47s46 21 46 47s-20 46 -46 46zM52 277c-21 0 -38 -17 -38 -38s17 -38 38 -38c3 0 5 0 8 1l-16 6v0c-15 7 -22 24 -16 39s24 23 39 17v0l19 -7
+c-6 12 -19 20 -34 20zM325 165c-3 0 -6 -1 -9 -1l16 -6c16 -6 23 -24 17 -40s-23 -23 -39 -17c-6 3 -13 6 -19 8c6 -12 19 -20 34 -20c21 0 38 17 38 38s-17 38 -38 38z" />
+ <glyph glyph-name="ion-stop" unicode="&#xf24f;" horiz-adv-x="384"
+d="M373 384c6 0 11 -5 11 -11v-362c0 -6 -5 -11 -11 -11h-362c-6 0 -11 5 -11 11v362c0 6 5 11 11 11h362z" />
+ <glyph glyph-name="ion-thermometer" unicode="&#xf2b6;" horiz-adv-x="160"
+d="M127 112c20 -14 33 -38 33 -64c0 -44 -36 -80 -80 -80s-80 36 -80 80c0 27 13 51 33 65v257c0 26 21 46 47 46s47 -20 47 -46v-258zM65 370v-50h30v50c0 8 -7 14 -15 14s-15 -6 -15 -14zM96 160v16h-16v-16h16zM96 192v64h-16v-64h16z" />
+ <glyph glyph-name="ion-thumbsdown" unicode="&#xf250;" horiz-adv-x="384"
+d="M24 195c-10 5 -18 17 -18 29c0 14 8 25 20 30c-4 5 -6 12 -6 19c0 14 8 25 20 30c-3 5 -5 11 -5 17c0 18 11 24 35 30s74 12 126 9c23 -1 55 -7 76 -7v32h112v-240h-112v16c-15 -1 -31 -4 -40 -14c-22 -23 -40 -65 -40 -108c0 -19 1 -29 -4 -34c-13 -13 -44 9 -52 37
+c-9 34 -1 62 1 87h-103c-19 0 -34 15 -34 34c0 15 10 29 24 33zM336 352c-9 0 -16 -7 -16 -16s7 -16 16 -16s16 7 16 16s-7 16 -16 16z" />
+ <glyph glyph-name="ion-thumbsup" unicode="&#xf251;" horiz-adv-x="384"
+d="M360 189c10 -5 18 -17 18 -29c0 -14 -8 -25 -20 -30c4 -5 6 -12 6 -19c0 -14 -8 -25 -20 -30c3 -5 5 -11 5 -17c0 -18 -11 -24 -35 -30s-74 -12 -126 -9c-23 1 -55 7 -76 7v-32h-112v240h112v-16c15 1 31 4 40 14c22 23 40 65 40 108c0 19 -1 29 4 34c13 13 44 -9 52 -37
+c9 -34 1 -62 -1 -87h103c19 0 34 -15 34 -34c0 -15 -10 -29 -24 -33zM48 32c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16z" />
+ <glyph glyph-name="ion-toggle-filled" unicode="&#xf354;"
+d="M320 240c26 0 48 -22 48 -48s-22 -48 -48 -48s-48 22 -48 48s22 48 48 48zM320 320c71 0 128 -57 128 -128s-57 -128 -128 -128h-192c-71 0 -128 57 -128 128s57 128 128 128h192zM320 112c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80z" />
+ <glyph glyph-name="ion-toggle" unicode="&#xf355;"
+d="M320 288h-192c-53 0 -96 -43 -96 -96s43 -96 96 -96h192c53 0 96 43 96 96s-43 96 -96 96zM320 320v0c71 0 128 -57 128 -128s-57 -128 -128 -128h-192c-71 0 -128 57 -128 128s57 128 128 128h192zM128 240c-26 0 -48 -22 -48 -48s22 -48 48 -48s48 22 48 48
+s-22 48 -48 48zM128 272v0c44 0 80 -36 80 -80s-36 -80 -80 -80s-80 36 -80 80s36 80 80 80z" />
+ <glyph glyph-name="ion-transgender" unicode="&#xf4f5;" horiz-adv-x="512"
+d="M368 448h144v-144h-40v76l-101 -100c8 -17 13 -36 13 -56c0 -63 -46 -115 -104 -126v-52h72v-46h-72v-64h-48v64h-72v46h72v52c-59 11 -104 63 -104 126c0 20 5 39 13 56l-22 22l-36 -36l-33 33l36 36l-46 45v-76h-40v144h144v-40h-70l43 -42l36 36l33 -33l-36 -36
+l17 -17c23 22 54 36 89 36c27 0 53 -8 74 -23c0 0 6 -5 15 -13l93 92h-70v40zM256 144c44 0 80 36 80 80s-36 80 -80 80s-80 -36 -80 -80s36 -80 80 -80z" />
+ <glyph glyph-name="ion-trash-a" unicode="&#xf252;" horiz-adv-x="352"
+d="M261 320v0h91v-32h-9s-5 -1 -8 -4s-4 -9 -4 -9l-19 -241c-2 -29 -2 -34 -36 -34h-200c-34 0 -34 5 -36 34l-19 242s-1 6 -4 9s-8 3 -8 3h-9v32h91v29c0 19 14 35 34 35h101c20 0 35 -16 35 -35v-29zM112 349v-29h128v29c0 10 -9 15 -19 15h-91c-10 0 -18 -5 -18 -15z
+M104 64h20l-10 192h-21zM187 64v192h-22v-192h22zM249 64l10 192h-20l-11 -192h21z" />
+ <glyph glyph-name="ion-trash-b" unicode="&#xf253;" horiz-adv-x="320"
+d="M318 315c3 -12 4 -11 -7 -11h-302c-11 0 -10 -1 -7 11c2 9 4 13 4 13c3 9 9 9 19 11l53 7c7 1 7 1 10 7c9 20 10 31 20 31h103c10 0 12 -11 21 -31c3 -6 3 -6 10 -7l53 -6c10 -2 16 -2 19 -11c0 0 2 -5 4 -14zM283 272c17 0 18 -2 17 -15l-19 -242c-2 -12 -2 -15 -17 -15
+h-208c-15 0 -15 3 -17 15l-19 242c-1 12 0 15 17 15h246z" />
+ <glyph glyph-name="ion-trophy" unicode="&#xf356;"
+d="M448 345c0 -25 2 -73 -22 -122c-15 -30 -36 -55 -63 -75c-23 -16 -49 -28 -77 -35c-16 -17 -32 -27 -46 -31v-33s0 -49 99 -49h13v-32h-256v32h13c85 0 97 35 99 46v36c-14 4 -30 14 -46 31c-28 7 -55 19 -77 35c-27 20 -48 45 -63 75c-17 36 -21 71 -22 97v0v11v0v21v0
+h80c-2 35 0 64 0 64h143h1h1h142s2 -29 0 -64h81v-7zM51 237c17 -34 43 -61 77 -78c-22 40 -33 84 -42 135c-1 8 -2 17 -3 26h-51c1 -23 5 -53 19 -83zM397 237c14 30 18 60 19 83h-51c-1 -9 -3 -18 -4 -26c-9 -51 -20 -95 -42 -135c34 17 61 43 78 78z" />
+ <glyph glyph-name="ion-tshirt-outline" unicode="&#xf4f6;"
+d="M146 362l-104 -31l11 -32l39 4l38 5l-2 -38l-14 -255h220l-14 255l-2 38l38 -5l39 -4l11 32l-104 31c-6 -8 -13 -14 -21 -19c-15 -10 -34 -15 -57 -15v0v0c-34 1 -59 11 -78 34zM288 400v0l160 -48l-32 -88l-64 8l16 -289h-288l16 289l-64 -8l-32 88l160 48
+c14 -27 31 -39 64 -40c33 0 50 13 64 40z" />
+ <glyph glyph-name="ion-tshirt" unicode="&#xf4f7;"
+d="M448 352l-32 -88l-64 8l16 -288h-288l16 288l-64 -8l-32 88l160 48c14 -27 31 -39 64 -40c33 0 50 13 64 40z" />
+ <glyph glyph-name="ion-umbrella" unicode="&#xf2b7;"
+d="M344 160v0v0v0zM104 160v0v0v0zM240 399c116 -8 208 -109 208 -227v-12c-4 25 -26 52 -52 52c-29 0 -52 -23 -52 -52v0c0 29 -23 52 -52 52s-49 -12 -52 -45v-135c0 -17 -6 -33 -18 -45s-29 -19 -46 -19c-35 0 -63 29 -63 64c0 9 7 16 16 16s16 -7 16 -16
+c0 -18 14 -32 31 -32c18 0 32 14 32 32v134c-1 24 -26 46 -52 46c-29 0 -52 -23 -52 -52v0c0 29 -23 52 -52 52c-27 0 -49 -26 -52 -52v18c0 118 92 213 208 221v1c0 9 7 16 16 16s16 -7 16 -16v-1z" />
+ <glyph glyph-name="ion-university" unicode="&#xf357;"
+d="M224 384l224 -111l-92 -60l-132 -85l-160 102v-198l-32 16v203l-32 21zM358 192l10 -82c-16 -12 -112 -78 -144 -110c-32 32 -128 98 -144 110l9 82l135 -88z" />
+ <glyph glyph-name="ion-unlocked" unicode="&#xf254;" horiz-adv-x="384"
+d="M22 -32c-12 0 -22 10 -22 22v212c0 12 10 22 22 22h3h19v31c0 42 17 87 43 115s64 46 105 46v0v0c41 0 79 -18 105 -46c20 -21 33 -51 39 -82h-53c-5 18 -13 35 -24 47v0v1c-18 19 -42 29 -67 29v0v0c-25 0 -49 -10 -67 -29v-1v0c-18 -19 -28 -53 -28 -80v-31h265
+c12 0 22 -10 22 -22v-212c0 -12 -10 -22 -22 -22h-340z" />
+ <glyph glyph-name="ion-upload" unicode="&#xf255;"
+d="M366 215c45 0 82 -37 82 -83s-37 -84 -82 -84h-110v80h48l-80 84l-80 -84h48v-80h-102c-49 0 -90 41 -90 91c0 40 26 74 61 86c5 29 29 51 59 51c10 0 18 -3 26 -7c19 40 59 67 105 67c64 0 115 -53 115 -118v-3z" />
+ <glyph glyph-name="ion-usb" unicode="&#xf2b8;" horiz-adv-x="256"
+d="M16 228v0v0zM256 320c0 -11 -6 -21 -14 -27v0c-2 -1 -3 -5 -3 -7c-1 -20 -3 -36 -9 -50c-7 -19 -20 -33 -39 -46c-17 -12 -29 -21 -36 -34c-7 -12 -11 -28 -11 -53v-24c0 -7 2 -13 10 -18c4 -2 7 -6 10 -9c8 -9 14 -21 14 -34c0 -28 -22 -50 -50 -50s-50 22 -50 50v1v0
+c0 18 10 33 24 42c5 4 9 5 9 18v0c0 14 -3 17 -10 27s-18 17 -32 26c-19 13 -33 27 -40 46c-6 15 -8 31 -9 39s-2 9 -4 11c-10 6 -16 16 -16 28c0 18 14 32 32 32s32 -14 32 -32c0 -10 -4 -20 -12 -26c-3 -2 -4 -11 -4 -14v0v0c0 -9 3 -18 7 -28c10 -21 45 -44 52 -44
+s8 5 8 12v196s-1 2 -3 4h-1v1v0c-9 6 -15 16 -15 27c0 18 14 32 32 32s32 -14 32 -32c0 -11 -5 -21 -14 -27v0c-2 -2 -2 -3 -2 -5v-140c0 -10 2 -12 8 -11c13 3 48 30 52 43c3 10 6 23 7 41v1c0 2 -2 4 -3 6c-10 6 -16 16 -16 28c0 18 14 32 32 32s32 -14 32 -32zM32 240
+c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM128 368c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16zM224 304c9 0 16 7 16 16s-7 16 -16 16s-16 -7 -16 -16s7 -16 16 -16z" />
+ <glyph glyph-name="ion-videocamera" unicode="&#xf256;"
+d="M335 263v-66l113 35v-89v-88l-113 35v-65c0 -5 -4 -9 -9 -9h-317c-5 0 -9 4 -9 9v12v55v171c0 5 4 9 9 9h208v38c0 4 -6 10 -10 10h-176v48h178c36 0 65 -29 65 -64v-32h52c5 0 9 -4 9 -9zM226 107c20 0 36 16 36 36s-16 35 -36 35s-36 -15 -36 -35c0 -10 4 -19 11 -26
+h-68c7 7 11 16 11 26c0 20 -16 36 -36 36s-36 -16 -36 -36s16 -36 36 -36h12h95h11z" />
+ <glyph glyph-name="ion-volume-high" unicode="&#xf257;"
+d="M199 40l-95 88h-104v128h104l95 88v-304zM255 92l-20 16c17 24 27 52 27 84s-10 60 -27 84l20 16c20 -28 33 -63 33 -100s-13 -72 -33 -100zM322 46l-21 16c27 36 43 81 43 130s-16 94 -43 130l21 16c30 -41 48 -91 48 -146s-18 -105 -48 -146zM365 369l20 15
+c39 -54 63 -120 63 -192s-24 -138 -63 -192l-20 15c36 49 58 111 58 177s-22 128 -58 177z" />
+ <glyph glyph-name="ion-volume-low" unicode="&#xf258;" horiz-adv-x="288"
+d="M199 40l-95 88h-104v128h104l95 88v-304zM255 92l-20 16c17 24 28 52 28 84s-11 60 -28 84l20 16c20 -28 33 -63 33 -100s-13 -72 -33 -100z" />
+ <glyph glyph-name="ion-volume-medium" unicode="&#xf259;" horiz-adv-x="370"
+d="M199 40l-95 88h-104v128h104l95 88v-304zM255 92l-20 16c17 24 28 52 28 84s-11 60 -28 84l20 16c20 -28 33 -63 33 -100s-13 -72 -33 -100zM322 46l-21 16c27 36 43 81 43 130s-16 94 -43 130l21 16c30 -41 48 -91 48 -146s-18 -105 -48 -146z" />
+ <glyph glyph-name="ion-volume-mute" unicode="&#xf25a;"
+d="M224 231l47 51v-180l-47 51h-65v78h65zM332 388c69 -38 116 -112 116 -196c0 -124 -100 -224 -224 -224c-39 0 -76 10 -108 27l-1 1c-69 38 -115 112 -115 196c0 124 100 224 224 224c39 0 75 -10 107 -28h1zM362 93c20 28 33 62 33 99c0 66 -38 123 -92 151
+c-6 3 -11 6 -17 8c-19 7 -40 11 -62 11c-37 0 -71 -12 -99 -32l73 -74h-76l-36 35c-20 -28 -32 -62 -32 -99c0 -65 36 -121 90 -150c6 -3 13 -7 19 -9c19 -7 39 -11 61 -11c37 0 72 12 100 32l-20 20v77z" />
+ <glyph glyph-name="ion-wand" unicode="&#xf358;"
+d="M192 208l48 48l48 -48l-48 -48zM0 16l176 176l48 -48l-176 -176zM224 352v64h32v-64h-32zM398 344l-45 -45l-23 22l46 45zM127 299l-45 45l22 22l45 -45zM376 50l-46 45l23 23l45 -46zM384 192v32h64v-32h-64z" />
+ <glyph glyph-name="ion-waterdrop" unicode="&#xf25b;" horiz-adv-x="320"
+d="M175 409c40 -41 145 -160 145 -288c0 -85 -72 -153 -160 -153c-56 0 -106 27 -134 69c-6 9 -11 19 -15 29c-7 17 -11 35 -11 55v4c1 67 31 131 64 183c20 31 42 57 59 77c9 10 16 18 22 24l1 1v0c4 3 8 6 14 6c5 0 10 -3 14 -6v0zM160 24c55 0 100 45 100 100
+c0 14 -3 28 -8 40c-17 -65 -70 -116 -136 -130c13 -6 28 -10 44 -10z" />
+ <glyph glyph-name="ion-wifi" unicode="&#xf25c;"
+d="M224 352c80 0 156 -30 214 -84l10 -10l-10 -9l-32 -32l-10 -10l-9 9c-44 41 -103 64 -163 64s-119 -23 -163 -64l-9 -9l-10 10l-32 32l-10 9l10 10c58 54 134 84 214 84v0zM365 192l11 -10l-10 -10l-33 -32l-9 -9l-10 8c-25 22 -57 35 -90 35s-65 -13 -90 -35l-10 -8
+l-9 9l-33 32l-10 10l11 10c37 33 83 52 132 54v0h9v0v0c52 0 102 -19 141 -54zM224 32l-10 10l-52 52l-11 10l12 10c17 11 32 20 61 20s47 -9 62 -20l11 -10l-10 -10l-53 -52z" />
+ <glyph glyph-name="ion-wineglass" unicode="&#xf2b9;" horiz-adv-x="256"
+d="M167 153c-11 -4 -24 -8 -24 -32v-94c0 -11 4 -19 12 -25c3 -2 7 -4 15 -6c32 -9 48 -16 50 -18c2 -1 4 -3 4 -7c0 0 -14 -3 -96 -3s-96 3 -96 3c0 4 2 6 4 7c2 2 18 9 50 18c8 2 11 4 14 6c8 6 11 14 11 25v94c0 24 -11 28 -22 32s-18 6 -26 11c-12 7 -23 16 -32 26
+c-20 23 -31 52 -31 87c0 50 4 100 8 114s14 25 31 25h178c17 0 27 -11 31 -25s8 -65 8 -115c0 -35 -11 -63 -31 -86c-9 -10 -20 -19 -32 -26c-8 -5 -15 -7 -26 -11zM128 178c26 0 50 11 67 28l6 6c16 18 22 35 23 65s-2 83 -8 107h-177c-7 -35 -8 -80 -7 -108s7 -46 23 -64
+c2 -3 4 -6 7 -8c17 -16 41 -26 66 -26zM208 277c0 -10 -1 -20 -4 -29s-8 -18 -15 -25l-5 -5c-14 -14 -34 -23 -56 -23c-21 0 -41 8 -55 22l-6 6c-7 7 -12 16 -15 25s-3 15 -4 29c-1 9 0 34 1 53c1 10 2 19 3 22h153c1 -6 2 -14 2 -22c1 -21 1 -45 1 -53zM192 269v0v26
+c0 4 -4 8 -8 8s-8 -4 -8 -8v-26c0 -3 1 -6 3 -7c1 -1 3 -1 5 -1c4 0 8 3 8 8zM191 316c1 2 1 4 1 6s-2 4 -4 5s-4 1 -6 1s-4 -1 -5 -3s-1 -4 -1 -6s2 -4 4 -5s4 -1 6 -1s4 1 5 3z" />
+ <glyph glyph-name="ion-woman" unicode="&#xf25d;" horiz-adv-x="192"
+d="M30 299c3 12 17 33 42 34h48c24 -1 38 -22 42 -34l29 -104c6 -23 -21 -32 -27 -10l-26 96h-9l46 -169h-43v-127c0 -23 -31 -23 -31 0v127h-10v-127c0 -23 -32 -23 -32 0v127h-42l45 169h-7l-27 -96c-7 -21 -33 -13 -27 10zM133 379c0 -21 -17 -37 -37 -37s-37 16 -37 37
+s17 37 37 37s37 -16 37 -37z" />
+ <glyph glyph-name="ion-wrench" unicode="&#xf2ba;"
+d="M430 333c14 -14 19 -31 18 -44s-6 -39 -32 -65s-77 -42 -113 -24c-5 3 -13 5 -21 -3c-10 -9 -202 -215 -202 -215c-17 -19 -48 -18 -66 0s-19 49 0 66c0 0 207 194 215 202s5 16 3 22c-20 47 2 89 24 112c22 24 51 31 65 32c13 1 31 -5 44 -18l-57 -56l10 -56l55 -10z
+M59 5c6 6 6 17 0 23s-16 6 -22 0s-6 -17 0 -23s16 -6 22 0z" />
+ <glyph glyph-name="ion-xbox" unicode="&#xf30c;"
+d="M95 200c-49 -72 -50 -139 -50 -143c-28 38 -45 84 -45 135c0 67 30 128 77 169l3 -1c51 -18 93 -68 93 -68s-38 -33 -78 -92zM448 192c0 -51 -17 -97 -45 -135c0 4 -1 71 -50 143c-40 59 -78 92 -78 92s42 50 93 68l3 1c47 -41 77 -102 77 -169zM169 367
+c-37 17 -65 12 -72 10c36 25 80 39 127 39s91 -14 127 -39c-7 2 -35 6 -72 -10c-29 -13 -55 -35 -55 -35s-26 22 -55 35zM327 155c40 -49 54 -85 62 -108l2 -5c-41 -46 -101 -74 -167 -74s-126 28 -167 74l1 5c8 23 23 59 63 108c46 57 103 94 103 94s57 -37 103 -94z" />
+ </font>
+</defs></svg>
diff --git a/public/assets/fonts/ionicons.ttf b/public/assets/fonts/ionicons.ttf
index 573d5b3..c4e4632 100755
--- a/public/assets/fonts/ionicons.ttf
+++ b/public/assets/fonts/ionicons.ttf
Binary files differ
diff --git a/public/assets/fonts/ionicons.woff b/public/assets/fonts/ionicons.woff
index 337b87f..5f3a14e 100755
--- a/public/assets/fonts/ionicons.woff
+++ b/public/assets/fonts/ionicons.woff
Binary files differ
diff --git a/public/assets/img/360.png b/public/assets/img/360.png
new file mode 100644
index 0000000..853952b
--- /dev/null
+++ b/public/assets/img/360.png
Binary files differ
diff --git a/public/assets/img/delete-cursor.png b/public/assets/img/delete-cursor.png
new file mode 100644
index 0000000..d7822c8
--- /dev/null
+++ b/public/assets/img/delete-cursor.png
Binary files differ
diff --git a/public/assets/img/keys.png b/public/assets/img/keys.png
new file mode 100644
index 0000000..edb1d5e
--- /dev/null
+++ b/public/assets/img/keys.png
Binary files differ
diff --git a/public/assets/img/offbeatrepeat.jpg b/public/assets/img/offbeatrepeat.jpg
new file mode 100644
index 0000000..4fa90c7
--- /dev/null
+++ b/public/assets/img/offbeatrepeat.jpg
Binary files differ
diff --git a/public/assets/img/plainpattern.png b/public/assets/img/plainpattern.png
new file mode 100644
index 0000000..1c4f12c
--- /dev/null
+++ b/public/assets/img/plainpattern.png
Binary files differ
diff --git a/public/assets/img/plainpattern2.png b/public/assets/img/plainpattern2.png
new file mode 100644
index 0000000..10d57a5
--- /dev/null
+++ b/public/assets/img/plainpattern2.png
Binary files differ
diff --git a/public/assets/img/plainpattern3.png b/public/assets/img/plainpattern3.png
new file mode 100644
index 0000000..3048665
--- /dev/null
+++ b/public/assets/img/plainpattern3.png
Binary files differ
diff --git a/public/assets/img/text-cursor.png b/public/assets/img/text-cursor.png
new file mode 100644
index 0000000..66e9e0d
--- /dev/null
+++ b/public/assets/img/text-cursor.png
Binary files differ
diff --git a/public/assets/javascripts/app.js b/public/assets/javascripts/app.js
index 1dd8a5e..3cafeca 100644
--- a/public/assets/javascripts/app.js
+++ b/public/assets/javascripts/app.js
@@ -1,69 +1,34 @@
-var is_iphone = (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i));
-var is_ipad = (navigator.userAgent.match(/iPad/i));
-var is_android = (navigator.userAgent.match(/Android/i))
-var is_mobile = is_iphone || is_ipad || is_android;
-
if (is_mobile) {
- // window.location.href = "mobile.html"
- $("html").addClass("mobile");
-}
-else if ($.browser.msie || ! has3d()) {
- // window.location.href = "error.html"
+ $("html").addClass("mobile")
}
else {
- $("html").addClass("desktop");
+ $("html").addClass("desktop")
}
+
var scene, cam, map;
var app = new function(){}
app.mode = { editor: false, builder: false }
-
+
app.init = function () {
app.tube = new Tube ()
app.router = new SiteRouter ()
}
app.launch = function () {
- var movements
-
- scene = new MX.Scene().addTo('#scene')
- scene.width = window.innerWidth
- scene.height = window.innerHeight
- scene.perspective = window.innerHeight
-
- window.onresize = function () {
- scene.width = window.innerWidth
- scene.height = window.innerHeight
- scene.perspective = window.innerHeight
- scene.update()
- }
-
- cam = scene.camera
- cam.y = viewHeight
-
- if (MX.Map) map = app.map = new MX.Map()
-
- if (is_mobile) {
- app.movements = new MX.MobileMovements(cam, viewHeight)
- }
- else {
- app.movements = new MX.Movements(cam, viewHeight)
- }
- app.movements.init()
-
+ if ($.browser.msie || ! has3d()) { return app.fallback() }
+
+ var last_t = 0
function animate (t) {
+ var dt = t - last_t
+ last_t = t
requestAnimationFrame(animate)
- environment.update(t)
- window.path && path.update(t)
- app.movements.update()
- scene.update()
+ environment.update(t, dt)
}
- window.inAnimation = true
-
var loader = new Loader(function(){
$("#loader").hide()
window.environment && window.environment.init()
@@ -74,6 +39,20 @@ app.launch = function () {
// loader.preloadImages([])
loader.ready()
+
+ window.scrollTo(0,0)
+}
+
+app.fallback = function(){
+ app.unsupported = true
+ var msg = "Sorry, your browser is not supported.<br><br>" +
+ "Please use <a href='http://chrome.com/'>Chrome</a> or <a href='https://www.apple.com/safari/'>Safari</a> or <a href='http://getfirefox.com/'>Firefox</a>."
+ var $fallback = $("<div>")
+ $fallback.attr('id', 'fallback')
+ $fallback.html(msg)
+ $('body').append($fallback)
+ $("#keyhint").hide()
+ $("#editorView").hide()
}
app.on = function(){
diff --git a/public/assets/javascripts/defaults.js b/public/assets/javascripts/defaults.js
index 038a882..1e1ac5b 100644
--- a/public/assets/javascripts/defaults.js
+++ b/public/assets/javascripts/defaults.js
@@ -1,9 +1,11 @@
+app = window.app || {}
app.defaults = {
viewHeight: window.viewHeight = 186,
+ wallHeight: 397,
units: app.units = "ft",
footResolution: 36,
meterResolution: 100,
- wallOpacity: 0.95,
+ wallOpacity: 0.98,
outlineWidth: 2,
colors: {
wall: [255,255,255],
@@ -12,3 +14,8 @@ app.defaults = {
ceiling: [255,255,255],
},
}
+
+window.marked && marked.setOptions({
+ sanitize: true,
+ smartypants: true,
+})
diff --git a/public/assets/javascripts/mx/extensions/mx.movements.js b/public/assets/javascripts/mx/extensions/mx.movements.js
index 669a7f4..3e34c1b 100644
--- a/public/assets/javascripts/mx/extensions/mx.movements.js
+++ b/public/assets/javascripts/mx/extensions/mx.movements.js
@@ -16,193 +16,281 @@ MX.Movements = function (cam) {
creeping = false,
locked = false,
gravity = false,
- rotationX_min = PI/-2,
- rotationX_max = PI/2
+ rotationX_min = PI/-4,
+ rotationX_max = PI/6
var v = 12,
- vr = Math.PI * 0.012,
+ vr = Math.PI * 0.018,
jumpV = 23,
vx = vy = vz = 0,
creepFactor = 0.3
+ var mouseX, mouseY, dx, dy, rotX, rotY, dragging = false
+
+ var trackpad
+
var DEFAULT_SCALE = 1.0, scale = DEFAULT_SCALE
var pos = { x: 0, y: 0, z: 0, rotationX: 0, rotationY: 0 }
- return {
+ $(document).one("keydown", function(){
+ $("#keyhint").fadeOut(250);
+ $('.reader #minimap').addClass('active');
+ })
- init: function () {
+ function clampRotation( vr ) {
+ if (window.Rooms && Rooms.mover.noclip) {
+ return clamp(vr, PI/-2, PI/2 )
+ }
+ else {
+ return clamp(vr, PI/-4, PI/6 )
+ }
+ }
- document.addEventListener('keydown', function (e) {
- // console.log(e.keyCode)
- if (locked || e.altKey || e.metaKey || e.ctrlKey) {
- return
- }
- switch ( e.keyCode ) {
-
- case 16: // shift
- creeping = true
- break
+ var exports = {
+
+ init: function () {
+
+ trackpad = new wheel ({
+ el: scene.el,
+ update: exports.mousewheel,
+ })
+
+ document.addEventListener('keydown', exports.keydown)
+ document.addEventListener('keyup', exports.keyup)
+ document.addEventListener('mousedown', exports.mousedown)
+ document.addEventListener('mousemove', exports.mousemove)
+ document.addEventListener('mouseup', exports.mouseup)
+ window.addEventListener('blur', exports.reset)
+ window.addEventListener('focus', exports.reset)
+ },
+
+ keydown: function (e) {
+ // console.log(e.keyCode)
+ if (locked || e.altKey || e.metaKey || e.ctrlKey) {
+ return
+ }
+ switch ( e.keyCode ) {
+
+ case 16: // shift
+ creeping = true
+ break
- case 38: // up
- case 87: // w
- moveForward = true
- break
+ case 38: // up
+ case 87: // w
+ moveForward = true
+ break
- case 37: // left
- case 65: // a
- moveLeft = true
- break
+ case 65: // a
+ moveLeft = true
+ break
- case 40: // down
- case 83: // s
- moveBackward = true
- break
+ case 40: // down
+ case 83: // s
+ moveBackward = true
+ break
- case 39: // right
- case 68: // d
- moveRight = true
- break
+ case 68: // d
+ moveRight = true
+ break
- case 81: // q
- turnLeft = true
- break
-
- case 69: // e
- turnRight = true
- break
-
- case 82: // r
- turnUp = true
- break
+ case 37: // left
+ case 81: // q
+ turnLeft = true
+ break
+
+ case 39: // right
+ case 69: // e
+ turnRight = true
+ break
+
+ case 82: // r
+ turnUp = true
+ break
- case 70: // f
- turnDown = true
- break
+ case 70: // f
+ turnDown = true
+ break
- case 32: // space
- if (gravity) {
- jumping = true
- vy = abs(vy) + jumpV * scale
- if (e.shiftKey) {
- vy *= -1
- }
+ case 32: // space
+ if (gravity) {
+ jumping = true
+ vy = abs(vy) + jumpV * scale
+ if (e.shiftKey) {
+ vy *= -1
+ }
+ }
+ else {
+ if (e.shiftKey) {
+ moveDown = true
}
else {
- if (e.shiftKey) {
- moveDown = true
- }
- else {
- moveUp = true
- }
+ moveUp = true
}
- break
+ }
+ break
- case 27: // esc
- map.toggle()
- break
- }
- })
+ case 27: // esc
+ if (Scenery.nextMedia) {
+ Scenery.nextMedia = null
+ app.tube('cancel-scenery')
+ }
+ else if (Scenery.nextWallpaper) {
+ Scenery.nextWallpaper = null
+ app.tube('cancel-wallpaper')
+ }
+ else if (app.controller.mediaViewer && app.controller.mediaViewer.$el.hasClass("active")) {
+ app.controller.mediaViewer.hide()
+ $(".inuse").removeClass("inuse")
+ }
+ else if (app.controller.colorControl && app.controller.colorControl.$el.hasClass('active')) {
+ app.controller.colorControl.hide()
+ $(".inuse").removeClass("inuse")
+ }
+ else if (app.controller.wallpaperPicker && app.controller.wallpaperPicker.$el.hasClass('active')) {
+ app.controller.wallpaperPicker.hide()
+ $(".inuse").removeClass("inuse")
+ }
+ else if (app.controller.presets && app.controller.presets.$el.hasClass('active')) {
+ app.controller.presets.hide()
+ $(".inuse").removeClass("inuse")
+ }
+ else if (Rooms.shapesMode) {
+ // don't show map in editor for now..
+ }
+ else {
+ app.controller.toolbar.toggleMap()
+ }
+ break
+
+ case 8: // backspace
+ e.preventDefault()
+ if (app.controller.sculptureEditor && app.controller.sculptureEditor.sculpture) {
+ app.controller.sculptureEditor.sculpture.remove()
+ }
+ else if (app.controller.mediaEditor && app.controller.mediaEditor.scenery) {
+ app.controller.mediaEditor.scenery.remove()
+ }
+ else if (app.controller.textEditor && app.controller.textEditor.scenery) {
+ app.controller.textEditor.scenery.remove()
+ }
+ }
+ },
- document.addEventListener('keyup', function (e) {
- if (locked) return;
- switch ( e.keyCode ) {
-
- case 16: // shift
- creeping = false
- break
+ keyup: function (e) {
+ if (locked) return;
+ switch ( e.keyCode ) {
+
+ case 16: // shift
+ creeping = false
+ break
- case 38: // up
- case 87: // w
- moveForward = false
- break
+ case 38: // up
+ case 87: // w
+ moveForward = false
+ break
- case 37: // left
- case 65: // a
- moveLeft = false
- break
+ case 65: // a
+ moveLeft = false
+ break
- case 40: // down
- case 83: // s
- moveBackward = false
- break
+ case 40: // down
+ case 83: // s
+ moveBackward = false
+ break
- case 39: // right
- case 68: // d
- moveRight = false
- break
+ case 68: // d
+ moveRight = false
+ break
- case 81: // q
- turnLeft = false
- break
-
- case 69: // e
- turnRight = false
- break
+ case 37: // left
+ case 81: // q
+ turnLeft = false
+ break
+
+ case 39: // right
+ case 69: // e
+ turnRight = false
+ break
- case 82: // r
- turnUp = false
- break
+ case 82: // r
+ turnUp = false
+ break
- case 70: // f
- turnDown = false
- break
+ case 70: // f
+ turnDown = false
+ break
- case 32: // space
- moveUp = moveDown = false
- break
+ case 32: // space
+ moveUp = moveDown = false
+ break
/*
- case 48: // 0
- cam.rotationX = 0
- cam.rotationY = 0
- cam.x = 0
- cam.y = viewHeight
- cam.z = 0
- break
+ case 48: // 0
+ movements.center()
+ break
*/
- }
- })
-
- var mouseX, mouseY, dx, dy, rotX, rotY, dragging = false
- document.addEventListener('mousedown', function (e) {
- if (locked) return;
- mouseX = e.pageX
- mouseY = e.pageY
- rotX = cam.rotationX
- rotY = cam.rotationY
- dragging = true
- })
-
- document.addEventListener('mousemove', function (e) {
- if (locked || ! dragging) return
- var dx = (e.pageX - mouseX) / window.innerWidth * Math.PI/3
- var dy = (e.pageY - mouseY) / window.innerHeight * Math.PI/3
- cam.rotationY = rotY + dx
- cam.rotationX = clamp( rotX - dy, rotationX_min, rotationX_max )
- })
-
- document.addEventListener('mouseup', function (e) {
- dragging = false
- })
-
- window.addEventListener('blur', reset)
- window.addEventListener('focus', reset)
- function reset(){
- moveForward = moveLeft = moveBackward = moveRight = moveUp = moveDown = turnLeft = turnRight = jumping = dragging = creeping = false
}
+ },
+
+ center: function(){
+ cam.rotationX = 0
+ cam.rotationY = 0
+ cam.x = 0
+ cam.y = viewHeight
+ cam.z = 0
+ },
+ mousedown: function (e) {
+ if (locked) return;
+ mouseX = e.pageX
+ mouseY = e.pageY
+ rotX = cam.rotationX
+ rotY = cam.rotationY
+ dragging = true
+ },
+
+ mousemove: function (e) {
+ if (locked || ! dragging) return
+ var dx = (e.pageX - mouseX) / window.innerWidth * Math.PI/3
+ var dy = (e.pageY - mouseY) / window.innerHeight * Math.PI/3
+ cam.rotationY = rotY + dx
+ cam.rotationX = clampRotation( rotX - dy )
+ },
+
+ mouseup: function (e) {
+ dragging = false
+ },
+
+ reset: function(){
+ moveForward = moveLeft = moveBackward = moveRight = moveUp = moveDown = turnLeft = turnRight = jumping = dragging = creeping = false
+ },
+
+ mousewheel: function (e, deltaY, deltaX) {
+ if (e.shiftKey) {
+ cam.rotationY -= deltaY / 150
+ }
+ else {
+ pos.x += deltaY * Math.cos(cam.rotationY + Math.PI / 2) * 10
+ pos.z += deltaY * Math.sin(cam.rotationY + Math.PI / 2) * 10
+ app.tube("move", pos)
+ }
},
- update: function () {
+ update: function (dt) {
- if (locked) return;
+ if (locked) { return }
var ry = cam.rotationY
var s = creeping ? scale * creepFactor : scale
- var vrrrr = creeping ? vr * creepFactor * 5 : vr
+ var vrrrr = creeping ? vr * creepFactor * 5 : vr * 0.5
var moving = moveForward || moveBackward || moveRight || moveLeft || moveUp || moveDown || turnLeft || turnRight || turnUp || turnDown
vx = vz = 0
+
+ var vv = v
+// vv *= dt / 100 * 8
+// s *= dt / 100 * 8
+// console.log(dt / 100 * 8)
pos.x = cam.x
pos.z = cam.z
@@ -210,33 +298,33 @@ MX.Movements = function (cam) {
if (moving) {
if (moveForward) {
- vx += v * Math.cos(ry + Math.PI / 2) * s
- vz += v * Math.sin(ry + Math.PI / 2) * s
+ vx += vv * Math.cos(ry + Math.PI / 2) * s
+ vz += vv * Math.sin(ry + Math.PI / 2) * s
}
if (moveBackward) {
- vx -= v * Math.cos(ry + Math.PI / 2) * s
- vz -= v * Math.sin(ry + Math.PI / 2) * s
+ vx -= vv * Math.cos(ry + Math.PI / 2) * s
+ vz -= vv * Math.sin(ry + Math.PI / 2) * s
}
if (moveLeft) {
- vx -= v * Math.cos(ry) * s
- vz -= v * Math.sin(ry) * s
+ vx -= vv * Math.cos(ry) * s
+ vz -= vv * Math.sin(ry) * s
}
if (moveRight) {
- vx += v * Math.cos(ry) * s
- vz += v * Math.sin(ry) * s
+ vx += vv * Math.cos(ry) * s
+ vz += vv * Math.sin(ry) * s
}
if (moveUp) {
- pos.y += v * scale
+ pos.y += vv * scale
}
if (moveDown) {
- pos.y -= v * scale
+ pos.y -= vv * scale
}
if (turnUp) {
- cam.rotationX = clamp( cam.rotationX - vrrrr*s, rotationX_min, rotationX_max)
+ cam.rotationX = clampRotation( cam.rotationX - vrrrr*s )
}
if (turnDown) {
- cam.rotationX = clamp( cam.rotationX + vrrrr*s, rotationX_min, rotationX_max)
+ cam.rotationX = clampRotation( cam.rotationX + vrrrr*s )
}
if (turnLeft) {
cam.rotationY += vrrrr*s
@@ -261,15 +349,13 @@ MX.Movements = function (cam) {
pos.y = viewHeight
vy = 0
jumping = false
- vz = vz || 1
}
- var ceiling = (Rooms.mover.room ? Rooms.mover.room.height : 5000)
+ var ceiling = ((window.Rooms && Rooms.mover.room) ? Rooms.mover.room.height : 5000)
- if (pos.y >= ceiling) {
+ if (pos.y >= ceiling-5) {
vy = 0
- pos.y = ceiling
- vz = vz || 1
+ pos.y = ceiling-5
}
}
@@ -286,4 +372,6 @@ MX.Movements = function (cam) {
velocity: function(n){ v = clamp(n, 1, 50) },
jumpVelocity: function(n){ jumpV = clamp(n, 1, 50) },
}
+
+ return exports
}
diff --git a/public/assets/javascripts/mx/extensions/mx.movementsMobile.js b/public/assets/javascripts/mx/extensions/mx.movementsMobile.js
index 994c8d7..95b61d1 100644
--- a/public/assets/javascripts/mx/extensions/mx.movementsMobile.js
+++ b/public/assets/javascripts/mx/extensions/mx.movementsMobile.js
@@ -14,56 +14,169 @@ MX.MobileMovements = function (cam) {
var pos = { x: 0, y: viewHeight, z: 0, rotationX: 0, rotationY: 0 }
var pointX, pointY, deltaX, deltaY, distX = 0, distY = 0, absDistX = 0, absDistY = 0, startTime
-
- return {
+
+ var rotationX = 0, rotationY = 0, destRotationX = 0, destRotationY = 0
+ var rotationSum = 0
+ var rotationMedian = 0
+ var orientationMax = 0
+ var samples = 0
+ var sampleThreshold = 120
+ var lastAlpha
+
+ var is_portrait
+
+ var exports = {
init: function () {
- document.addEventListener("touchstart", function(e){
- if (e.touches.length == 1) {
- touching = true
-
- startTime = Date.now()
-
- var point = event.touches[0]
- pointX = point.pageX
- pointY = point.pageY
- distX = distY = 0
- pos.x = cam.x
- pos.z = cam.z
- pos.rotationY = cam.rotationY
- }
- })
- document.addEventListener("touchmove", function(e){
- e.preventDefault()
- if (e.touches.length == 1) {
+ exports.orientationchange()
+
+ document.addEventListener("touchstart", exports.touchstart)
+ document.addEventListener("touchmove", exports.touchmove)
+ document.addEventListener("touchend", exports.touchend)
+ window.addEventListener('orientationchange', exports.orientationchange)
+ window.addEventListener("devicemotion", exports.devicemotion)
+ window.addEventListener("deviceorientation", exports.deviceorientation)
+ },
+ touchstart: function(e){
+ if (e.touches.length == 1) {
+ touching = true
+
+ startTime = Date.now()
+
+ var point = event.touches[0]
+ pointX = point.pageX
+ pointY = point.pageY
+ distX = distY = 0
+ pos.x = cam.x
+ pos.z = cam.z
+ pos.rotationY = cam.rotationY
+ }
+ },
+ touchmove: function(e){
+ e.preventDefault()
+ if (e.touches.length == 1) {
+
+ var timestamp = Date.now()
+ var point = event.touches[0]
+ deltaX = point.pageX - pointX
+ deltaY = point.pageY - pointY
+
+ pointX = point.pageX
+ pointY = point.pageY
+
+ distX += deltaX
+ distY += deltaY
+ absDistX = abs(distX)
+ absDistY = abs(distY)
+ }
+ },
+ touchend: function(e){
+ e.preventDefault()
+ if (e.touches.length == 0) {
+ touching = directionLocked = false
+ var timestamp = Date.now()
+ var duration = startTime - timestamp
+ if (duration < 300) {
+ }
+ }
+ },
+ orientationchange: function(e){
+ is_portrait = window.innerWidth < window.innerHeight
+ if (is_portrait) {
+ lastAlpha = 0
+ }
+ },
+ devicemotion: function(e) {
+ if (! is_portrait) return;
+ var rotationBeta = e.rotationRate.alpha; // weird!
+ rotationSum += rotationBeta;
+ samples += 1;
+ },
+ deviceorientation: function (e) {
+ if (! lastAlpha) { lastAlpha = e.alpha }
+ is_portrait ? exports.portraitorientation(e) : exports.landscapeorientation(e)
+ },
+ portraitorientation: function(e) {
+ // compass gives most accurate orientation in portrait mode
+ var alpha, dx = 0, dy = 0
+
+ if (e.webkitCompassHeading) {
+ alpha = 180 - e.webkitCompassHeading;
+ }
+ else {
+ alpha = 180 - e.alpha;
+ }
+
+ // android rotates in reverse
+ if (is_android) {
+ alpha = 360 - alpha
+ }
+
+ // use rotationRate to gauge if we've tilted the screen past vertical
+ // for looking at ceiling
+ if (e.beta > orientationMax) {
+ orientationMax = e.beta
+ rotationMedian = rotationSum
+ }
+
+ // this number was only going to 83 max.. not 90.. weird
+ var beta = e.beta + 7;
+
+ // if we've got enough motion data, we should be able to determine
+ // if we've tilted backwards. otherwise, lock to the horizon.
+ if (! is_android && samples > sampleThreshold) {
+ dx = rotationSum > rotationMedian ? e.beta - 90 : 90 - e.beta
+ }
+ else {
+ dx = 0
+ }
+
+ // avoid jumping around in a circle
+ if (Math.abs(alpha - lastAlpha) < 100 || Math.abs(alpha - lastAlpha) > 300) {
+ dy = alpha - lastAlpha
+ lastAlpha = alpha
+ }
+
+ // avoid jumping around in a circle #2
+ if (dy > 300) {
+ dy -= 360
+ } else if (dy < -300) {
+ dy += 360
+ }
+
+ destRotationX = MX.toRad(dx)
+ destRotationY += MX.toRad(dy)
+ },
+
+ landscapeorientation: function (e) {
+ var dx, dy
+
+ dx = e.gamma > 0 ? 90 - e.gamma : 90 + e.gamma
+ dy = e.alpha - lastAlpha
+ lastAlpha = e.alpha
- var timestamp = Date.now()
- var point = event.touches[0]
- deltaX = point.pageX - pointX
- deltaY = point.pageY - pointY
-
- pointX = point.pageX
- pointY = point.pageY
+ // avoid the sudden jump from 0 to -360
+ if (dy > 300) {
+ dy -= 360
+ }
+ else if (dy < -300) {
+ dy += 360
+ }
- distX += deltaX
- distY += deltaY
- absDistX = abs(distX)
- absDistY = abs(distY)
- }
- })
- document.addEventListener("touchend", function(e){
- e.preventDefault()
- if (e.touches.length == 0) {
- touching = directionLocked = false
- var timestamp = Date.now()
- var duration = startTime - timestamp
- if (duration < 300) {
- }
- }
- })
+ destRotationX = dx > 45 ? 0 : MX.toRad(dx)
+ destRotationY += MX.toRad(dy)
},
update: function () {
+ var drx, dry
+
+ dry = (destRotationY - rotationY) / 6
+ drx = (destRotationX - rotationX) / 6
+ rotationY += dry
+ rotationX += drx
+ cam.rotationY = pos.rotationY += dry
+ cam.rotationX = pos.rotationX += drx
+
if (distX || distY) {
var oldDistY = absDistY, oldDistX = absDistX
absDistY = avg(absDistY, 0, 5)
@@ -77,8 +190,7 @@ MX.MobileMovements = function (cam) {
pos.x -= dy * Math.cos(pos.rotationY + Math.PI / 2)
pos.z -= dy * Math.sin(pos.rotationY + Math.PI / 2)
- pos.rotationY += dx / (window.innerWidth) * Math.PI / 2
- cam.rotationY = pos.rotationY
+ cam.rotationY = pos.rotationY += dx / (window.innerWidth) * Math.PI / 2
app.tube("move", pos)
}
@@ -93,6 +205,7 @@ MX.MobileMovements = function (cam) {
jumpVelocity: function(n){ jumpV = clamp(n, 1, 50) },
}
+ return exports
}
diff --git a/public/assets/javascripts/mx/extensions/mx.orbitCamera.js b/public/assets/javascripts/mx/extensions/mx.orbitCamera.js
new file mode 100644
index 0000000..a936cef
--- /dev/null
+++ b/public/assets/javascripts/mx/extensions/mx.orbitCamera.js
@@ -0,0 +1,97 @@
+MX.OrbitCamera = function(opt){
+ var exports = {}, bound = false
+ exports.opt = opt = defaults(opt, {
+ el: window, // object to bind events on
+ camera: scene.camera, // camera object we'll be moving
+ radius: 100,
+ radiusRange: [ 10, 1000 ],
+ rotationX: PI/2,
+ rotationY: 0,
+ center: { x: 0, y: 0, z: 0 },
+ sensitivity: 10, // moving 1 pixel is like moving N radians
+ wheelSensitivity: 10,
+ ease: 10,
+ })
+ var rx, ry, radius, px, py, epsilon = 1e-10, dragging = false
+ exports.init = function(){
+ ry = opt.rotationY
+ rx = opt.rotationX
+ radius = opt.radius
+ exports.wheel = new wheel({
+ el: opt.el,
+ update: function(e, delta){
+ opt.radius = clamp( opt.radius + delta * opt.wheelSensitivity, opt.radiusRange[0], opt.radiusRange[1] )
+ },
+ })
+ exports.bind()
+ }
+ exports.toggle = function(state){
+ if (state) exports.bind()
+ else exports.unbind()
+ }
+ exports.bind = function(){
+ if (bound) return;
+ bound = true
+ opt.el.addEventListener("mousedown", down)
+ window.addEventListener("mousemove", move)
+ window.addEventListener("mouseup", up)
+ exports.wheel.unlock()
+ }
+ exports.unbind = function(){
+ if (! bound) return;
+ bound = false
+ opt.el.removeEventListener("mousedown", down)
+ window.removeEventListener("mousemove", move)
+ window.removeEventListener("mouseup", up)
+ exports.wheel.lock()
+ }
+ function down (e) {
+ px = e.pageX
+ py = e.pageY
+ dragging = true
+ }
+ function move (e) {
+ if (! dragging) return
+ exports.delta(px- e.pageX, py - e.pageY)
+ px = e.pageX
+ py = e.pageY
+ }
+ function up (e) {
+ dragging = false
+ }
+ exports.delta = function(x,y){
+ opt.rotationY += x/window.innerWidth * opt.sensitivity
+ opt.rotationX = clamp( opt.rotationX + y/window.innerHeight * opt.sensitivity, 0, PI)
+ }
+ exports.move = function(y, x){
+ opt.rotationY = y
+ if (typeof x == "number") { opt.rotationX = x }
+ }
+ exports.update = function(){
+ if (! bound) return
+ if (abs(ry - opt.rotationY) > epsilon) {
+ ry = avg(ry, opt.rotationY, opt.ease)
+ }
+ else {
+ ry = opt.rotationY
+ }
+ if (abs(rx - opt.rotationX) > epsilon) {
+ rx = avg(rx, opt.rotationX, opt.ease)
+ }
+ else {
+ rx = opt.rotationX
+ }
+ if (abs(radius - opt.radius) > epsilon) {
+ radius = avg(radius, opt.radius, opt.ease)
+ }
+ else {
+ radius = opt.radius
+ }
+ opt.camera.x = opt.center.x + radius * sin(rx) * cos(ry)
+ opt.camera.y = opt.center.y + radius * cos(rx)
+ opt.camera.z = opt.center.z + radius * sin(rx) * sin(ry)
+ opt.camera.rotationX = PI/2 - rx
+ opt.camera.rotationY = ry + PI/2
+ }
+ return exports
+}
diff --git a/public/assets/javascripts/mx/mx.js b/public/assets/javascripts/mx/mx.js
index 40a5f2e..60651eb 100644
--- a/public/assets/javascripts/mx/mx.js
+++ b/public/assets/javascripts/mx/mx.js
@@ -25,7 +25,7 @@ var MX = MX || (function (undefined) {
var MX = {
version: '0.1.0',
prefix: undefined,
- rotationUnit: 'rad'
+ rotationUnit: 'rad',
}
var floatPrecision = 5
@@ -162,24 +162,24 @@ var MX = MX || (function (undefined) {
Object.defineProperty(this, 'width', {
get: function () {
return width
- || parseInt(self.el.style.width, 10)
+ || parseInt(self.el.style.width, 10) * app_devicePixelRatio
|| 0
},
set: function (val) {
width = val
- this.el.style.width = width + 'px'
+ this.el.style.width = (width/app_devicePixelRatio) + 'px'
}
})
Object.defineProperty(this, 'height', {
get: function () {
return height
- || parseInt(self.el.style.height, 10)
+ || parseInt(self.el.style.height, 10) * app_devicePixelRatio
|| 0
},
set: function (val) {
height = val
- this.el.style.height = height + 'px'
+ this.el.style.height = (height/app_devicePixelRatio) + 'px'
}
})
}
@@ -302,9 +302,9 @@ var MX = MX || (function (undefined) {
+ (-this.y).toFixed(floatPrecision) + 'px,'
+ (-this.z).toFixed(floatPrecision) + 'px) '
+ 'scale3d('
- + this.scaleX.toFixed(floatPrecision) + ','
- + this.scaleY.toFixed(floatPrecision) + ','
- + this.scaleZ.toFixed(floatPrecision) + ') '
+ + (app_devicePixelRatio * this.scaleX).toFixed(floatPrecision) + ','
+ + (app_devicePixelRatio * this.scaleY).toFixed(floatPrecision) + ','
+ + (app_devicePixelRatio * this.scaleZ).toFixed(floatPrecision) + ') '
if (rotationTranslation) {
transformString += rotationTranslation.before
diff --git a/public/assets/javascripts/mx/primitives/mx.grid.js b/public/assets/javascripts/mx/primitives/mx.grid.js
new file mode 100644
index 0000000..a765c89
--- /dev/null
+++ b/public/assets/javascripts/mx/primitives/mx.grid.js
@@ -0,0 +1,70 @@
+MX.Grid = MX.Object3D.extend({
+ init: function (ops) {
+
+ this.type = "Grid"
+
+ var ops = this.ops = defaults(ops, {
+ x: 0,
+ y: 0,
+ z: 0,
+ space: 20,
+ cells: 20,
+ })
+
+ ops.side = ops.space * ops.cells
+
+ var ctx, canvas = document.createElement("canvas")
+
+ this.el = canvas
+ this.width = this.height = canvas.width = canvas.height = ops.side + 4
+
+ ctx = canvas.getContext('2d')
+
+ this.x = ops.x || 0
+ this.y = ops.y || 0
+ this.z = ops.z || 0
+ this.rotationX = PI/2
+ this.scale = ops.scale || 1
+ this.backface = ops.backface || false
+
+ ops.className && this.el.classList.add(ops.className)
+ this.backface && this.el.classList.add("backface-visible")
+ this.el.classList.add("mx-grid")
+
+ this.draw(ctx)
+ },
+
+ draw: function(ctx, recenter){
+ ctx = ctx || this.ctx
+
+ if (recenter) {
+ ctx.save()
+ ctx.translate( -grid.width/2, -grid.height/2 )
+ }
+
+ var cells = this.ops.cells,
+ space = this.ops.space,
+ side = this.ops.side
+
+ ctx.strokeStyle = "#444"
+ ctx.lineWidth = 1
+ ctx.beginPath()
+ ctx.translate(1,1)
+ for (var i = 0; i <= cells; i++) {
+ ctx.moveTo(i*space, 0)
+ ctx.lineTo(i*space, side)
+ ctx.moveTo(0, i*space)
+ ctx.lineTo(side, i*space)
+ }
+ ctx.closePath()
+ ctx.stroke()
+
+ if (recenter) {
+ ctx.restore()
+ }
+
+ },
+
+})
+
+
diff --git a/public/assets/javascripts/mx/primitives/mx.image.js b/public/assets/javascripts/mx/primitives/mx.image.js
index 575e9c0..ce99592 100644
--- a/public/assets/javascripts/mx/primitives/mx.image.js
+++ b/public/assets/javascripts/mx/primitives/mx.image.js
@@ -1,6 +1,7 @@
MX.Image = MX.Object3D.extend({
init: function (ops) {
-
+ ops = ops || {}
+
this.type = "Image"
this.media = ops.media
this.width = 0
@@ -12,13 +13,13 @@ MX.Image = MX.Object3D.extend({
this.backface = ops.backface || false
ops.className && this.el.classList.add(ops.className)
- this.backface && this.el.classList.add("backface-visible")
+ this.backface && this.el.classList.add("backface-visible")
this.el.classList.add("image")
this.el.classList.add("mx-scenery")
this.el.style.backgroundRepeat = 'no-repeat'
- this.load(ops)
+ ops.src && this.load(ops)
},
load: function(ops){
@@ -41,8 +42,41 @@ MX.Image = MX.Object3D.extend({
layer.el.classList.add('image')
layer.dirty = true
layer.update()
+ layer.ops.onload
+
+ if (ops.keepImage) {
+ layer.image = image
+ }
+ }
+
+ if (ops.src) {
+ image.src = ops.src
+ }
+ else if (ops.media) {
+ image.src = ops.media.url
+ }
+ else if (ops.url) {
+ image.src = ops.url
+ }
+ },
+
+ draw: function(ctx, recenter){
+ if (! this.image) { return }
+
+ if (recenter) {
+ ctx.save()
+ ctx.scale(-1, 1)
+ ctx.translate( -this.width/2 * this.scale, -this.height/2 * this.scale )
+ }
+
+ ctx.drawImage(this.image,
+ 0, 0, this.image.naturalWidth, this.image.naturalHeight,
+ 0, 0, this.image.width * this.scale * devicePixelRatio, this.image.height * this.scale * devicePixelRatio
+ )
+
+ if (recenter) {
+ ctx.restore()
}
- image.src = ops.src;
},
})
diff --git a/public/assets/javascripts/mx/primitives/mx.point.js b/public/assets/javascripts/mx/primitives/mx.point.js
new file mode 100644
index 0000000..41a7732
--- /dev/null
+++ b/public/assets/javascripts/mx/primitives/mx.point.js
@@ -0,0 +1,17 @@
+MX.Point = MX.Object3D.extend({
+ init: function(p){
+ this.updateChildren = false
+ this.move({
+ x: p.a,
+ y: 11,
+ z: p.b,
+ width: 20,
+ height: 20,
+ rotationX: PI/2,
+ })
+ this.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')'
+ this.el.style.backfaceVisibility = "visible"
+ this.el.style.borderRadius = "50%"
+ scene.add(this)
+ }
+})
diff --git a/public/assets/javascripts/mx/primitives/mx.polyline.js b/public/assets/javascripts/mx/primitives/mx.polyline.js
new file mode 100644
index 0000000..e549150
--- /dev/null
+++ b/public/assets/javascripts/mx/primitives/mx.polyline.js
@@ -0,0 +1,57 @@
+MX.Polyline = MX.Object3D.extend({
+ init: function(polyline){
+ this.faces = []
+ this.points = polyline.points
+ for (var i = 1; i < this.points.length; i++) {
+ var mx = new MX.Object3D()
+ var head = this.points[i-1]
+ var tail = this.points[i]
+ this.move_face(mx, head, tail)
+ this.faces.push(mx)
+ scene.add(mx)
+ }
+ },
+
+ rebuild: function(){
+ for (var i = 1; i < this.points.length; i++) {
+ var mx = this.faces[i-1]
+ var head = this.points[i-1]
+ var tail = this.points[i]
+ this.move_face(mx, head, tail)
+ }
+ },
+
+ move_face: function (mx, head, tail){
+ var mid_x = (head.a + tail.a)
+ var mid_z = (head.b + tail.b)
+ var len = head.distanceTo( tail )
+ var angle = atan2( head.b - tail.b, head.a - tail.a )
+ mx.move({
+ x: mid_x / 2,
+ y: wallHeight/2 + 1,
+ z: mid_z / 2,
+ width: ceil(len),
+ height: wallHeight,
+ rotationY: angle
+ })
+ // var hue = abs(round( angle / PI * 90 + 300))
+ // mx.el.style.backgroundColor = 'hsl(' + [hue, "100%", "50%"] + ')'
+ var lum = abs(round( angle / PI * 20 + 70))
+ mx.el.style.backgroundColor = 'hsla(' + ["0", "0%", lum + "%", "0.99"] + ')'
+ },
+
+ set_height: function(height){
+ for (var i = 0; i < this.faces.length; i++) {
+ this.faces[i].height = height
+ this.faces[i].y = height / 2 + 1
+ }
+ },
+
+ destroy: function(){
+ this.faces.forEach(function(mx){
+ scene.remove(mx)
+ })
+ this.faces = null
+ this.points = null
+ },
+})
diff --git a/public/assets/javascripts/mx/primitives/mx.soundcloud.js b/public/assets/javascripts/mx/primitives/mx.soundcloud.js
new file mode 100644
index 0000000..fecb2f4
--- /dev/null
+++ b/public/assets/javascripts/mx/primitives/mx.soundcloud.js
@@ -0,0 +1,130 @@
+MX.Soundcloud = MX.Object3D.extend({
+ init: function (ops) {
+
+ this.type = "Soundcloud"
+ this.media = ops.media
+ this.width = 0
+ this.height = 0
+ this.x = ops.x || 0
+ this.y = ops.y || 0
+ this.z = ops.z || 0
+ this.scale = ops.scale || 1
+ this.backface = ops.backface || false
+
+ ops.className && this.el.classList.add(ops.className)
+ this.backface && this.el.classList.add("backface-visible")
+ this.el.classList.add("audio")
+ this.el.classList.add("mx-scenery")
+
+ this.el.style.backgroundRepeat = 'no-repeat'
+ this.paused = true
+
+ this.ops = ops
+ },
+
+ load: function(ops){
+ if (ops) {
+ ops = this.ops = defaults(ops, this.ops)
+ }
+ else {
+ ops = this.ops
+ }
+
+ this.width = ops.media.width
+ this.height = ops.media.height
+
+ var tag = Parser.lookup.soundcloud.tag(ops.media)
+ var $iframe = $(tag)
+ var iframe = $iframe[0]
+ $iframe.css('z-index', '-1')
+ this.el.appendChild( iframe )
+
+ var overlay = this.overlay = document.createElement("div")
+ overlay.style.width = "100%"
+ overlay.style.height = "100%"
+ overlay.style.position = "absolute"
+ overlay.style.top = "0"
+ overlay.style.left = "0"
+ overlay.style.zIndex = "2"
+ overlay.className = "overlay"
+ this.el.appendChild(overlay)
+
+ this.player = SC.Widget( iframe )
+ this.player.setVolume(80)
+
+ this.duration = 0
+
+ this.player.bind(SC.Widget.Events.READY, this.ready.bind(this))
+// this.player.bind(SC.Widget.Events.LOAD_PROGRESS, this.loadProgress.bind(this))
+// this.player.bind(SC.Widget.Events.PLAY_PROGRESS, this.playProgress.bind(this))
+ this.player.bind(SC.Widget.Events.PLAY, this.didPlay.bind(this))
+ this.player.bind(SC.Widget.Events.PAUSE, this.didPause.bind(this))
+ this.player.bind(SC.Widget.Events.FINISH, this.finished.bind(this))
+ },
+
+ ready: function(){
+ this.seek( this.media.keyframe || 0 )
+
+ if (this.media.autoplay) {
+ this.play()
+ }
+
+ this.player.getDuration(function(duration){
+ this.duration = duration
+ }.bind(this))
+ },
+
+ play: function(){
+ this.player.play()
+ },
+
+ pause: function(){
+ this.player.pause()
+ },
+
+ toggle: function(state){
+ if (typeof state === "boolean") {
+ if (state) this.play()
+ else this.pause()
+ }
+ else {
+ this.player.toggle()
+ }
+ },
+
+ seek: function(n){
+ if (n < 1) {
+ n = n * this.duration
+ }
+ this.player.seekTo(n)
+ },
+
+ setLoop: function(state){
+ this.media.loop = state
+ },
+
+ setVolume: function(n){
+ if (this.muted || ! this.player) return
+ this.player.setVolume(floor( n * 100 ))
+ },
+
+ didPlay: function(){
+ this.paused = false
+ },
+
+ didPause: function(){
+ this.paused = true
+ },
+
+ finished: function(){
+ console.log("soundcloud finished")
+ if (this.media.loop) {
+ this.seek(0)
+ this.play()
+ }
+ else if (this.bound) {
+ $(".playButton").removeClass('playing')
+ }
+ },
+
+})
diff --git a/public/assets/javascripts/mx/primitives/mx.text.js b/public/assets/javascripts/mx/primitives/mx.text.js
index 9c7af5c..3095b67 100644
--- a/public/assets/javascripts/mx/primitives/mx.text.js
+++ b/public/assets/javascripts/mx/primitives/mx.text.js
@@ -3,34 +3,57 @@ MX.Text = MX.Object3D.extend({
init: function (ops) {
this.type = "Text"
-
- var layer = new MX.Object3D('text')
- layer.width = ops.width || 100
- layer.height = ops.height || 50
- layer.x = ops.x || 0
- layer.y = ops.y || 0
- layer.z = ops.z || 0
- layer.scale = ops.scale || 1
- layer.el.innerHTML = ops.value || ""
- if (ops.id) layer.el.id = ops.id;
- if (ops.background) layer.el.style.background = ops.background;
- if (ops.color) layer.el.style.color = ops.color;
- if (ops.fontSize) layer.el.style.fontSize = ops.fontSize + "px";
- this.add(layer)
+ this.type = "Image"
+ this.media = ops.media
+ this.width = 0
+ this.height = 0
+ this.x = ops.x || 0
+ this.y = ops.y || 0
+ this.z = ops.z || 0
+ this.scale = ops.scale || 1
+ this.backface = ops.backface || false
+
+ this.scale = ops.scale || 1
+ this.width = ops.media.width
+ this.height = ops.media.height
+ this.x = ops.x || 0
+ this.y = ops.y || 0
+ this.z = ops.z || 0
+ this.rotationX = ops.rotationX || 0
+ this.rotationY = ops.rotationY || 0
+ this.rotationZ = ops.rotationZ || 0
+
+ ops.className && this.el.classList.add(ops.className)
+ this.backface && this.el.classList.add("backface-visible")
+ this.el.classList.add("mx-text")
+ this.el.classList.add("mx-scenery")
+
+ this.inner = document.createElement("div")
+ this.inner.classList.add("inner")
+ this.el.appendChild(this.inner)
+
+ this.load(ops)
+ },
+
+ load: function(ops){
+ var media = ops.media
+ if (media.font) this.setFont(media.font)
- this.children.forEach(function (c, i) {
- if (ops.classname) {
- c.el.classList.add(ops.classname)
- }
- else {
- }
- c.el.style.backgroundRepeat = 'no-repeat'
- })
+ this.setText( media.description )
+ },
+
+ setFont: function(font){
+ if (! font.color || font.color[0] == "#") { font.color = [0,0,0] }
- this.dirty = true
- this.updateChildren = true
- this.update()
- }
+ this.inner.style.fontFamily = "'" + font.family + "',sans-serif"
+ this.el.style.fontSize = (font.size / devicePixelRatio) + "pt"
+ this.el.style.textAlign = font.align
+ this.el.style.color = rgb_string(font.color)
+ },
+
+ setText: function(text){
+ this.inner.innerHTML = marked( text || "" )
+ },
})
diff --git a/public/assets/javascripts/mx/primitives/mx.video.js b/public/assets/javascripts/mx/primitives/mx.video.js
index 12d3dcb..53ccf2e 100644
--- a/public/assets/javascripts/mx/primitives/mx.video.js
+++ b/public/assets/javascripts/mx/primitives/mx.video.js
@@ -21,6 +21,7 @@ MX.Video = MX.Object3D.extend({
this.el.classList.add("video")
this.el.classList.add("mx-scenery")
this.paused = !! this.media.autoplay
+ this.playing = false
this.muted = app.muted || !! this.media.mute
},
@@ -31,8 +32,8 @@ MX.Video = MX.Object3D.extend({
this.player.addEventListener("loadedmetadata", this.ready.bind(this))
this.player.addEventListener("error", this.error.bind(this))
this.player.addEventListener("ended", this.finished.bind(this))
- this.player.width = this.width
- this.player.height = this.height
+ this.player.width = "100%"
+ this.player.height = "100%"
this.player.src = this.media.url
this.player.load()
@@ -45,6 +46,9 @@ MX.Video = MX.Object3D.extend({
if (this.media.mute) {
this.mute()
}
+ else {
+ this.unmute()
+ }
if (this.media.autoplay) {
this.play()
@@ -57,11 +61,13 @@ MX.Video = MX.Object3D.extend({
play: function(){
this.paused = false
+ this.playing = true
this.player.play()
},
pause: function(){
this.paused = true
+ this.playing = false
this.player.pause()
},
@@ -74,14 +80,21 @@ MX.Video = MX.Object3D.extend({
mute: function(){
this.player.muted = true
+ this.player.volume = 0
this.muted = true
},
unmute: function(){
this.player.muted = false
+ this.player.volume = 0.8
this.muted = false
},
+ setVolume: function(n){
+ if (this.muted || ! this.player) return
+ this.player.volume = n
+ },
+
setLoop: function(state){
this.media.loop = state
},
diff --git a/public/assets/javascripts/mx/primitives/mx.vimeo.js b/public/assets/javascripts/mx/primitives/mx.vimeo.js
index 4922519..af138ae 100644
--- a/public/assets/javascripts/mx/primitives/mx.vimeo.js
+++ b/public/assets/javascripts/mx/primitives/mx.vimeo.js
@@ -20,6 +20,7 @@ MX.Vimeo = MX.Object3D.extend({
this.backface && this.el.classList.add("backface-visible")
this.el.classList.add("video")
this.el.classList.add("mx-scenery")
+ this.playing = false
this.paused = !! this.media.autoplay
this.muted = app.muted || !! this.media.mute
this.started = false
@@ -32,8 +33,8 @@ MX.Vimeo = MX.Object3D.extend({
preload.id = uid
preload.setAttribute("src", "//player.vimeo.com/video/" + this.media.token + "?api=1&badge=0&controls=0branding=0&byline=0&portrait=0&title=0&" + loop + "&player_id=" + uid)
preload.style.backgroundImage = "url(" + this.media.thumbnail + ")"
- preload.style.width = this.media.width + "px"
- preload.style.height = this.media.height + "px"
+ preload.style.width = "100%"
+ preload.style.height = "100%"
preload.style.border = "0"
preload.style.pointerEvents = "none"
preload.className = "preload"
@@ -62,6 +63,9 @@ MX.Vimeo = MX.Object3D.extend({
if (this.media.mute) {
this.mute()
}
+ else {
+ this.unmute()
+ }
this.seek( this.media.keyframe || 0 )
@@ -96,7 +100,7 @@ MX.Vimeo = MX.Object3D.extend({
return
}
- if (! this.started || n === 0) {
+ if (! this.started) {
return
}
@@ -127,6 +131,11 @@ MX.Vimeo = MX.Object3D.extend({
this.player.api('setVolume', 0.8)
this.muted = false
},
+
+ setVolume: function(n){
+ if (this.muted || ! this.player) return
+ this.player.api('setVolume', n)
+ },
setLoop: function(state){
this.media.loop = state
@@ -137,19 +146,26 @@ MX.Vimeo = MX.Object3D.extend({
if (this.paused) {
this.pause()
}
+ else {
+ this.playing = true
+ }
},
onPause: function(){
if (! this.paused) {
this.play()
}
+ else {
+ this.playing = false
+ }
},
finished: function(){
-// if (this.media.loop) {
-// this.seek(0)
-// this.play()
-// }
+ console.log("vimeo finished")
+ if (this.media.loop) {
+ this.seek(0)
+ this.play()
+ }
// else if (this.bound) {
if (! this.media.loop && this.bound) {
$(".playButton").removeClass('playing')
diff --git a/public/assets/javascripts/mx/primitives/mx.youtube.js b/public/assets/javascripts/mx/primitives/mx.youtube.js
index 873348f..8cd9f59 100644
--- a/public/assets/javascripts/mx/primitives/mx.youtube.js
+++ b/public/assets/javascripts/mx/primitives/mx.youtube.js
@@ -21,6 +21,7 @@ MX.Youtube = MX.Object3D.extend({
this.el.classList.add("video")
this.el.classList.add("mx-scenery")
this.paused = !! this.media.autoplay
+ this.playing = false
this.muted = app.muted || !! this.media.mute
},
@@ -31,12 +32,25 @@ MX.Youtube = MX.Object3D.extend({
preload.id = uid
preload.style.backgroundImage = "url(" + this.media.thumbnail + ")"
preload.style.backgroundSize = "cover"
- preload.style.width = this.media.width + "px"
- preload.style.height = this.media.height + "px"
+ preload.style.width = "100%"
+ preload.style.height = "100%"
preload.style.pointerEvents = "none"
+ preload.style.position = "absolute"
+ preload.style.top = "0"
+ preload.style.left = "0"
+ preload.style.zIndex = "1"
preload.className = "preload"
this.el.appendChild(preload)
+ var overlay = this.overlay = document.createElement("div")
+ overlay.style.width = "100%"
+ overlay.style.height = "100%"
+ overlay.style.position = "absolute"
+ overlay.style.top = "0"
+ overlay.style.left = "0"
+ overlay.style.zIndex = "2"
+ overlay.className = "overlay"
+ this.el.appendChild(overlay)
this.defer(uid)
},
@@ -96,6 +110,9 @@ MX.Youtube = MX.Object3D.extend({
if (this.media.mute) {
this.mute()
}
+ else {
+ this.unmute()
+ }
this.seek( this.media.keyframe || 0 )
},
@@ -127,11 +144,13 @@ MX.Youtube = MX.Object3D.extend({
play: function(){
this.paused = false
+ this.playing = true
this.player.playVideo()
},
pause: function(){
this.paused = true
+ this.playing = false
this.player.pauseVideo()
},
@@ -157,6 +176,11 @@ MX.Youtube = MX.Object3D.extend({
this.player.setVolume(80)
this.muted = false
},
+
+ setVolume: function(n){
+ if (this.muted || ! this.player || ! this.player.setVolume) return
+ this.player.setVolume( floor(n * 100) )
+ },
setLoop: function(state){
this.media.loop = state
diff --git a/public/assets/javascripts/rectangles/_env.js b/public/assets/javascripts/rectangles/_env.js
index 4b14a21..b3c7d66 100644
--- a/public/assets/javascripts/rectangles/_env.js
+++ b/public/assets/javascripts/rectangles/_env.js
@@ -1,6 +1,22 @@
var environment = new function(){}
environment.init = function(){
+ scene = new MX.Scene().addTo('#scene')
+ scene.width = window.innerWidth
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ cam = scene.camera
+ cam.y = viewHeight
+
+ if (is_mobile) {
+ app.movements = new MX.MobileMovements(cam, viewHeight)
+ }
+ else {
+ app.movements = new MX.Movements(cam, viewHeight)
+ }
+ app.movements.init()
+
map = new Map ()
if (window.scene) {
@@ -10,21 +26,30 @@ environment.init = function(){
"z": 0,
"rotationX": 0, // PI/2,
"rotationY": PI/2, // PI
-// "rotationX": 0,
-// "rotationY": PI
+ // "rotationX": 0,
+ // "rotationY": PI
})
scene.camera.radius = 20
}
-
- app.movements.gravity(true)
-
+
+ window.onresize = function () {
+ scene.width = window.innerWidth
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+ scene.update()
+ }
+
Rooms.init()
+ Walls.init()
Scenery.init()
+ Sculpture.init()
scene.update()
environment.update()
+ app.movements.gravity(true)
+
var minimap_el = document.querySelector("#minimap .el")
if (minimap_el) {
window.minimap = new Map ({
@@ -50,8 +75,13 @@ environment.init = function(){
}
})
}
-environment.update = function(t){
+environment.minimal = function(){
+ environment.update = function(t){}
+}
+environment.update = function(t, dt){
+ app.movements.update(dt || 0)
+ scene.update()
map.update()
- window.minimap && window.minimap.update && minimap.update()
+ window.minimap && minimap.update && minimap.update()
z = false
}
diff --git a/public/assets/javascripts/rectangles/engine/map/_map.js b/public/assets/javascripts/rectangles/engine/map/_map.js
index 99ede82..ba3ec92 100644
--- a/public/assets/javascripts/rectangles/engine/map/_map.js
+++ b/public/assets/javascripts/rectangles/engine/map/_map.js
@@ -15,6 +15,8 @@ var Map = function(opt){
var base = this
base.el = opt.el
+ base.$el = $(base.el)
+ base.opt = opt
if (! base.el) return
@@ -32,7 +34,6 @@ var Map = function(opt){
scene.camera.x + sides.a, scene.camera.z + sides.b )
}
-
base.set_zoom = function (n) {
n = clamp(n, opt.zoom_min, opt.zoom_max)
base.zoom_exponent = n
@@ -40,15 +41,40 @@ var Map = function(opt){
}
base.set_zoom(opt.zoom)
+ base.resize = function(w, h){
+ if (w && h) {
+ canvas.width = base.dimensions.a = w
+ canvas.height = base.dimensions.b = h
+ }
+ else {
+ // resize here - esp if 2d-hires
+ canvas.width = base.dimensions.a = base.el.parentNode.offsetWidth
+ canvas.height = base.dimensions.b = base.el.parentNode.offsetHeight
+ }
+ }
+
+ base.toggle = function(state){
+ return $(base.el).toggle(state).is(':visible')
+ }
+
var canvas = base.canvas = document.createElement("canvas")
canvas.width = base.dimensions.a
canvas.height = base.dimensions.b
-
+
base.el.appendChild(canvas)
-
+
switch (opt.type) {
+ case "ortho":
+ base.draw = new Map.Draw (base, { ortho: true })
+ base.draw.grid_size = MAP_GRID_SIZE
+ base.ui = new Map.UI.Ortho (base)
+ base.sides = base.sides_for_center
+ $(window).resize(base.resize)
+ break
+
case "editor":
base.draw = new Map.Draw (base)
+ base.draw.grid_size = MAP_GRID_SIZE
base.ui = new Map.UI.Editor (base)
base.sides = base.sides_for_center
$(window).resize(base.resize)
@@ -56,20 +82,11 @@ var Map = function(opt){
case "minimap":
base.draw = new Map.Draw (base, { center: scene.camera, minimap: true })
+ base.draw.grid_size = MAP_GRID_SIZE * 10
base.ui = new Map.UI.Minimap (base)
base.sides = base.sides_for_camera
break
}
-
- base.resize = function(){
- canvas.width = base.dimensions.a = window.innerWidth
- canvas.height = base.dimensions.b = window.innerHeight
- }
-
- base.toggle = function(){
- $(base.el).toggle()
- }
-
}
Map.prototype.update = function(){
diff --git a/public/assets/javascripts/rectangles/engine/map/draw.js b/public/assets/javascripts/rectangles/engine/map/draw.js
index 3e185d2..4f4759f 100644
--- a/public/assets/javascripts/rectangles/engine/map/draw.js
+++ b/public/assets/javascripts/rectangles/engine/map/draw.js
@@ -5,79 +5,129 @@ Map.Draw = function(map, opt){
var draw = this
- var ctx = map.canvas.getContext("2d")
+ var ctx = draw.ctx = map.canvas.getContext("2d")
draw.animate = function(){
ctx.save()
draw.clear()
- // draw.ruler()
+ draw.fill("rgba(255,255,255,0.98)")
- if (opt.minimap) {
+ if (opt.ortho) {
+ }
+ else if (opt.minimap) {
ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2)
ctx.scale( map.zoom, map.zoom )
+ if (map.opt.pivot) { ctx.rotate(scene.camera.rotationY + PI) }
ctx.translate( opt.center.x, - opt.center.z )
ctx.scale( -1, 1 )
draw.coords()
- draw.regions(Rooms.regions, [ "#fff" ])
+ if (Rooms.shapesMode) {
+ shapes.draw(draw.ctx, "#fff", null)
+ shapes.draw(draw.ctx, null, "#000")
+ }
+ else {
+ draw.regions(Rooms.regions, [ "#fff" ], "#000")
+ }
draw.camera(scene.camera)
}
-
else {
ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2)
ctx.scale( map.zoom, map.zoom )
ctx.translate( map.center.a, map.center.b )
ctx.scale( -1, 1 )
- draw.regions(Rooms.regions, [ "#f8f8f8" ])
+ draw.regions(Rooms.regions, [ "#f8f8f8" ], "#000")
draw.mouse(map.ui.mouse.cursor)
+ draw.mouse_dimensions(map.ui.mouse.cursor)
draw.coords()
scene && draw.camera(scene.camera)
}
ctx.restore()
}
+ draw.translate = function(){
+ ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2)
+ ctx.scale( map.zoom, map.zoom )
+ ctx.translate( map.center.a, map.center.b )
+ ctx.scale( -1, 1 )
+ }
+ // changes the ctx temporarily
draw.render = function(){
- ctx.save()
+ var thumbnail_width = 1000
+ var thumbnail_height = 750
+
+ var extent = Rooms.extent()
+ var center = extent.center()
+ var extent_width = extent.width()
+ var extent_height = extent.height()
+ var zoom
+ if (extent_width > extent_height) {
+ zoom = thumbnail_width / extent.width() * 0.9
+ }
+ else {
+ zoom = thumbnail_height / extent.height() * 0.9
+ }
+
+ var canvas = document.createElement("canvas")
+ canvas.width = thumbnail_width
+ canvas.height = thumbnail_height
+ ctx = canvas.getContext('2d')
+
draw.clear()
- ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2)
- ctx.scale( map.zoom, map.zoom )
- ctx.translate( map.center.a, map.center.b )
+ ctx.translate( thumbnail_width * 1/2, thumbnail_height * 1/2)
+ ctx.scale( zoom, zoom )
+ ctx.translate( center.a, -center.b )
ctx.scale( -1, 1 )
- draw.regions(Rooms.regions, ["#fff"])
- draw.mouse(map.ui.mouse.cursor)
- scene && draw.camera(scene.camera)
-
+ draw.regions(Rooms.regions, ["#fff"], null)
+
ctx.restore()
+
+ // invert opacity
+ var pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height)
+ var pixels = pixelData.data
+ for (var i = 0, k, _len = pixels.length; i < _len; i++) {
+ k = i*4
+ if (pixels[k+3] == 0) {
+ pixels[k] = pixels[k+1] = pixels[k+2] = pixels[k+3] = 255
+ }
+ else {
+ pixels[k] = pixels[k+1] = pixels[k+2] = 255
+ pixels[k+3] = 0
+ }
+ }
+ ctx.putImageData(pixelData, 0, 0)
+
+ // reset the ctx
+ ctx = draw.ctx
+
+ return canvas
}
draw.clear = function(){
- ctx.fillStyle = "rgba(255,255,255,0.98)"
ctx.clearRect(0, 0, map.dimensions.a, map.dimensions.b)
- ctx.fillRect(0, 0, map.dimensions.a, map.dimensions.b)
}
- draw.ruler = function (){
- ctx.strokeStyle = "rgba(80,80,80,0.5)"
- ctx.lineWidth = 1
- var len = 5
- for (var i = 0.5; i < map.dimensions.a; i += 10) {
- line(i, 0, i, len)
- line(0, i, len, i)
- }
+ draw.fill = function(fillStyle){
+ ctx.fillStyle = fillStyle
+ ctx.fillRect(0, 0, map.dimensions.a, map.dimensions.b)
}
- draw.regions = function(regions, colors){
+ draw.regions = function(regions, colors, stroke){
+ if (stroke) {
+ ctx.strokeStyle = "#000"
+ ctx.lineWidth = (1 / map.zoom)
+ }
for (var i = 0; i < regions.length; i++) {
if (regions[i].dupe) continue
ctx.fillStyle = colors[i % colors.length]
- ctx.strokeStyle = "#000"
- ctx.lineWidth = (1 / map.zoom)
fill_region(regions[i])
- stroke_sides(regions[i])
+ if (stroke) {
+ stroke_sides(regions[i])
+ }
}
}
@@ -88,7 +138,8 @@ Map.Draw = function(map, opt){
ctx.beginPath();
ctx.arc(mouse.x.b, mouse.y.b, radius, 0, 2*Math.PI, false);
ctx.fill();
-
+ }
+ draw.mouse_dimensions = function(mouse){
if (mouse.width() != 0 && mouse.height() != 0) {
if (map.ui.dragging) {
stroke_rect(mouse)
@@ -124,36 +175,39 @@ Map.Draw = function(map, opt){
}
draw.coords = function(){
- /*
- ctx.fillStyle = "#888";
- dot_at(0,0)
- ctx.fillStyle = "#bbb";
- dot_at(100,0)
- dot_at(0,100)
- ctx.fillStyle = "#ddd";
- dot_at(200,0)
- dot_at(0,200)
- ctx.fillStyle = "#eee";
- dot_at(300,0)
- dot_at(0,300)
- */
-
ctx.strokeStyle = "rgba(0,0,0,0.1)"
ctx.lineWidth = 1/map.zoom
var sides = map.sides()
- var quant = sides.clone().quantize(200)
- for (var x = quant.x.a - 200; x <= quant.x.b; x += 200) {
- line(x, sides.y.a, x, sides.y.b)
- }
- for (var y = quant.y.a - 200; y <= quant.y.b; y += 200) {
- line(sides.x.a, y, sides.x.b, y)
+ var quant = sides.clone().quantize(draw.grid_size)
+ for (var x = quant.x.a - draw.grid_size; x <= quant.x.b; x += draw.grid_size) {
+ if (Math.round(x) % 360 == 0) {
+ ctx.strokeStyle = "rgba(0,0,0,0.3)"
+ ctx.lineWidth = 1/map.zoom
+ }
+ else {
+ ctx.strokeStyle = "rgba(0,0,0,0.05)"
+ ctx.lineWidth = 1/map.zoom
+ }
+ line(x, sides.y.a, x, sides.y.b)
}
+
+ for (var y = quant.y.a - draw.grid_size; y <= quant.y.b; y += draw.grid_size) {
+ if (Math.round(y) % 360 == 0) {
+ ctx.strokeStyle = "rgba(0,0,0,0.3)"
+ ctx.lineWidth = 1/map.zoom
+ }
+ else {
+ ctx.strokeStyle = "rgba(0,0,0,0.05)"
+ ctx.lineWidth = 1/map.zoom
+ }
+ line(sides.x.a, y, sides.x.b, y)
+ }
}
//
- function line (x,y,a,b,translation){
+ var line = draw.line = function (x,y,a,b,translation){
if (translation) {
x += translation.a
a += translation.a
@@ -184,11 +238,11 @@ Map.Draw = function(map, opt){
line(r.x.a, r.y.a, r.x.b, r.y.b, r.translation)
}
- function dot_at (x,z){
+ draw.dot_at = function dot_at (x, z, radius){
ctx.save()
ctx.translate(x,z)
- var radius = 2 / map.zoom
+ radius = (radius || 2) / map.zoom
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2*Math.PI, false);
@@ -196,4 +250,29 @@ Map.Draw = function(map, opt){
ctx.restore()
}
+
+ draw.x_at = function x_at (x, z, length){
+ ctx.save()
+ if (x && 'x' in x) {
+ length = z
+ ctx.translate(x.x,x.z)
+ }
+ else {
+ ctx.translate(x,z)
+ }
+
+ var len = (length/2 || 4) / map.zoom
+
+ ctx.lineCap = "square"
+ ctx.lineWidth = 2/map.zoom
+ ctx.beginPath()
+ ctx.moveTo( -len, -len);
+ ctx.lineTo( len, len);
+ ctx.moveTo( -len, len);
+ ctx.lineTo( len, -len);
+ ctx.stroke();
+
+ ctx.restore()
+ }
+
} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/_base.js b/public/assets/javascripts/rectangles/engine/map/tools/_base.js
new file mode 100644
index 0000000..17b247d
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/_base.js
@@ -0,0 +1,11 @@
+var MapTool = Fiber.extend(function(base){
+ var exports = {
+ recenterCursor: true,
+ down: function(e, cursor){},
+ move: function(e, cursor){},
+ drag: function(e, cursor){},
+ up: function(e, cursor, new_cursor){},
+ cancel: function(){},
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/arrow.js b/public/assets/javascripts/rectangles/engine/map/tools/arrow.js
new file mode 100644
index 0000000..0b0557e
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/arrow.js
@@ -0,0 +1,83 @@
+// Tool used to move corners of polylines
+
+var ArrowTool = MapTool.extend(function(base){
+ var exports = {}
+
+ var selected_point = null, selected_segment = null, original_point = null, selected_shape = null
+ var src_points, dest_points
+
+ exports.down = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var p = shapes.findClosestPoint(last_point)
+ if (p && p.shape.type() !== "ortho") {
+ selected_shape = p.shape
+ selected_point = p.point
+ original_point = selected_point.clone()
+ return
+ }
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ document.body.style.cursor = "pointer"
+
+ selected_segment = segment
+ console.log(segment.head, segment.tail)
+ selected_shape = segment.shape
+ src_points = segment.shape.cloneSegment( segment )
+ dest_points = segment.shape.getSegment( segment )
+
+ last_point.a = segment.x
+ last_point.b = segment.y
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ map.ui.set_drag_tool("position")
+ }
+ }
+
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var p = shapes.findClosestPoint(last_point)
+ if (p) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(p.point)
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ return
+ }
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ document.body.style.cursor = "pointer"
+ last_point.a = segment.x
+ last_point.b = segment.y
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+
+ exports.drag = function(e, cursor){
+ if (selected_point) {
+ selected_point.a = original_point.a + cursor.x.magnitude()
+ selected_point.b = original_point.b + cursor.y.magnitude()
+ selected_shape.rebuild()
+ }
+ else if (selected_segment) {
+ selected_shape.translateSegment(
+ src_points, dest_points,
+ cursor.x.magnitude(), cursor.y.magnitude()
+ )
+ selected_shape.rebuild()
+ }
+ }
+
+ exports.up = function(e, cursor){
+ selected_point = selected_shape = selected_segment = original_point = null
+ }
+
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/eraser.js b/public/assets/javascripts/rectangles/engine/map/tools/eraser.js
new file mode 100644
index 0000000..8fc3687
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/eraser.js
@@ -0,0 +1,29 @@
+// Tool used to delete lines
+
+var EraserTool = MapTool.extend(function(base){
+ var exports = {}
+ exports.down = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ shapes.removeSegment(segment)
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ document.body.style.cursor = "pointer"
+ last_point.a = segment.x
+ last_point.b = segment.y
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ return exports
+})
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/line.js b/public/assets/javascripts/rectangles/engine/map/tools/line.js
new file mode 100644
index 0000000..8175d66
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/line.js
@@ -0,0 +1,63 @@
+// Tool is used to define a very simple line between two points.
+// It is used by the BlueprintScaler to specify a sample distance to scale.
+
+var LineTool = MapTool.extend(function(base){
+ var exports = {}
+
+ var selected_point = null
+
+ var line = exports.line = []
+
+ var can_drag, dragging
+
+ exports.down = function(e, cursor){
+
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ cursor.quantize(1/map.zoom)
+ app.router.blueprintView.map.center.a = cursor.x.a
+ app.router.blueprintView.map.center.b = -cursor.y.a
+ cursor.x.b = cursor.x.a
+ cursor.y.b = cursor.y.a
+ return
+ }
+
+ this.cursor = cursor
+ switch (line.length) {
+ case 0:
+ line[0] = cursor.x_component()
+ can_drag = true
+ break
+ case 1:
+ line[1] = cursor.x_component()
+ can_drag = false
+ break
+ case 2:
+ line[0] = cursor.x_component()
+ line.pop()
+ can_drag = true
+ break
+ }
+ }
+
+ exports.move = function(e, cursor){
+ this.cursor = cursor
+ }
+
+ exports.drag = function(e, cursor){
+ if (dragging) {
+ line[1].a = cursor.x.b
+ line[1].b = cursor.y.b
+ }
+ else if (can_drag && cursor.magnitude() > 10/map.zoom) {
+ line[1] = cursor.y_component()
+ dragging = true
+ }
+ }
+
+ exports.up = function(e, cursor){
+ can_drag = dragging = false
+ }
+
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/ortho.js b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js
new file mode 100644
index 0000000..374c822
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js
@@ -0,0 +1,118 @@
+// Tool to make a polyline where all walls are orthogonal
+
+var OrthoPolylineTool = MapTool.extend(function (base) {
+
+ var prev_point, horizontal = false, first_edge_is_horizontal = false
+
+ var exports = {}
+ exports.down = function(e, cursor){
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ e.preventDefault()
+ e.stopPropagation()
+ if (map.ui.placing) {
+ // close polyline or cancel
+ map.ui.placing = false
+ if (shapes.workline.points.length > 2) {
+ shapes.workline.build()
+ shapes.add(shapes.workline)
+ }
+ else {
+ shapes.workline.reset()
+ }
+ return
+ }
+ else {
+ map.ui.tools.position.rightclick(e, cursor)
+ }
+ return
+ }
+
+ // compare to initial point
+ var p = last_point.clone()
+ if (map.ui.placing) {
+ if (shapes.workline.lastPoint().eq(p)) {
+ return
+ }
+ else if (shapes.workline.canCloseWith(p)) {
+ shapes.workline.close()
+ shapes.workline.build()
+ shapes.add(shapes.workline)
+ map.ui.placing = false
+ }
+ else {
+ shapes.workline.add(p)
+ prev_point = p
+ horizontal = ! horizontal
+ }
+ }
+ else {
+ map.ui.placing = true
+ shapes.workline = new OrthoPolyline ()
+ shapes.workline.add(p)
+ first_point = prev_point = p
+ horizontal = false
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ if (map.ui.placing) {
+ if (shapes.workline.points.length == 1) {
+ var x = abs(prev_point.a - last_point.a)
+ var y = abs(prev_point.b - last_point.b)
+ if (x > y) {
+ last_point.b = prev_point.b
+ first_edge_is_horizontal = horizontal = true
+ }
+ else {
+ last_point.a = prev_point.a
+ first_edge_is_horizontal = horizontal = false
+ }
+ }
+ else {
+ if (horizontal) {
+ last_point.b = prev_point.b
+ }
+ else {
+ last_point.a = prev_point.a
+ }
+ if (horizontal == first_edge_is_horizontal) {
+ // check if this point is within N pixels of the normal
+ // and lock it into place if so
+ if (horizontal && abs( first_point.a - last_point.a ) < 10/map.zoom) {
+ last_point.a = first_point.a
+ }
+ else if (! horizontal && abs( first_point.b - last_point.b ) < 10/map.zoom) {
+ last_point.b = first_point.b
+ }
+ }
+ }
+
+ if (shapes.workline.canCloseWith(last_point)) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(first_point)
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ return
+ }
+ var end_point = shapes.findClosestEndPoint(last_point)
+ if (end_point) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(end_point.point)
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ return
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ exports.cancel = function(){
+ if (map.ui.placing) { shapes.workline.reset() }
+ first_point = null
+ map.ui.placing = false
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/polyline.js b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js
new file mode 100644
index 0000000..445ae26
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js
@@ -0,0 +1,73 @@
+// Tool used to draw polylines with arbitrary angles
+
+var PolylineTool = MapTool.extend(function (base) {
+ var exports = {}
+ exports.down = function(e, cursor){
+
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ e.preventDefault()
+ e.stopPropagation()
+ if (map.ui.placing) {
+ // close polyline or cancel
+ map.ui.placing = false
+ if (shapes.workline.points.length > 2) {
+ shapes.workline.build()
+ shapes.add(shapes.workline)
+ }
+ else {
+ shapes.workline.reset()
+ }
+ return
+ }
+ map.ui.tools.position.rightclick(e, cursor)
+ return
+ }
+
+ // compare to initial point
+ var p = last_point.clone()
+ if (map.ui.placing) {
+ if (shapes.workline.canCloseWith(p)) {
+ shapes.workline.close()
+ shapes.workline.build()
+ shapes.add(shapes.workline)
+ map.ui.placing = false
+ }
+ else {
+ shapes.workline.add(p)
+ }
+ }
+ else {
+ map.ui.placing = true
+ shapes.workline = new Polyline ()
+ shapes.workline.add(p)
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ if (map.ui.placing && shapes.workline.canCloseWith(last_point)) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(shapes.workline.points[0])
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ return
+ }
+ var end_point = shapes.findClosestEndPoint(last_point)
+ if (end_point) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(end_point.point)
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ return
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ exports.cancel = function(){
+ if (map.ui.placing) { shapes.workline.reset() }
+ map.ui.placing = false
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/position.js b/public/assets/javascripts/rectangles/engine/map/tools/position.js
new file mode 100644
index 0000000..f8365bc
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/position.js
@@ -0,0 +1,19 @@
+// Tool used to set position on the map and let you change the view by dragging.
+
+var PositionTool = MapTool.extend(function(base){
+ var exports = {
+ recenterCursor: false,
+ drag: function(e, cursor){
+ map.center.a = -cursor.x.magnitude()
+ map.center.b = cursor.y.magnitude()
+ },
+ rightclick: function(e, cursor){
+ cursor.quantize(1/map.zoom)
+ map.center.a = cursor.x.a
+ map.center.b = -cursor.y.a
+ cursor.x.b = cursor.x.a
+ cursor.y.b = cursor.y.a
+ }
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/start.js b/public/assets/javascripts/rectangles/engine/map/tools/start.js
new file mode 100644
index 0000000..203a85f
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/start.js
@@ -0,0 +1,29 @@
+// Tool is used to set the start position on the map.
+
+var StartPositionTool = MapTool.extend(function(base){
+ var exports = {}
+
+ var selected_point = null
+
+ var line = exports.line = []
+
+ var can_drag, dragging
+
+ exports.down = function(e, cursor){
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ cursor.quantize(1/map.zoom)
+ app.router.blueprintView.map.center.a = cursor.x.a
+ app.router.blueprintView.map.center.b = -cursor.y.a
+ cursor.x.b = cursor.x.a
+ cursor.y.b = cursor.y.a
+ return
+ }
+
+ cam.x = app.controller.startPosition.x = cursor.x.a
+ cam.z = app.controller.startPosition.z = cursor.y.a
+ }
+
+ return exports
+
+})
diff --git a/public/assets/javascripts/rectangles/engine/map/ui_editor.js b/public/assets/javascripts/rectangles/engine/map/ui/editor.js
index f9334e6..699597a 100644
--- a/public/assets/javascripts/rectangles/engine/map/ui_editor.js
+++ b/public/assets/javascripts/rectangles/engine/map/ui/editor.js
@@ -26,6 +26,13 @@ Map.UI.Editor = function(map){
resize: true,
destroy: false,
})
+
+ base.blur = function(){
+ Rooms.forEach(function(r){
+ return r.focused = false
+ })
+ app.tube("builder-pick-nothing")
+ }
//
@@ -35,6 +42,7 @@ Map.UI.Editor = function(map){
cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
if (e.ctrlKey || e.which === 3) {
+ if (Rooms.regions.length == 0) return
cursor.quantize(1/map.zoom)
map.center.a = cursor.x.a
map.center.b = -cursor.y.a
@@ -50,7 +58,7 @@ Map.UI.Editor = function(map){
return r.focused = r.rect.contains(cursor.x.a, cursor.y.a)
})
- if (intersects.length && base.permissions.destroy) {
+ if (intersects.length && (base.permissions.destroy || e.altKey)) {
base.mouse.down = false
room = intersects[0]
@@ -63,6 +71,9 @@ Map.UI.Editor = function(map){
Rooms.remove(room)
app.tube("builder-destroy-room", room)
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( (app.router.builderView || app.router.editorView).settings )
return
}
else if (intersects.length) {
@@ -161,18 +172,22 @@ Map.UI.Editor = function(map){
cursor.y.abs().quantize(1)
var room = Rooms.add_with_rect( cursor )
+ Rooms.rebuild()
+
UndoStack.push({
type: "create-room",
undo: { id: room.id },
redo: room.copy()
})
+ Rooms.rebuild()
app.tube("builder-pick-room", room)
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.controller.settings )
}
}
-
if (base.resizing || base.dragging) {
-
var oldState = base.dragging.copy()
if (base.resizing) {
@@ -187,24 +202,61 @@ Map.UI.Editor = function(map){
undo: oldState,
redo: base.dragging.copy()
})
+ Rooms.rebuild()
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( (app.router.builderView || app.router.editorView).settings )
}
+
+ var intersects = Rooms.filter(function(r){
+ return r.focused = r.rect.contains(cursor.x.a, cursor.y.a)
+ })
+ if (! base.dragging && ! intersects.length) {
+ app.tube("builder-pick-nothing")
+ }
base.creating = base.dragging = base.resizing = false
}
var wheelState, wheelTimeout
- function mousewheel (e, val, delta){
+ function mousewheel (e, deltaY, deltaX){
var cursor = base.mouse.cursor
var intersects = Rooms.filter(function(r){
- return r.focused = r.rect.contains(cursor.x.a, cursor.y.a)
+ return r.focused // = r.rect.contains(cursor.x.a, cursor.y.a)
})
- if (intersects.length) {
+ if (intersects.length && window.heightIsGlobal) {
+ var rooms = Rooms.values()
+ wheelState = wheelState || rooms[0].height
+ var height = clamp( ~~(rooms[0].height + deltaY * 2), height_min, height_max )
+ rooms.forEach(function(room){
+ room.height = height
+ })
+
+ app.tube("builder-pick-room", intersects[0])
+
+ clearTimeout(wheelTimeout)
+ wheelTimeout = setTimeout(function(){
+ UndoStack.push({
+ type: "update-rooms-height",
+ undo: wheelState,
+ redo: height
+ })
+ Rooms.rebuild()
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( (app.router.builderView || app.router.editorView).settings )
+
+ wheelState = null
+ }, 250)
+ }
+ else if (intersects.length) {
wheelState = wheelState || intersects[0].copy()
- intersects[0].height = clamp( ~~(intersects[0].height - delta), height_min, height_max )
+ intersects[0].height = clamp( ~~(intersects[0].height + deltaY * 2), height_min, height_max )
+ app.tube("builder-pick-room", intersects[0])
clearTimeout(wheelTimeout)
wheelTimeout = setTimeout(function(){
@@ -213,15 +265,20 @@ Map.UI.Editor = function(map){
undo: wheelState,
redo: intersects[0].copy()
})
- Rooms.clipper.update()
+ Rooms.rebuild()
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+
wheelState = null
- }, 500)
+ }, 250)
}
else {
- map.set_zoom(map.zoom_exponent - delta/20)
+ map.set_zoom(map.zoom_exponent + deltaY/20)
}
}
function rightclick (e){
}
+
}
diff --git a/public/assets/javascripts/rectangles/engine/map/ui_minimap.js b/public/assets/javascripts/rectangles/engine/map/ui/minimap.js
index fabbdb9..0fdd336 100644
--- a/public/assets/javascripts/rectangles/engine/map/ui_minimap.js
+++ b/public/assets/javascripts/rectangles/engine/map/ui/minimap.js
@@ -72,8 +72,8 @@ Map.UI.Minimap = function(map){
base.dragging = false
}
- function mousewheel (e, val, delta){
- map.set_zoom(map.zoom_exponent - delta/20)
+ function mousewheel (e, deltaY, deltaX){
+ map.set_zoom(map.zoom_exponent - deltaY/20)
}
function rightclick (e){
diff --git a/public/assets/javascripts/rectangles/engine/map/ui/ortho.js b/public/assets/javascripts/rectangles/engine/map/ui/ortho.js
new file mode 100644
index 0000000..5be7446
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/ui/ortho.js
@@ -0,0 +1,107 @@
+Map.UI = Map.UI || {}
+Map.UI.Ortho = function(map){
+
+ var base = this
+ var last_event = null
+
+ base.creating = base.dragging = base.resizing = false
+
+ base.mouse = new mouse({
+ el: map.el,
+ down: function(e, cursor){
+ last_event = e
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom)
+ if (tool.recenterCursor) {
+ cursor.x.add(map.center.a)
+ cursor.y.sub(map.center.b)
+ base.tools[currentTool].down(e, cursor)
+ }
+ else {
+ base.tools[currentTool].down(e, cursor)
+ cursor.x.add(map.center.a)
+ cursor.y.sub(map.center.b)
+ }
+ },
+ move: function(e, cursor){
+ last_event = e
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom)
+ if (tool.recenterCursor) {
+ cursor.x.add(map.center.a)
+ cursor.y.sub(map.center.b)
+ base.tools[currentTool].move(e, cursor)
+ }
+ else {
+ base.tools[currentTool].move(e, cursor)
+ cursor.x.add(map.center.a)
+ cursor.y.sub(map.center.b)
+ }
+ },
+ drag: function(e, cursor){
+ last_event = e
+ cursor.x.b = ((cursor.x.b/map.dimensions.a)+0.5) * map.dimensions.a / map.zoom
+ cursor.y.b = ((cursor.y.b/map.dimensions.b)-0.5) * map.dimensions.b / map.zoom
+ if (tool.recenterCursor) {
+ cursor.x.b += map.center.a
+ cursor.y.b -= map.center.b
+ base.tools[currentTool].drag(e, cursor)
+ }
+ else {
+ base.tools[currentTool].drag(e, cursor)
+ cursor.x.b += map.center.a
+ cursor.y.b -= map.center.b
+ }
+ },
+ up: function(e, cursor, new_cursor){
+ last_event = e
+ new_cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom)
+ new_cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom)
+ if (tool.recenterCursor) {
+ new_cursor.x.add(map.center.a)
+ new_cursor.y.sub(map.center.b)
+ base.tools[currentTool].up(e, cursor, new_cursor)
+ }
+ else {
+ base.tools[currentTool].up(e, cursor, new_cursor)
+ new_cursor.x.add(map.center.a)
+ new_cursor.y.sub(map.center.b)
+ }
+ if (nextTool) {
+ console.log('found nextTool')
+ base.set_tool(nextTool)
+ nextTool = null
+ }
+ }
+ })
+
+ var currentTool = "polyline", nextTool, tool
+ base.add_tool = function(name, tool){
+ base.tools[name] = tool
+ }
+ base.set_tool = function(s){
+ console.log("set tool to", s)
+ if (base.tools[currentTool]) {
+ base.tools[currentTool].cancel()
+ }
+ currentTool = s
+ tool = base.tools[currentTool]
+ }
+ base.set_drag_tool = function(s){
+ console.log('set drag tool to', s)
+ nextTool = currentTool
+ currentTool = s
+ tool = base.tools[currentTool]
+ base.tools[currentTool].down(last_event, base.mouse.cursor)
+ }
+ base.tools = {}
+
+ base.wheel = new wheel({
+ el: map.el,
+ update: mousewheel,
+ })
+
+ function mousewheel (e, deltaY, deltaX){
+ map.set_zoom(map.zoom_exponent - deltaY/20)
+ }
+}
diff --git a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js
index 6f96275..9aff33f 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js
@@ -13,6 +13,7 @@
vec2 = require('../../models/vec2')
Rect = require('../../models/rect')
Room = require('../../models/room')
+ Walls = require('./_walls')
UidGenerator = require('../../util/uid')
sort = require('../../util/sort')
_ = require('lodash')
@@ -36,6 +37,7 @@
base.list = {}
base.regions = []
+ base.shapesMode = false
base.uid = new UidGenerator(base.list)
@@ -64,13 +66,13 @@
base.remove = function(room){
delete base.list[room.id]
- Rooms.clipper.update()
+ Rooms.rebuild()
}
base.removeAll = function(){
base.list = {}
base.regions = []
- Rooms.clipper.update()
+ Rooms.rebuild()
}
base.count = function(){
@@ -80,6 +82,10 @@
base.forEach = function(f){
return base.values().forEach(f)
}
+
+ base.some = function(f){
+ return base.values().some(f)
+ }
base.map = function(f){
return base.values().map(f)
@@ -88,6 +94,17 @@
base.values = function(){
return _.values(base.list)
}
+
+ base.rebuild = function(walls_data){
+ if (base.shapesMode) return
+ walls_data = walls_data || Walls.serialize()
+ Rooms.clipper.update()
+ Rooms.builder.rebuild()
+ Rooms.grouper.build()
+ Walls.paint()
+ Walls.deserialize(walls_data)
+ app.tube("rooms-built")
+ }
base.serialize = function(){
var rooms = base.map(function(room){
@@ -96,7 +113,7 @@
return rooms
}
- base.deserialize = function(rooms_data){
+ base.deserialize = function(rooms_data, walls_data){
rooms_data.forEach(function(data){
if (! data || ! data.rect) return
var rect = new Rect(data.rect.x[0], data.rect.y[0], data.rect.x[1], data.rect.y[1])
@@ -107,7 +124,46 @@
})
base.add(room)
})
- Rooms.clipper.update()
+ Rooms.rebuild(walls_data)
+ }
+
+ base.deserializeFromShapes = function(data, walls_data) {
+ walls_data = walls_data || Walls.serialize()
+ base.shapesMode = true
+ window.viewHeight = data.viewHeight || app.defaults.viewHeight
+ window.wallHeight = data.wallHeight || app.defaults.wallHeight
+ $(".units").val( data.units )
+
+ Rooms.builder.clear()
+
+ shapes.deserialize( data.shapes )
+ // shapes.build()
+ var regions = RegionList.build()
+
+ regions.forEach(function(region){
+ var room = new Room({
+ rect: region,
+ regions: [region],
+ height: wallHeight,
+ })
+
+ room.sides = region.sides
+ region.id = Rooms.uid("room_")
+ Rooms.list[ region.id ] = room
+ var mx_walls = Rooms.builder.build_walls(region)
+ room.mx_floor = Rooms.builder.make_floor(room, region)
+ room.mx_ceiling = Rooms.builder.make_ceiling(room, region)
+
+ mx_walls.forEach(function(mx){ scene.add(mx) })
+ scene.add(room.mx_floor)
+ scene.add(room.mx_ceiling)
+ })
+
+ Rooms.grouper.build()
+
+ Walls.paint()
+ Walls.deserialize(walls_data)
+ app.tube("rooms-built")
}
base.report = function(){
@@ -118,6 +174,14 @@
return data
}
+ base.extent = function(){
+ var extent = new Rect ( new vec2(Infinity, -Infinity), new vec2(Infinity, -Infinity) )
+ base.forEach(function(room){
+ extent.expand(room.rect)
+ })
+ return extent
+ }
+
base.sorted_by_position = function(){
return sort.rooms_by_position( base.values() )
}
diff --git a/public/assets/javascripts/rectangles/engine/rooms/_walls.js b/public/assets/javascripts/rectangles/engine/rooms/_walls.js
index 82ccb87..38dac84 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/_walls.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/_walls.js
@@ -35,8 +35,23 @@
var base = this
base.list = []
+ base.floors = []
base.lookup = {}
base.colors = {}
+
+ base.init = function(){
+ base.colors = base.copyColors( app.defaults.colors )
+ }
+
+ base.copyColors = function(colors){
+ var copy = {
+ wall: colors.wall.slice(),
+ outline: colors.outline.slice(),
+ floor: colors.floor.slice(),
+ ceiling: colors.ceiling.slice(),
+ }
+ return copy
+ }
base.first = function(){
for (var i in base.list) {
@@ -46,6 +61,10 @@
}
}
+ base.find = function(id){
+ return base.lookup[id]
+ }
+
base.assign = function(list){
base.list = list
base.lookup = {}
@@ -53,11 +72,21 @@
base.lookup[wall.id] = wall
})
}
+
+ base.assignFloors = function(floors){
+ base.floors = floors
+ floors.forEach(function(floor){
+ base.lookup[floor.id] = floor
+ })
+ }
base.bind = function(){
base.list.forEach(function(wall){
wall.bind()
})
+ base.floors.forEach(function(floor){
+ floor.bind()
+ })
}
base.count = function(){
@@ -65,16 +94,20 @@
}
base.forEach = function(f){
- return base.list.forEach(f)
+ return base.values().forEach(f)
}
base.map = function(f){
- return base.list.map(f)
+ return base.values().map(f)
}
-
+
+ base.values = function(){
+ return _.values(base.lookup)
+ }
+
base.serialize = function(){
var data = []
- base.list.forEach(function(wall){
+ base.forEach(function(wall){
data.push(wall.serialize())
})
return data
@@ -84,6 +117,9 @@
walls_data.forEach(function(wall_data){
if (! wall_data) { return }
var wall = base.lookup[ wall_data.id ]
+ if (! wall) {
+ return
+ }
wall.deserialize( wall_data )
})
},
@@ -93,21 +129,91 @@
var outlineColor = rgb_string(Walls.colors.outline)
var floorColor = rgb_string(Walls.colors.floor)
var ceilingColor = rgb_string(Walls.colors.ceiling)
- Walls.forEach(function(wall){
+ Walls.list.forEach(function(wall){
wall.outline(wallColor, outlineColor)
})
- Rooms.forEach(function(room){
- room.setFloorColor(floorColor)
- room.setCeilingColor(ceilingColor)
+ Walls.floors.forEach(function(floor){
+ if (floor.ceiling) floor.color(ceilingColor)
+ else floor.color(floorColor)
})
}
+ base.luminance = function(rgb){
+ rgb = rgb || Walls.colors.ceiling
+ var rgb_max = Math.max.apply(0, rgb)
+ var rgb_min = Math.min.apply(255, rgb)
+ return (rgb_max + rgb_min ) / 2
+ }
+
+ base.setBodyColor = function(){
+ $("#header").toggleClass("black", Walls.luminance() < 100)
+ $("body").css("background-color", rgb_string( Walls.colors.wall ))
+ }
+ base.clearBodyColor = function(){
+ $("#header").removeClass("black")
+ $("body").css("background-color", "transparent")
+ }
+
+ base.setWallpaper = {
+ wall: function(background){
+ var img = new Image ()
+ img.onload = function(){
+ Walls.list.forEach(function(wall){
+ wall.wallpaper(background, img)
+ })
+ }.bind(this)
+ img.src = background.src.replace(/url\(\"?\'?/,"").replace(/\"?\'?\)/,"")
+ img.complete && img.onload()
+ },
+ floor: function(background){
+ Walls.floors.forEach(function(floor){
+ if (floor.ceiling) return
+ floor.wallpaper(background)
+ })
+ },
+ ceiling: function(background){
+ Walls.floors.forEach(function(floor){
+ if (! floor.ceiling) return
+ floor.wallpaper(background)
+ })
+ },
+ }
+
+ base.clearWallpaper = {
+ wall: function(){
+ Walls.list.forEach(function(wall){
+ wall.wallpaper("none")
+ })
+ },
+ outline: function(){
+ },
+ floor: function(){
+ Walls.floors.forEach(function(floor){
+ if (floor.ceiling) return
+ floor.wallpaper("none")
+ })
+ },
+ ceiling: function(){
+ Walls.floors.forEach(function(floor){
+ if (! floor.ceiling) return
+ floor.wallpaper("none")
+ })
+ },
+ }
+
base.setColor = {
wall: function(rgb){
var rgbaColor = rgba_string(rgb, app.defaults.wallOpacity)
+ var rgbColor = rgb_string(rgb)
+
+ if (Rooms.mover.room) {
+ $("#header").toggleClass("black", base.luminance() < 100)
+ $("body").css("background-color", rgbColor)
+ }
+
Walls.colors.wall = rgb
- Walls.forEach(function(wall){
+ Walls.list.forEach(function(wall){
wall.outline(rgbaColor, null)
})
},
@@ -115,7 +221,7 @@
outline: function(rgb){
var rgbColor = rgb_string(rgb)
Walls.colors.outline = rgb
- Walls.forEach(function(wall){
+ Walls.list.forEach(function(wall){
wall.outline(null, rgbColor)
})
},
@@ -123,19 +229,20 @@
floor: function(rgb){
var rgbColor = rgb_string(rgb)
Walls.colors.floor = rgb
- Rooms.forEach(function(room){
- room.setFloorColor(rgbColor)
+ Walls.floors.forEach(function(floor){
+ if (floor.ceiling) return
+ floor.color(rgbColor)
})
},
ceiling: function(rgb){
var rgbColor = rgb_string(rgb)
Walls.colors.ceiling = rgb
- Rooms.forEach(function(room){
- room.setCeilingColor(rgbColor)
+ Walls.floors.forEach(function(floor){
+ if (! floor.ceiling) return
+ floor.color(rgbColor)
})
},
-
}
}
diff --git a/public/assets/javascripts/rectangles/engine/rooms/builder.js b/public/assets/javascripts/rectangles/engine/rooms/builder.js
index 6a89158..f78fb91 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/builder.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/builder.js
@@ -14,6 +14,7 @@
PI = Math.PI
HALF_PI = PI/2
TOP = CEILING, BOTTOM = FLOOR
+ $ = { browser: { mozilla: false } }
function sidesToString(sides){
var s = ""
if (sides & FRONT) s += "front "
@@ -32,19 +33,16 @@
var els = []
base.init = function(){
- base.bind()
+ // base.bind()
}
base.bind = function(){
- app.on("clip", base.rebuild.bind(base))
}
base.rebuild = function(){
if (window.scene) {
base.clear()
base.build()
- Rooms.grouper.build()
- app.tube("rooms-built")
}
}
@@ -264,6 +262,9 @@
el.rotationX = PI/2
el.rect = region
el.side = FLOOR
+ if ($.browser.mozilla) {
+ el.el.style.display = "none"
+ }
return el
}
this.make_ceiling = function (room, region) {
@@ -280,10 +281,13 @@
el.rotationX = -PI/2
el.rect = region
el.side = CEILING
+ if ($.browser.mozilla) {
+ el.el.style.display = "none"
+ }
return el
}
this.make_wall = function (klass) {
- // klass += ".backface-hidden"
+ klass += ".backface-hidden"
var el = new MX.Object3D(".face" + (klass || ""))
el.width = el.height = el.scaleX = el.scaleY = el.scaleZ = 1
el.z = el.y = el.x = 0
@@ -296,7 +300,7 @@
this.el = this.rect = this.face = null
}
- // possible if walls are opaque
+ // preferable if walls are opaque
// el.el.classList.add("backface-hidden")
return el
diff --git a/public/assets/javascripts/rectangles/engine/rooms/clipper.js b/public/assets/javascripts/rectangles/engine/rooms/clipper.js
index 33e3a84..df83cc8 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/clipper.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/clipper.js
@@ -38,7 +38,6 @@
base.update = function(){
base.solve_rects()
- app.tube("clip")
}
var regions
@@ -49,7 +48,7 @@
Rooms.regions = regions = []
return
}
-
+
base.reset_rects()
base.clip_rects()
var culled = base.cull_rects_iterative()
diff --git a/public/assets/javascripts/rectangles/engine/rooms/grouper.js b/public/assets/javascripts/rectangles/engine/rooms/grouper.js
index 663d29d..890a476 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/grouper.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/grouper.js
@@ -48,13 +48,16 @@
base.build = function (){
var walls = []
+ var floors = []
var collections = base.collect()
base.cull(collections)
base.group(walls, collections, FRONT)
base.group(walls, collections, BACK)
base.group(walls, collections, LEFT)
base.group(walls, collections, RIGHT)
+ base.groupFloors(floors, collections)
Walls.assign( walls )
+ Walls.assignFloors( floors )
Walls.bind()
}
base.collect = function(){
@@ -63,12 +66,16 @@
collections[BACK] = []
collections[LEFT] = []
collections[RIGHT] = []
+ collections[FLOOR] = []
+ collections[CEILING] = []
Rooms.forEach(function(room){
room.mx_walls.forEach(function(mx){
var side = mx.side || mx.half_side
collections[side].push(mx)
})
+ collections[FLOOR] = collections[FLOOR].concat( room.mx_floor )
+ collections[CEILING] = collections[CEILING].concat( room.mx_ceiling )
})
base.cull(collections)
@@ -161,6 +168,20 @@
return walls
}
+ base.groupFloors = function(floors, collections){
+ var floor = new Floor ({
+ id: 'floor',
+ side: FLOOR,
+ mx: collections[FLOOR]
+ })
+ var ceiling = new Floor ({
+ id: 'ceiling',
+ side: CEILING,
+ mx: collections[CEILING]
+ })
+ floors.push(floor)
+ floors.push(ceiling)
+ }
}
diff --git a/public/assets/javascripts/rectangles/engine/rooms/mover.js b/public/assets/javascripts/rectangles/engine/rooms/mover.js
index 7195fcc..ac27aba 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/mover.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/mover.js
@@ -4,6 +4,15 @@ Rooms.mover = new function(){
base.room = null
base.noclip = false
+ var cursor = base.cursor = new Rect (0,0,0,0)
+ var cursor_copy = new Rect (0,0,0,0)
+ var wall_vec = new Rect (0,0,0,0)
+ var intersect = new vec2(0,0)
+
+ var origins = new Rect()
+ origins.x = cursor.x
+ origins.y = wall_vec.x
+
base.init = function(){
base.bind()
base.update(scene.camera)
@@ -11,7 +20,8 @@ Rooms.mover = new function(){
base.bind = function(){
app.on("move", base.update)
- keys.on("backslash", function(){
+ keys.on("backslash", function(e){
+ if ( ! (e.ctrlKey || e.metaKey) ) return
base.noclip = ! base.noclip
base.room = null
app.movements.gravity( ! base.noclip )
@@ -19,15 +29,9 @@ Rooms.mover = new function(){
}
base.update = function(pos){
+ var intersect, collision, distance
var radius = scene.camera.radius
- if (base.noclip) {
- cam.x = pos.x
- cam.y = pos.y
- cam.z = pos.z
- return
- }
-
cam.y = pos.y
// if we were in a room already..
@@ -39,17 +43,41 @@ Rooms.mover = new function(){
return
}
- // check if we've breached one of the walls.. clamp position if so
- var collision = base.room.collidesDisc(pos.x, pos.z, radius)
-
- if (collision) {
- cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x
- cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z
- return
+ distance = sqrt(pow(cam.x-pos.x, 2), pow(cam.z-pos.z, 2))
+
+ // check if we've breached one of the walls.. clamp position if so.
+ // there are two algorithms for this now, ridiculously..
+ // - the first one is smoother, best for keyboard use
+ // but if the distance travelled is greater than the min. distance from the wall,
+ // then there is a possibility of ejection from the room. so is bad for phone/mousewheel.
+
+ // - the second one determines fortuitously if we have breached any of the walls
+ // however it can get jumpy if you run into a wall.. thus it is best for devices like phone or mousewheel
+ // the benefit is you will never leave the room.
+ if (base.noclip) {
+ // in no-clip mode we walk through walls.
}
+ else if (distance < radius) {
+ collision = base.room.collidesDisc(cam, pos, radius)
+
+ if (collision) {
+ cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x
+ cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z
+ return
+ }
+ }
+ else {
+ intersect = base.intersect(pos)
+ if (intersect) {
+ cam.x = intersect.a
+ cam.z = intersect.b
+ return
+ }
+ }
// in this case, we appear to have left the room..
- $(".face.active").removeClass("active")
+ // $(".face.active").removeClass("active")
+ Walls.clearBodyColor()
base.room = null
}
@@ -65,11 +93,162 @@ Rooms.mover = new function(){
// did we actually enter a room?
if (intersects.length) {
base.room = intersects[0]
- base.room.mx_floor.forEach(function(w){ $(w.el).addClass("active") })
- base.room.mx_ceiling.forEach(function(w){ $(w.el).addClass("active") })
- base.room.mx_walls.forEach(function(w){ $(w.el).addClass("active") })
+ if (! base.noclip) {
+ Walls.setBodyColor()
+ }
+ app.tube("change-room", { room: base.room })
}
-
}
+ base.intersect = function(pos){
+ var closest_intersect, closest_wall, new_t, wall_t, t, min_t = 1
+
+ cursor_copy.x.a = cursor.x.a = cam.x
+ cursor_copy.x.b = cursor.x.b = cam.z
+ cursor_copy.y.a = cursor.y.a = pos.x
+ cursor_copy.y.b = cursor.y.b = pos.z
+
+ cursor_copy.extend_ends(scene.camera.radius)
+
+ origins.x = cursor_copy.x
+ origins.y = wall_vec.x
+
+ Walls.list.forEach(function(wall, i){
+ var actually_intersects = false, intersecting_face
+
+ wall.get_points(wall_vec)
+
+ t = perp(origins, wall_vec) / ( perp(cursor_copy, wall_vec) || 0.0000001 )
+
+ if ( min_t < t || t < 0 || 1 < t ) return
+
+ intersect.a = cursor_copy.x.a + ( cursor_copy.y.a - cursor_copy.x.a ) * t
+ intersect.b = cursor_copy.x.b + ( cursor_copy.y.b - cursor_copy.x.b ) * t
+
+ if ( ! is_collinear( intersect, wall_vec ) ) return
+
+ if (wall.side & LEFT_RIGHT) {
+ intersecting_face = wall.surface.face_for_x(intersect.b)
+ }
+ else {
+ intersecting_face = wall.surface.face_for_x(intersect.a)
+ }
+
+ actually_intersects = !! (intersecting_face && intersecting_face.y.a == 0)
+ if (actually_intersects) {
+ closest_intersect = intersect.clone()
+ closest_wall = wall_vec.clone()
+ min_t = t
+ }
+ })
+
+ if (closest_intersect) {
+
+ var aw, len, dd
+ aw = angle(closest_wall)
+ wall_vec.assign(closest_wall)
+ wall_vec.x.a -= scene.camera.radius * sin(aw)
+ wall_vec.x.b += scene.camera.radius * cos(aw)
+ wall_vec.y.a -= scene.camera.radius * sin(aw)
+ wall_vec.y.b += scene.camera.radius * cos(aw)
+
+ origins.x = cursor.x
+ origins.y = wall_vec.x
+
+ new_t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 )
+ wall_t = perp(origins, cursor) / ( perp(wall_vec, cursor) || 0.0000001 )
+
+ intersect.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * new_t
+ intersect.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * new_t
+
+ // here compare len to the length of the wall in the direction we are travelling
+ dd = dot2(diff(closest_wall), diff(cursor))
+ len = sqrt(dot(wall_vec, wall_vec))
+ if (dd > 0) {
+ len *= 1-abs(wall_t)
+ }
+ else {
+ len *= abs(wall_t)
+ aw += PI
+ }
+
+ len = clamp(len, 0, (1-min_t) * sqrt(dot(cursor, cursor)))
+
+ intersect.a += len * cos(aw)
+ intersect.b += len * sin(aw)
+
+ wall_vec.normalize()
+ intersect.a = clamp(intersect.a, wall_vec.x.a, wall_vec.y.a)
+ intersect.b = clamp(intersect.b, wall_vec.x.b, wall_vec.y.b)
+
+ return intersect
+ }
+ else {
+ return cursor.y
+ }
+ }
+ function diff (v) {
+ return new vec2(v.y.a - v.x.a, v.y.b - v.x.b)
+ }
+ function angle (va) {
+ return atan2(va.y.b - va.x.b, va.y.a - va.x.a)
+ }
+ function angle2 (pa, pb) {
+ return atan2(pb.b - pa.b, pb.a - pa.a)
+ }
+ function normal (va) {
+ return atan2(va.x.a - va.y.a, va.y.b - va.x.b)
+ }
+ function dot (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.a - vb.x.a) + (va.y.b - va.x.b) * (vb.y.b - vb.x.b)
+ }
+ function dot2 (pa, pb) {
+ return pa.a * pb.a + pa.b * pb.b
+ }
+ function perp (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a)
+ }
+ function is_collinear (p, vec) {
+ var on_x, on_y
+ var pa = round(p.a), pb = round(p.b)
+
+ if (vec.x.a < vec.y.a) {
+ on_x = vec.x.a <= pa && pa <= vec.y.a
+ }
+ else {
+ on_x = vec.x.a >= pa && pa >= vec.y.a
+ }
+
+ if (vec.x.b < vec.y.b) {
+ on_y = vec.x.b <= pb && pb <= vec.y.b
+ }
+ else {
+ on_y = vec.x.b >= pb && pb >= vec.y.b
+ }
+
+ return !! (on_x && on_y)
+ }
+ cursor_copy.extend_ends = function(n){
+ var a = angle(this)
+ this.x.a -= n*cos(a)
+ this.x.b -= n*sin(a)
+ this.y.a += n*cos(a)
+ this.y.b += n*sin(a)
+ return this
+ }
+ wall_vec.normalize = function(){
+ var carry
+ if (this.x.a > this.y.a) {
+// console.log("SWAP X")
+ carry = this.x.a
+ this.x.a = this.y.a
+ this.y.a = carry
+ }
+ if (this.x.b > this.y.b) {
+// console.log("SWAP Y")
+ carry = this.x.b
+ this.x.b = this.y.b
+ this.y.b = carry
+ }
+ }
}
diff --git a/public/assets/javascripts/rectangles/engine/rooms/projector.js b/public/assets/javascripts/rectangles/engine/rooms/projector.js
deleted file mode 100644
index 2eac314..0000000
--- a/public/assets/javascripts/rectangles/engine/rooms/projector.js
+++ /dev/null
@@ -1,30 +0,0 @@
-
-rooms.projector = new function(){
-
- projector = new THREE.Projector();
- vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
- projector.unprojectVector( vector, camera );
-
- raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
- intersects = raycaster.intersectObjects( scene.children, true );
-
-}
-
-
-
-THREE.Projector = function () {
-
- _viewProjectionMatrix = new THREE.Matrix4(),
-
- this.unprojectVector = function ( vector, camera ) {
- camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
-
- _viewProjectionMatrix.multiplyMatrices(
- camera.matrixWorld,
- camera.projectionMatrixInverse
- );
-
- return vector.applyProjection( _viewProjectionMatrix );
- };
-
-}
diff --git a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js
index d34e299..6203c20 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js
@@ -5,11 +5,13 @@ var Scenery = new function(){
base.list = {}
base.nextMedia = null
+ base.nextWallpaper = null
- base.mouse = new mouse ({ use_offset: false })
+ base.mouse = new mouse ({ use_offset: false, mousedownUsesCapture: true })
base.init = function(){
base.resize.init()
+ base.sound.init()
}
base.add = function(opt){
@@ -22,20 +24,35 @@ var Scenery = new function(){
case 'video':
case 'youtube':
case 'vimeo':
+ if (is_mobile) return
scene_media = new Scenery.types.video (opt)
break
+
+ case 'soundcloud':
+ if (is_mobile) return
+ scene_media = new Scenery.types.audio (opt)
+ break
+
+ case 'text':
+ scene_media = new Scenery.types.text (opt)
+ scene_media.focused = !! opt.newMedia
+ break
}
base.list[scene_media.id] = scene_media
return scene_media
}
base.addNextToWall = function(opt){
+ opt.newMedia = true
opt.media = base.nextMedia
opt.index = opt.index || 0
var scene_media = base.add(opt)
// test if scenery was placed here
- if (! scene_media.bounds) {
+ if (! scene_media) {
+ return null
+ }
+ else if (! scene_media.bounds) {
base.remove( scene_media.id )
return null
}
@@ -48,7 +65,7 @@ var Scenery = new function(){
base.find = function(id){
return base.list[id] || null
}
-
+
base.remove = function(id){
var scene_media = base.list[id]
delete base.list[id]
@@ -83,6 +100,7 @@ var Scenery = new function(){
}
base.deserialize = function(scenery_data){
+ var added = []
scenery_data.forEach(function(data){
var wall = Walls.lookup[data.wall_id] || Walls.first()
var scene_media = base.add({
@@ -91,9 +109,40 @@ var Scenery = new function(){
media: data.media,
id: data.id
})
+ added.push(scene_media)
})
+ return added
}
+ base.rewindAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") scenery.seek(0)
+ })
+ }
+ base.playAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") {
+ scenery.unmute()
+ scenery.play()
+ }
+ })
+ }
+ base.pauseAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") scenery.pause()
+ })
+ }
+ base.muteAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") scenery.mx.mute()
+ })
+ }
+ base.unmuteAll = function(){
+ base.forEach(function(scenery){
+ if (scenery.type == "video") scenery.mx.unmute()
+ })
+ }
+
return base
}
diff --git a/public/assets/javascripts/rectangles/engine/scenery/move.js b/public/assets/javascripts/rectangles/engine/scenery/move.js
index 93bccb0..94c6281 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/move.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/move.js
@@ -2,7 +2,7 @@
Scenery.move = function(base){
var x, y, z, position, dimension, bounds
- var dragging = false
+ var dragging = false, moved = false
var oldState
this.bind = function(){
@@ -14,6 +14,7 @@ Scenery.move = function(base){
}
this.unbind = function(){
+ base.focused = false
Scenery.mouse.unbind_el(base.mx.el)
Scenery.mouse.off("down", down)
Scenery.mouse.off("enter", switch_wall)
@@ -22,29 +23,26 @@ Scenery.move = function(base){
}
function down (e, cursor){
- if (e.target != base.mx.el) return;
+ if (e.target != base.mx.el && (e.target != base.mx.overlay)) return;
if (editor.permissions.destroy) {
- UndoStack.push({
- type: 'destroy-scenery',
- undo: base.serialize(),
- redo: { id: base.id },
- })
-
- // TODO: watch individual scenery object here
- Minotaur.watch( app.router.editorView.settings )
-
- Scenery.remove(base.id)
+ base.remove()
return
}
-
+
// load the modal
app.controller.pick(base)
+ if (! base.focused) {
+ e.clickAccepted = false
+ base.focused = true
+ return
+ }
if (! (editor.permissions.move || editor.permissions.resize) ) {
e.clickAccepted = false
return
}
dragging = true
+ moved = false
x = base.mx.x
y = base.mx.y
z = base.mx.z
@@ -59,6 +57,8 @@ Scenery.move = function(base){
function drag (e, cursor){
if (! dragging) return
+
+ moved = true
var flipX = base.wall.side & (FRONT | RIGHT)
@@ -75,13 +75,14 @@ Scenery.move = function(base){
switch (base.wall.side) {
case FRONT:
case BACK:
- base.mx.x = position.a + delta.a * cos(wall_rotation[base.wall.side]) + dimension.a / 2
+ base.mx.x = position.a + delta.a * cos(base.wall.rotationY) + dimension.a / 2
break
case LEFT:
case RIGHT:
- base.mx.z = position.a + delta.a * sin(wall_rotation[base.wall.side]) + dimension.a / 2
+ base.mx.z = position.a + delta.a * sin(base.wall.rotationY) + dimension.a / 2
break
}
+
if (editor.permissions.resize) {
Scenery.resize.move_dots()
}
@@ -89,21 +90,22 @@ Scenery.move = function(base){
function up (e, cursor){
if (! dragging || ! oldState) return
-
- dragging = false
- document.body.classList.remove("dragging")
-
- UndoStack.push({
- type: 'update-scenery',
- undo: oldState,
- redo: base.serialize(),
- })
+
+ if (moved) {
+ UndoStack.push({
+ type: 'update-scenery',
+ undo: oldState,
+ redo: base.serialize(),
+ })
- // TODO: watch individual scenery object here
- Minotaur.watch( app.router.editorView.settings )
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ }
+ dragging = moved = false
oldState = null
- }
+ document.body.classList.remove("dragging")
+ }
function switch_wall (e, target, cursor){
if (! dragging) return
@@ -142,7 +144,7 @@ Scenery.move = function(base){
if (editor.permissions.resize) {
Scenery.resize.rotate_dots()
-// Scenery.resize.move_dots()
+ Scenery.resize.move_dots()
}
cursor.x.a = cursor.x.b
diff --git a/public/assets/javascripts/rectangles/engine/scenery/randomize.js b/public/assets/javascripts/rectangles/engine/scenery/randomize.js
new file mode 100644
index 0000000..6581f38
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js
@@ -0,0 +1,115 @@
+/*
+ // get the list of media we want to place
+ var media_objs = $(".mediaContainer").toArray().map(function(el){
+ return $(el).data("media")
+ })
+ Scenery.randomize.add( media_objs )
+*/
+
+Scenery.randomize = {};
+
+// Given a list of media objects, generate their ideal dimensions
+Scenery.randomize.get_dimensions = function (media_objs){
+ var media_list = media_objs.map(function(media){
+ var width, height
+ if (media.width > media.height) {
+ width = Math.min(DEFAULT_PICTURE_WIDTH, media.width)
+ height = media.height/media.width * width
+ }
+ else {
+ height = Math.min(DEFAULT_PICTURE_WIDTH, media.height)
+ width = media.width/media.height * height
+ }
+ return {
+ dimensions: new vec2( width, height ),
+ media: media,
+ }
+ })
+ return media_list
+}
+
+// Build the lookup of empty walls.
+// Takes a list of walls to use, or undefined to use all empty walls.
+// Returns a lookup of walls to use, keyed by wall ID.
+Scenery.randomize.get_empty_walls = function(wall_list){
+ // get a list of all walls
+ var walls = {}, removed = [];
+
+ (wall_list || Walls.list).forEach(function(wall){
+ walls[wall.id] = wall
+ })
+
+ // remove the walls that already have stuff on them
+ if (! wall_list) {
+ Scenery.forEach(function(scenery){
+ if (scenery.was_randomly_placed) {
+ // remove it and reuse this wall?
+ removed.push( scenery.serialize() )
+ Scenery.remove( scenery.id )
+ }
+ else {
+ delete walls[scenery.wall.id]
+ }
+ })
+ }
+
+ return { walls: walls, removed: removed }
+}
+
+// Randomly place a set of media objects on empty walls.
+// Only one object per wall will be added.
+// Optionally takes a list of walls to use.
+Scenery.randomize.add = function (media_objs, wall_list) {
+ var media_list = Scenery.randomize.get_dimensions(media_objs)
+ var empty_data = Scenery.randomize.get_empty_walls(wall_list)
+ var walls = empty_data.walls
+ var removed = empty_data.removed
+ var added = []
+
+ var wall_ids = _.keys(walls)
+ if (! wall_ids.length) { return }
+
+ // randomize walls
+ shuffle(wall_ids)
+ shuffle(media_list)
+
+ // assign each of the media to the walls, until we run out of either
+ media_list.some(function(media){
+ // bail if we're out of walls
+ if (wall_ids.length == 0) { return true }
+
+ var i, fits = -1
+
+ for (i = 0; i < wall_ids.length; i++) {
+ if (walls[wall_ids[i]].surface.fits(media.dimensions)) {
+ fits = i
+ break
+ }
+ }
+
+ if (fits != -1) {
+ var wall = walls[wall_ids[fits]]
+ wall_ids.splice(fits, 1)
+
+ var scenery = Scenery.add({
+ media: media.media,
+ wall: wall,
+ index: 0,
+ })
+ scenery.was_randomly_placed = true
+ added.push(scenery.serialize())
+ }
+ else {
+ // artwork won't fit anywhere??
+ }
+
+ return false
+ })
+
+ UndoStack.push({
+ type: "randomize-scenery",
+ undo: { added: added, removed: removed },
+ redo: { added: added, removed: removed },
+ })
+
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js
index e26c0a7..252af74 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/resize.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js
@@ -6,8 +6,9 @@ Scenery.resize = new function(){
var obj
var x, y, z, bounds
var dragging = false
- var naturalDimension, dimension, position, scale
+ var naturalDimension, naturalDimensionCopy, dimension, position, scale
var oldState
+ var rotationY
var dots = [], dot, selected_dot
@@ -31,7 +32,8 @@ Scenery.resize = new function(){
// generate a dot element
base.build_dot = function(side) {
var dot = new MX.Object3D('.dot')
- dot.width = dot.height = dot_side
+ dot.width = dot.height = dot_side * 2
+ dot.scale = 0.5
dot.side = side
$(dot.el).on({
mouseenter: function(){ base.hovering = true },
@@ -48,7 +50,8 @@ Scenery.resize = new function(){
// rotate the dots as appropriate
base.rotate_dots = function(){
- rotationY = wall_rotation[obj.wall.side]
+ // console.trace()
+ rotationY = obj.wall.rotationY
dots.forEach(function(dot){
dot.rotationY = rotationY
})
@@ -56,45 +59,43 @@ Scenery.resize = new function(){
// move all the dots to the object's current position
base.move_dots = function(){
- x = obj.mx.x + sin(rotationY) * dot_distance_from_picture
- y = obj.mx.y
- z = obj.mx.z - cos(rotationY) * dot_distance_from_picture
+ var x = obj.mx.x + sin(rotationY) * dot_distance_from_picture
+ var y = obj.mx.y
+ var z = obj.mx.z - cos(rotationY) * dot_distance_from_picture
dots.forEach(function(dot){
- base.move_dot(dot)
+ base.move_dot(dot, { x: x, y: y, z: z })
})
}
// move a dot .. to the initial position of the image
- base.move_dot = function(dot){
- dot.x = x
- dot.y = y
- dot.z = z
-
+ base.move_dot = function(dot, pos){
if (dot.side & TOP) {
- dot.y += obj.mx.height * obj.mx.scale / 2
+ pos.y += obj.dimensions.b / 2
}
if (dot.side & BOTTOM) {
- dot.y -= obj.mx.height * obj.mx.scale / 2
+ pos.y -= obj.dimensions.b / 2
}
if (dot.side & LEFT) {
- dot.x -= cos(rotationY) * (obj.mx.width * obj.mx.scale) / 2
- dot.z -= sin(rotationY) * (obj.mx.width * obj.mx.scale) / 2
+ pos.x -= cos(rotationY) * (obj.dimensions.a) / 2
+ pos.z -= sin(rotationY) * (obj.dimensions.a) / 2
}
if (dot.side & RIGHT) {
- dot.x += cos(rotationY) * (obj.mx.width * obj.mx.scale) / 2
- dot.z += sin(rotationY) * (obj.mx.width * obj.mx.scale) / 2
+ pos.x += cos(rotationY) * (obj.dimensions.a) / 2
+ pos.z += sin(rotationY) * (obj.dimensions.a) / 2
}
+ dot.move(pos)
}
// pick a new object to focus on and show the dots
base.show = function(new_object) {
// if (obj === new_object) return
+ if (! new_object) return
obj = new_object
-
base.add_dots()
base.rotate_dots()
base.move_dots()
+ Sculpture.resize.hide()
}
// dismiss the dots on blur
@@ -119,22 +120,13 @@ Scenery.resize = new function(){
base.bind = function(){
dots.forEach(function(dot){
Scenery.mouse.bind_el(dot.el)
- $(dot.el).bind({
- mouseenter: function(e){
- Scenery.resize.hovering = true
- },
- mouseleave: function(e){
- Scenery.resize.hovering = false
- base.defer_hide()
- }
- })
})
Scenery.mouse.on("down", down)
Scenery.mouse.on("drag", drag)
Scenery.mouse.on("up", up)
}
- this.unbind = function(){
+ base.unbind = function(){
dots.forEach(function(dot){
Scenery.mouse.unbind_el(dot.el)
})
@@ -146,15 +138,19 @@ Scenery.resize = new function(){
function down (e, cursor){
var selection = dots.filter(function(dot){return e.target == dot.el})
if (! selection.length) return
-
+
selected_dot = selection[0]
dragging = true
naturalDimension = obj.naturalDimensions
dimension = obj.dimensions
position = new vec3(obj.mx.x, obj.mx.y, obj.mx.z)
- scale = obj.mx.scale
oldState = obj.serialize()
+
+ if (obj.type == "text") {
+ naturalDimensionCopy = naturalDimension.clone()
+ positionCopy = position.clone()
+ }
document.body.classList.add("dragging")
}
@@ -167,7 +163,6 @@ Scenery.resize = new function(){
var width = cursor.x.magnitude()
var height = cursor.y.magnitude()
var mag = cursor.magnitude()
- var old_width = dimension.a * scale
if (abs(width) > abs(height)) {
mag = x_sign * mag * sign(width)
@@ -176,18 +171,23 @@ Scenery.resize = new function(){
mag = y_sign * mag * sign(height)
}
- obj.set_scale( ( dimension.a + mag ) / naturalDimension.a )
- // dimension.a // scale * (old_width + mag) / old_width
+ if (obj.type == "text") {
+ obj.mx.width = obj.media.width = naturalDimension.a = naturalDimensionCopy.a + (mag * 2)
+ obj.mx.height = obj.media.height = naturalDimension.b = naturalDimensionCopy.b + (mag * 2)
+ dimension.a = naturalDimension.a * obj.scale
+ dimension.b = naturalDimension.b * obj.scale
+ }
+ else {
+ obj.set_scale( ( dimension.a + mag ) / naturalDimension.a )
+ }
-// console.log(scale, obj.mx.scale, dimension.a + mag, naturalDimension.a)
-
- if (selected_dot.side & LEFT_RIGHT) {
- obj.mx.x = position.a + cos(rotationY) * mag/2 * (x_sign)
- obj.mx.z = position.c + sin(rotationY) * mag/2 * (x_sign)
- }
- if (selected_dot.side & TOP_BOTTOM) {
- obj.mx.y = position.b - mag/2 * y_sign
- }
+ if (selected_dot.side & LEFT_RIGHT) {
+ obj.mx.x = position.a + cos(rotationY) * mag/2 * (x_sign)
+ obj.mx.z = position.c + sin(rotationY) * mag/2 * (x_sign)
+ }
+ if (selected_dot.side & TOP_BOTTOM) {
+ obj.mx.y = position.b - mag/2 * y_sign
+ }
base.move_dots()
@@ -195,12 +195,28 @@ Scenery.resize = new function(){
}
function up (e, cursor){
+ if (! dragging) return
dragging = false
- selected_dot = null
if (! editor.permissions.resize) { return }
- obj.scale = obj.mx.ops.scale = obj.mx.scale
- obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale)
+ if (obj.type == "text") {
+ var newHeight = $(obj.mx.inner).height()
+ if (selected_dot.side & BOTTOM) {
+ obj.mx.y = position.b + (naturalDimensionCopy.b - newHeight) / 2 * obj.scale
+ }
+ else {
+ obj.mx.y = dots[0].y - newHeight/2*obj.scale
+ }
+ obj.mx.height = obj.media.height = naturalDimension.b = newHeight
+ dimension.a = naturalDimension.a * obj.scale
+ dimension.b = naturalDimension.b * obj.scale
+ base.move_dots()
+ }
+ else {
+ obj.scale = obj.mx.ops.scale = obj.mx.scale
+ obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale)
+ }
+
UndoStack.push({
type: 'update-scenery',
undo: oldState,
@@ -211,6 +227,7 @@ Scenery.resize = new function(){
Minotaur.watch( app.router.editorView.settings )
document.body.classList.remove("dragging")
+ selected_dot = null
}
}
diff --git a/public/assets/javascripts/rectangles/engine/scenery/sound.js b/public/assets/javascripts/rectangles/engine/scenery/sound.js
new file mode 100644
index 0000000..5a783d6
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/scenery/sound.js
@@ -0,0 +1,16 @@
+
+Scenery.sound = {}
+Scenery.sound.max_distance = 1500
+Scenery.sound.init = function(){
+ app.tube.on("move", Scenery.sound.move)
+}
+Scenery.sound.move = function(){
+ Scenery.forEach(function(scenery){
+ if ((scenery.type == "video" || scenery.type == "audio")) { // && ! scenery.muted()) {
+ var distance = dist(cam.x, cam.z,
+ scenery.mx.x, scenery.mx.z)
+ var volume = 1 - (clamp( distance, 0, Scenery.sound.max_distance ) / Scenery.sound.max_distance)
+ scenery.setVolume(volume)
+ }
+ })
+}
diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js
index 2dbae48..e3b9b4d 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js
@@ -28,32 +28,119 @@ Scenery.types.base = Fiber.extend(function(base){
this.dimensions = this.naturalDimensions.clone().mul(this.scale)
},
+ place: function(opt){
+ if (opt.data) {
+ if (opt.wall) {
+ var position = opt.wall.mxToPosition(opt.data.position)
+ opt.index = opt.wall.surface.index_for_x( position.a, 0 )
+ }
+ this.set_wall(opt)
+ this.deserialize(opt.data)
+ }
+ else {
+ this.set_wall(opt)
+ if (this.wall && ! this.bounds) {
+ this.find_minimum_scale(opt)
+ if (! this.bounds) return
+ }
+
+ this.recenter()
+ if (opt.position) {
+ this.translateTo(opt.position)
+ }
+ var mx_position = this.wall.positionToMx( this.position, this.dimensions )
+ this.mx.move(mx_position)
+ }
+ },
+
+ find_minimum_scale: function(opt){
+ var bounds = this.wall.surface.bounds_at_index_with_dimensions(opt.index || 0, new vec2(50, 50))
+ var scale = 1
+ if (! bounds || bounds.width() < 50 || bounds.height < 50) return
+ if (this.naturalDimensions.a > bounds.width()) {
+ scale = bounds.width() / (this.naturalDimensions.a + 10)
+ }
+ if (this.naturalDimensions.b > bounds.height()) {
+ scale = Math.min(scale, bounds.height() / (this.naturalDimensions.b + 10))
+ }
+ this.set_scale(scale)
+ this.set_wall(opt)
+ },
+
recenter: function () {
if (! this.bounds) return
var center = this.bounds.center()
center.a -= this.dimensions.a / 2
center.b -= this.dimensions.b / 2
- var mx_position = this.wall.positionToMx( center, this.dimensions )
- this.mx.move(mx_position)
this.position.assign(center)
},
+ translateTo: function (position){
+ var flipX = this.wall.side & (FRONT | RIGHT)
+ var delta = position.clone().subVec(this.position)
+ delta.a -= this.dimensions.a/2
+ delta.b -= this.dimensions.b/2
+
+ if (flipX) { delta.a *= -1 }
+
+ var new_bounds = this.wall.surface.translate( this.bounds, this.dimensions, this.position, delta )
+
+ this.position.b += delta.b
+
+ switch (this.wall.side) {
+ case FRONT:
+ case BACK:
+ this.position.a += delta.a * cos(this.wall.rotationY)
+ break
+ case LEFT:
+ case RIGHT:
+ this.position.a += delta.a * sin(this.wall.rotationY)
+ break
+ }
+ },
+
bind: function(){
this.move.bind()
- $(this.mx.el).bind({
- mouseenter: this.enter,
- mouseleave: this.leave,
- })
+// $(this.mx.el).bind({
+// mouseenter: this.enter,
+// mouseleave: this.leave,
+// })
},
unbind: function(){
this.move.unbind()
- $(this.mx.el).unbind({
- mouseenter: this.enter,
- mouseleave: this.leave,
- })
+// $(this.mx.el).unbind({
+// mouseenter: this.enter,
+// mouseleave: this.leave,
+// })
},
+ remove: function(){
+ if (this.removed) return
+ this.removed = true
+
+ UndoStack.push({
+ type: 'destroy-scenery',
+ undo: this.serialize(),
+ redo: { id: this.id },
+ })
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+
+ Scenery.remove(this.id)
+
+ Scenery.resize.hide()
+ if (app.controller.mediaEditor) {
+ app.controller.mediaEditor.tainted = false
+ app.controller.mediaEditor.hide()
+ }
+ if (app.controller.textEditor) {
+ app.controller.textEditor.tainted = false
+ app.controller.textEditor.hide()
+ }
+ },
+
destroy: function(){
this.unbind()
scene.remove(this.mx)
@@ -70,17 +157,17 @@ Scenery.types.base = Fiber.extend(function(base){
},
enter: function(e){
- if (editor.permissions.resize) {
- Scenery.resize.show(this)
- Scenery.hovering = true
- }
+// if (editor.permissions.resize) {
+// Scenery.resize.show(this)
+// Scenery.hovering = true
+// }
},
leave: function(e){
- if (editor.permissions.resize) {
- Scenery.resize.defer_hide(this)
- Scenery.hovering = false
- }
+// if (editor.permissions.resize) {
+// Scenery.resize.defer_hide(this)
+// Scenery.hovering = false
+// }
},
serialize: function(){
diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/audio.js b/public/assets/javascripts/rectangles/engine/scenery/types/audio.js
new file mode 100644
index 0000000..fdd221d
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/scenery/types/audio.js
@@ -0,0 +1,77 @@
+
+Scenery.types.audio = Scenery.types.base.extend(function(base){
+
+ var exports = {
+
+ type: 'audio',
+
+ init: function(opt){
+
+ opt.scale = 1.0
+
+ base.init.call(this, opt)
+
+ this.build()
+ this.bind()
+ this.place(opt)
+ },
+
+ build: function(){
+ this.mx = new MX.Soundcloud({
+ scale: this.scale,
+ media: this.media,
+ y: this.scale * this.media.height/2,
+ backface: false,
+ })
+ scene.add( this.mx )
+ this.mx.load()
+ },
+
+ serialize: function(){
+ var data = base.serialize.call(this)
+ return data
+ },
+
+ deserialize: function(data){
+ this.mx.move(data.position)
+ this.mx.ops.width = data.dimensions.a
+ this.mx.ops.height = data.dimensions.b
+ this.dimensions.deserialize(data.dimensions)
+ },
+
+ setVolume: function(n){
+ this.mx.setVolume(n)
+ },
+
+ play: function(){
+ this.mx.play()
+ },
+
+ pause: function(){
+ this.mx.pause()
+ },
+
+ toggle: function(){
+ this.mx.toggle()
+ },
+
+ paused: function(){
+ return this.mx.paused
+ },
+
+ muted: function(){
+ return this.mx.muted
+ },
+
+ seek: function(n){
+ this.mx.seek(n)
+ },
+
+ setLoop: function(shouldLoop){
+ this.mx.setLoop(shouldLoop)
+ },
+
+ }
+
+ return exports
+})
diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/image.js b/public/assets/javascripts/rectangles/engine/scenery/types/image.js
index d2fa3ab..0e5e77c 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/types/image.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/types/image.js
@@ -3,27 +3,17 @@ Scenery.types.image = Scenery.types.base.extend(function(base){
var exports = {
+ type: 'image',
+
init: function(opt){
- opt.scale = opt.scale || (opt.data && opt.data.scale) || 300 / max(300, opt.media.width)
+ opt.scale = opt.scale || (opt.data && opt.data.scale) || DEFAULT_PICTURE_WIDTH / max(DEFAULT_PICTURE_WIDTH, opt.media.width)
base.init.call(this, opt)
this.build()
this.bind()
-
- if (opt.data) {
- if (opt.wall) {
- var position = opt.wall.mxToPosition(opt.data.position)
- opt.index = opt.wall.surface.index_for_x( position.a, 0 )
- }
- this.set_wall(opt)
- this.deserialize(opt.data)
- }
- else {
- this.set_wall(opt)
- this.bounds && this.recenter()
- }
+ this.place(opt)
},
build: function(){
@@ -46,6 +36,7 @@ Scenery.types.image = Scenery.types.base.extend(function(base){
this.mx.move(data.position)
this.mx.ops.width = data.dimensions.a
this.mx.ops.height = data.dimensions.b
+ this.dimensions.deserialize(data.dimensions)
},
}
diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/text.js b/public/assets/javascripts/rectangles/engine/scenery/types/text.js
new file mode 100644
index 0000000..6e11da2
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/scenery/types/text.js
@@ -0,0 +1,58 @@
+
+Scenery.types.text = Scenery.types.base.extend(function(base){
+
+ var exports = {
+
+ type: 'text',
+
+ init: function(opt){
+
+ opt.scale = 0.5
+
+ base.init.call(this, opt)
+
+ this.build()
+ this.bind()
+ this.place(opt)
+ },
+
+ build: function(){
+ this.mx = new MX.Text({
+ scale: this.scale,
+ media: this.media,
+ y: this.scale * this.media.height/2,
+ backface: false,
+ })
+ scene.add( this.mx )
+ },
+
+ setText: function(text){
+ this.media.description = text
+ this.mx.setText( text )
+ },
+
+ setFont: function(style){
+ for (var i in style) {
+ if (style.hasOwnProperty(i)) {
+ this.media.font[i] = style[i]
+ }
+ }
+ this.mx.setFont(this.media.font)
+ },
+
+ serialize: function(){
+ var data = base.serialize.call(this)
+ return data
+ },
+
+ deserialize: function(data){
+ this.mx.move(data.position)
+ this.mx.ops.width = data.dimensions.a
+ this.mx.ops.height = data.dimensions.b
+ this.dimensions.deserialize(data.dimensions)
+ },
+
+ }
+
+ return exports
+})
diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/video.js b/public/assets/javascripts/rectangles/engine/scenery/types/video.js
index ef25d8d..163e19e 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/types/video.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/types/video.js
@@ -2,27 +2,18 @@
Scenery.types.video = Scenery.types.base.extend(function(base){
var exports = {
+
+ type: 'video',
init: function(opt){
- opt.scale = opt.scale || 300 / max(300, opt.media.width)
-
+
+ opt.scale = opt.scale || (opt.data && opt.data.scale) || DEFAULT_PICTURE_WIDTH / max(DEFAULT_PICTURE_WIDTH, opt.media.width)
+
base.init.call(this, opt)
this.build()
this.bind()
-
- if (opt.data) {
- if (opt.wall) {
- var position = opt.wall.mxToPosition(opt.data.position)
- opt.index = opt.wall.surface.index_for_x( position.a, 0 )
- }
- this.set_wall(opt)
- this.deserialize(opt.data)
- }
- else {
- this.set_wall(opt)
- this.bounds && this.recenter()
- }
+ this.place(opt)
},
build: function(){
@@ -47,7 +38,8 @@ Scenery.types.video = Scenery.types.base.extend(function(base){
backface: false,
})
scene.add(this.mx)
- this.mx.load()
+
+ this.mx.load()
},
play: function(){
@@ -99,6 +91,14 @@ Scenery.types.video = Scenery.types.base.extend(function(base){
}
},
+ unmute: function(){
+ this.mx.unmute()
+ },
+
+ setVolume: function(n){
+ this.mx.setVolume(n)
+ },
+
serialize: function(){
var data = base.serialize.call(this)
return data
@@ -106,6 +106,9 @@ Scenery.types.video = Scenery.types.base.extend(function(base){
deserialize: function(data){
this.mx.move(data.position)
+ this.mx.ops.width = data.dimensions.a
+ this.mx.ops.height = data.dimensions.b
+ this.dimensions.deserialize(data.dimensions)
},
}
diff --git a/public/assets/javascripts/rectangles/engine/scenery/undo.js b/public/assets/javascripts/rectangles/engine/scenery/undo.js
index e5624a0..b976ea2 100644
--- a/public/assets/javascripts/rectangles/engine/scenery/undo.js
+++ b/public/assets/javascripts/rectangles/engine/scenery/undo.js
@@ -4,12 +4,14 @@
type: "create-scenery",
undo: function(state){
Scenery.remove(state.id)
+ Scenery.resize.hide()
// TODO: watch individual scenery object here
Minotaur.watch( app.router.editorView.settings )
},
redo: function(state){
- Scenery.deserialize([ state ])
+ var scenery = Scenery.deserialize([ state ])
+ Scenery.resize.show( scenery )
// TODO: watch individual scenery object here
Minotaur.watch( app.router.editorView.settings )
@@ -19,8 +21,10 @@
type: "update-scenery",
undo: function(state){
var scenery = Scenery.find(state.id)
+ var wall = Walls.find( state.wall_id )
+
scenery.deserialize(state)
- scenery.set_wall(Walls.find( state.wall_id ))
+ scenery.set_wall({ wall: wall })
if (editor.permissions.resize) {
Scenery.resize.show(scenery)
@@ -31,13 +35,15 @@
},
redo: function(state){
var scenery = Scenery.find(state.id)
+ var wall = Walls.find( state.wall_id )
+
scenery.deserialize(state)
- scenery.set_wall(Walls.find( state.wall_id ))
+ scenery.set_wall({ wall: wall })
if (editor.permissions.resize) {
Scenery.resize.show(scenery)
- Scenery.resize.rotate_dots()
Scenery.resize.move_dots()
+ Scenery.resize.rotate_dots()
}
// TODO: watch individual scenery object here
@@ -47,12 +53,14 @@
{
type: "destroy-scenery",
undo: function(state){
- Scenery.deserialize([ state ])
+ var scenery = Scenery.deserialize([ state ])
+ Scenery.resize.show( scenery )
// TODO: watch individual scenery object here
Minotaur.watch( app.router.editorView.settings )
},
redo: function(state){
+ Scenery.resize.hide()
Scenery.remove(state.id)
// TODO: watch individual scenery object here
@@ -66,11 +74,11 @@
type: "create-room",
undo: function(room){
Rooms.remove(room)
- Rooms.clipper.update()
+ Rooms.rebuild()
},
redo: function(room){
Rooms.add(new Room(room))
- Rooms.clipper.update()
+ Rooms.rebuild()
app.tube("builder-pick-room", room)
},
},
@@ -80,14 +88,14 @@
var room = Rooms.list[state.id]
room.rect.assign( state.rect )
room.height = state.height
- Rooms.clipper.update()
+ Rooms.rebuild()
app.tube("builder-pick-room", room)
},
redo: function(state){
var room = Rooms.list[state.id]
room.rect.assign( state.rect )
room.height = state.height
- Rooms.clipper.update()
+ Rooms.rebuild()
app.tube("builder-pick-room", room)
},
},
@@ -95,12 +103,22 @@
type: "destroy-room",
undo: function(room){
Rooms.add(new Room(room))
- Rooms.clipper.update()
+ Rooms.rebuild()
app.tube("builder-pick-room", room)
},
redo: function(room){
Rooms.remove(room)
- Rooms.clipper.update()
+ Rooms.rebuild()
+ },
+ },
+
+ {
+ type: "update-rooms-height",
+ undo: function(state){
+ var rooms = Rooms.values()
+ rooms.forEach(function(room){
+ room.height = state
+ })
},
},
@@ -111,7 +129,32 @@
undo: function(state){
var wall = Walls.lookup[state.id]
wall.deserialize(state)
-
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+ {
+ type: "update-all-wallpaper",
+ undo: function(state){
+ Walls.deserialize(state)
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+ {
+ type: "choose-preset",
+ undo: function(state){
+ app.controller.colorControl.load(state.colors)
+ Walls.deserialize(state.walls)
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ redo: function(state){
+ app.controller.presets.loadByName(state)
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+ {
+ type: "choose-another-preset",
+ undo: function(state){
+ app.controller.presets.loadByName(state)
Minotaur.watch( app.router.editorView.settings )
},
},
@@ -119,11 +162,103 @@
type: "update-colors",
undo: function(state){
Walls.setColor[ state.mode ]( state.rgb )
- app.router.editorView.lightControl.setSwatchColor( state.mode, state.rgb )
+ app.router.editorView.colorControl.setSwatchColor( state.mode, state.rgb )
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+ {
+ type: "randomize-scenery",
+ undo: function(state){
+ state.added.forEach(function(_scenery){
+ Scenery.remove(_scenery.id)
+ })
+ var scenery_list = Scenery.deserialize(state.removed)
+ scenery_list.forEach(function(scenery){
+ scenery.was_randomly_placed = true
+ })
+ Scenery.resize.hide()
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ redo: function(state){
+ state.removed.forEach(function(_scenery){
+ Scenery.remove(_scenery.id)
+ })
+ var scenery_list = Scenery.deserialize(state.added)
+ scenery_list.forEach(function(scenery){
+ scenery.was_randomly_placed = true
+ })
+
+ // TODO: watch individual scenery object here
Minotaur.watch( app.router.editorView.settings )
},
},
+ //
+ {
+ type: "create-sculpture",
+ undo: function(state){
+ Sculpture.remove(state.id)
+ Sculpture.resize.hide()
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ redo: function(state){
+ var scenery = Sculpture.deserialize([ state ])
+ Sculpture.resize.show( sculpture )
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+ {
+ type: "update-sculpture",
+ undo: function(state){
+ var sculpture = Sculpture.find(state.id)
+
+ sculpture.deserialize(state)
+
+ if (editor.permissions.resize) {
+ Sculpture.resize.show(sculpture)
+ }
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ redo: function(state){
+ var sculpture = Sculpture.find(state.id)
+
+ sculpture.deserialize(state)
+
+ if (editor.permissions.resize) {
+ Sculpture.resize.show(sculpture)
+ Sculpture.resize.move_dots()
+ Sculpture.resize.rotate_dots()
+ }
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+ {
+ type: "destroy-sculpture",
+ undo: function(state){
+ var sculpture = Sculpture.deserialize([ state ])
+ Sculpture.resize.show( sculpture )
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ redo: function(state){
+ Sculpture.resize.hide()
+ Sculpture.remove(state.id)
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+ },
+
])
})()
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js
new file mode 100644
index 0000000..888b925
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js
@@ -0,0 +1,105 @@
+
+var Sculpture = new function(){
+
+ var base = this;
+
+ base.list = {}
+
+ base.mouse = new mouse ({ use_offset: false, mousedownUsesCapture: true })
+
+ base.init = function(){
+ app.on("move", base.updateBillboards)
+ base.resize.init()
+ }
+
+ base.updateBillboards = function(){
+ base.forEach(function(sculpture){
+ if (sculpture.billboard) {
+ sculpture.mx.rotationY = cam.rotationY
+ }
+ })
+ if (Sculpture.resize.obj && Sculpture.resize.obj.billboard) {
+ Sculpture.resize.move_dots()
+ }
+ }
+
+ base.add = function(opt){
+ var sculpture
+ switch (opt.media.type) {
+ case 'image':
+ sculpture = new Sculpture.types.image (opt)
+ break
+ }
+ base.list[sculpture.id] = sculpture
+ return sculpture
+ }
+
+ base.addNext = function(opt){
+ opt.newMedia = true
+ opt.media = Scenery.nextMedia
+ var sculpture = base.add(opt)
+
+ // test if sculpture was placed here
+ if (! sculpture) {
+ return null
+ }
+ else {
+ Scenery.nextMedia = null
+ return sculpture
+ }
+ }
+
+ base.find = function(id){
+ return base.list[id] || null
+ }
+
+ base.remove = function(id){
+ var scene_media = base.list[id]
+ delete base.list[id]
+ scene_media && scene_media.destroy()
+ }
+
+ base.removeAll = function(){
+ base.forEach(function(scene_media){
+ base.remove(scene_media.id)
+ })
+ }
+
+ base.uid = new UidGenerator(base.list)
+
+ base.forEach = function(f){
+ return base.values().forEach(f)
+ }
+
+ base.map = function(f){
+ return base.values().map(f)
+ }
+
+ base.values = function(){
+ return _.values(base.list)
+ }
+
+ base.serialize = function(){
+ var sculptures = base.map(function(sculpture){
+ return sculpture.serialize()
+ })
+ return sculptures
+ }
+
+ base.deserialize = function(sculpture_data){
+ var added = []
+ sculpture_data.forEach(function(data){
+ var scene_media = base.add({
+ id: data.id,
+ data: data,
+ media: data.media,
+ })
+ added.push(scene_media)
+ })
+ return added
+ }
+
+ return base
+}
+
+Sculpture.types = {}
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/move.js b/public/assets/javascripts/rectangles/engine/sculpture/move.js
new file mode 100644
index 0000000..0cbeccd
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/move.js
@@ -0,0 +1,111 @@
+
+Sculpture.move = function(base){
+
+ var x, y, z, position, dimension, bounds
+ var rotationY
+ var dragging = false, altPressed = false, shiftPressed = false, moved = false
+ var oldState
+ var height, width
+
+ this.bind = function(){
+ Sculpture.mouse.bind_el(base.mx.el)
+ Sculpture.mouse.on("down", down)
+ Sculpture.mouse.on("drag", drag)
+ Sculpture.mouse.on("up", up)
+ }
+
+ this.unbind = function(){
+ base.focused = false
+ Sculpture.mouse.unbind_el(base.mx.el)
+ Sculpture.mouse.off("down", down)
+ Sculpture.mouse.off("drag", drag)
+ Sculpture.mouse.off("up", up)
+ }
+
+ function down (e, cursor){
+ if (e.target != base.mx.el && (e.target != base.mx.overlay)) return;
+ if (editor.permissions.destroy) {
+ base.remove()
+ return
+ }
+
+ // load the modal
+ app.controller.pick(base)
+
+ if (! base.focused) {
+ e.clickAccepted = false
+ base.focused = true
+ return
+ }
+ if (! (editor.permissions.move || editor.permissions.resize) ) {
+ e.clickAccepted = false
+ return
+ }
+ altPressed = (e.altKey && ! base.billboard)
+ shiftPressed = e.shiftKey
+ dragging = true
+ moved = false
+ x = base.mx.x
+ y = base.mx.y
+ z = base.mx.z
+ rotationY = base.mx.rotationY
+ height = base.mx.height * base.mx.scale
+
+ bounds = base.bounds
+ dimension = base.dimensions
+
+ oldState = base.serialize()
+ document.body.classList.add("dragging")
+ }
+
+ function drag (e, cursor){
+ if (! dragging) return
+
+ moved = true
+
+ var delta = cursor.delta()
+ delta.mul( cursor_amp ) // TODO: this should be proportional to your distance from the wall
+ delta.b *= -1
+
+ // here we need to move the element based on the XY coords, as
+ // base.mx.y = position.b + delta.b + dimension.b / 2
+ if (shiftPressed) {
+ base.mx.y = clamp( y + delta.b, height/2 + sculpture_distance_from_floor, Infinity )
+ }
+ else if (altPressed) {
+ base.mx.rotationY = mod( rotationY + delta.a / (window.innerWidth / 2) , TWO_PI )
+ Sculpture.resize.move_dots()
+ }
+ else {
+ base.mx.x = x + delta.a * cos(cam.rotationY) - delta.b * sin(cam.rotationY)
+ base.mx.z = z + delta.a * sin(cam.rotationY) + delta.b * cos(cam.rotationY)
+ }
+
+ if (editor.permissions.resize) {
+ Sculpture.resize.move_dots()
+ base.updateOutline()
+ }
+ }
+
+ function up (e, cursor){
+ if (! dragging || ! oldState) return
+
+ if (moved) {
+ UndoStack.push({
+ type: 'update-sculpture',
+ undo: oldState,
+ redo: base.serialize(),
+ })
+
+ // TODO: watch individual sculpture object here
+ Minotaur.watch( app.router.editorView.settings )
+ }
+
+ dragging = moved = false
+ oldState = null
+ document.body.classList.remove("dragging")
+ }
+
+ return this
+
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/resize.js b/public/assets/javascripts/rectangles/engine/sculpture/resize.js
new file mode 100644
index 0000000..5f21d66
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/resize.js
@@ -0,0 +1,208 @@
+Sculpture.resize = new function(){
+
+ var base = this
+
+ var obj
+ var x, y, z, bounds
+ var dragging = false
+ var naturalDimension, naturalDimensionCopy, dimension, position, scale
+ var oldState
+ var rotationY
+
+ var dots = [], dot, selected_dot
+
+ base.init = function(){
+ base.build()
+ base.bind()
+ }
+
+ // create 9 dots at the corners of the div
+ base.build = function(){
+ [ TOP,
+ TOP_RIGHT,
+ RIGHT,
+ BOTTOM_RIGHT,
+ BOTTOM,
+ BOTTOM_LEFT,
+ LEFT,
+ TOP_LEFT ].forEach(base.build_dot)
+ }
+
+ // generate a dot element
+ base.build_dot = function(side) {
+ var dot = new MX.Object3D('.dot')
+ dot.width = dot.height = dot_side * 2
+ dot.scale = 0.5
+ dot.side = side
+ $(dot.el).on({
+ mouseenter: function(){ base.hovering = true },
+ mouseleave: function(){ base.hovering = false },
+ })
+ dots.push(dot)
+ }
+
+ base.add_dots = function(){
+ dots.forEach(function(dot){
+ scene.add(dot)
+ })
+ }
+
+ // move all the dots to the object's current position
+ base.move_dots = function(){
+ rotationY = obj.mx.rotationY
+
+ var x = obj.mx.x + sin(rotationY) * dot_distance_from_picture
+ var y = obj.mx.y
+ var z = obj.mx.z - cos(rotationY) * dot_distance_from_picture
+
+ dots.forEach(function(dot){
+ base.move_dot(dot, { x: x, y: y, z: z, rotationY: rotationY })
+ })
+ }
+
+ // move a dot .. to the initial position of the image
+ base.move_dot = function(dot, pos){
+ if (dot.side & TOP) {
+ pos.y += obj.dimensions.b / 2
+ }
+ if (dot.side & BOTTOM) {
+ pos.y -= obj.dimensions.b / 2
+ }
+ if (dot.side & LEFT) {
+ pos.x -= cos(rotationY) * (obj.dimensions.a) / 2
+ pos.z -= sin(rotationY) * (obj.dimensions.a) / 2
+ }
+ if (dot.side & RIGHT) {
+ pos.x += cos(rotationY) * (obj.dimensions.a) / 2
+ pos.z += sin(rotationY) * (obj.dimensions.a) / 2
+ }
+ dot.move(pos)
+ }
+
+ // pick a new object to focus on and show the dots
+ base.show = function(new_object) {
+ // if (obj === new_object) return
+ if (! new_object) return
+ base.obj = obj = new_object
+ base.add_dots()
+ base.move_dots()
+ }
+
+ // dismiss the dots on blur
+ var dotsHideTimeout;
+ base.defer_hide = function(){
+ clearTimeout(dotsHideTimeout)
+
+ dotsHideTimeout = setTimeout(function(){
+ if (Scenery.hovering || Scenery.resize.hovering || Scenery.mouse.down) return
+ Scenery.resize.hide()
+ }, dot_hide_delay)
+ }
+
+ base.hide = function () {
+ if (! obj) return
+ base.obj = obj = null
+ dots.forEach(function(dot){
+ scene.remove(dot)
+ })
+ }
+
+ base.bind = function(){
+ dots.forEach(function(dot){
+ Sculpture.mouse.bind_el(dot.el)
+ })
+ Sculpture.mouse.on("down", down)
+ Sculpture.mouse.on("drag", drag)
+ Sculpture.mouse.on("up", up)
+ }
+
+ base.unbind = function(){
+ dots.forEach(function(dot){
+ Sculpture.mouse.unbind_el(dot.el)
+ })
+ Sculpture.mouse.off("down", down)
+ Sculpture.mouse.off("drag", drag)
+ Sculpture.mouse.off("up", up)
+ }
+
+ function down (e, cursor){
+ var selection = dots.filter(function(dot){return e.target == dot.el})
+ if (! selection.length) return
+
+ selected_dot = selection[0]
+ dragging = true
+
+ naturalDimension = obj.naturalDimensions
+ dimension = obj.dimensions
+ position = new vec3(obj.mx.x, obj.mx.y, obj.mx.z)
+ oldState = obj.serialize()
+
+ if (obj.type == "text") {
+ naturalDimensionCopy = naturalDimension.clone()
+ positionCopy = position.clone()
+ }
+
+ document.body.classList.add("dragging")
+ }
+
+ function drag (e, cursor){
+ if (! dragging) return
+
+ var x_sign = selected_dot.side & LEFT ? -1 : selected_dot.side & RIGHT ? 1 : 0
+ var y_sign = selected_dot.side & TOP ? -1 : selected_dot.side & BOTTOM ? 1 : 0
+ var width = cursor.x.magnitude()
+ var height = cursor.y.magnitude()
+ var mag = cursor.magnitude()
+
+ if (abs(width) > abs(height)) {
+ mag = x_sign * mag * sign(width)
+ }
+ else {
+ mag = y_sign * mag * sign(height)
+ }
+
+ if (obj.type == "text") {
+ obj.mx.width = obj.media.width = naturalDimension.a = naturalDimensionCopy.a + (mag * 2)
+ obj.mx.height = obj.media.height = naturalDimension.b = naturalDimensionCopy.b + (mag * 2)
+ dimension.a = naturalDimension.a * obj.scale
+ dimension.b = naturalDimension.b * obj.scale
+ }
+ else {
+ obj.set_scale( ( dimension.a + mag ) / naturalDimension.a )
+ }
+
+ if (selected_dot.side & LEFT_RIGHT) {
+ obj.mx.x = position.a + cos(rotationY) * mag/2 * (x_sign)
+ obj.mx.z = position.c + sin(rotationY) * mag/2 * (x_sign)
+ }
+ if (selected_dot.side & TOP_BOTTOM) {
+ obj.mx.y = position.b - mag/2 * y_sign
+ }
+
+ base.move_dots()
+ obj.updateOutline()
+
+ app.controller.sculptureEditor.setDimensions()
+ }
+
+ function up (e, cursor){
+ if (! dragging) return
+ dragging = false
+ if (! editor.permissions.resize) { return }
+
+ obj.scale = obj.mx.ops.scale = obj.mx.scale
+ obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale)
+
+ UndoStack.push({
+ type: 'update-sculpture',
+ undo: oldState,
+ redo: obj.serialize(),
+ })
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+
+ document.body.classList.remove("dragging")
+ selected_dot = null
+ }
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js
new file mode 100644
index 0000000..2f593e8
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js
@@ -0,0 +1,176 @@
+Sculpture.types.base = Fiber.extend(function(base){
+
+ var exports = {
+
+ init: function(opt){
+ this.id = opt.id || Sculpture.uid("sculpture")
+ // this.move = new Sculpture.move (this)
+ this.media = opt.media
+ this.naturalDimensions = new vec3(this.media.width, this.media.height, this.media.width)
+ this.dimensions = new vec3(this.media.width, this.media.height, this.media.width)
+
+ this.move = new Sculpture.move (this)
+ this.billboard = true
+ this.backface = true
+
+ this.set_scale( opt.scale || this.media.scale || 1.0 )
+ this.position = new vec2(0,0)
+
+ this.isSculpture = true
+ },
+
+ set_scale: function(scale){
+ this.scale = scale || 1.0
+ if (this.mx) {
+ this.mx.scale = this.mx.ops.scale = this.scale
+ }
+ this.dimensions = this.naturalDimensions.clone().mul(this.scale)
+ },
+ set_depth: function(depth){
+ console.log(this.dimensions.c, this.naturalDimensions.c, depth)
+ this.dimensions.c = depth
+ this.naturalDimensions.c = depth / this.scale
+ },
+
+ place: function(opt){
+ if (opt.data) {
+ this.deserialize(opt.data)
+ }
+ else {
+ this.mx.move(opt.position)
+ }
+ },
+
+ bind: function(){
+ this.move.bind()
+ },
+
+ unbind: function(){
+ this.move.unbind()
+ },
+
+ setOutline: function(val){
+ this.outline = val
+ if (val && ! this.outlineEl) {
+ this.buildOutline()
+ }
+ this.outlineEl.el.style.display = val ? "block" : "none"
+ },
+ setOutlineColor: function(val){
+ this.outlineColor = val
+ if (this.outlineEl) {
+ this.outlineColor = this.outlineEl.el.style.borderColor = val
+ }
+ },
+ setBillboard: function(val){
+ this.billboard = val
+ if (this.billboard) {
+ this.mx.el.classList.add("backface-hidden")
+ this.mx.el.classList.remove("backface-visible")
+ this.mx.rotationY = cam.rotationY
+ }
+ else {
+ this.mx.el.classList.add("backface-visible")
+ this.mx.el.classList.remove("backface-hidden")
+ this.mx.rotationY = quantize(cam.rotationY, PI/2)
+ }
+ Sculpture.resize.move_dots()
+ },
+
+ buildOutline: function(){
+ this.outlineEl = new MX.Object3D(".mx-outline")
+ this.outlineEl.width = this.naturalDimensions.a
+ this.outlineEl.height = this.naturalDimensions.c
+ this.outlineEl.scale = this.mx.scale
+ this.outlineEl.rotationX = -PI/2
+ this.outlineEl.x = this.mx.x
+ this.outlineEl.y = sculpture_distance_from_floor
+ this.outlineEl.z = this.mx.z
+ this.outlineEl.el.style.borderColor = this.outlineColor || "#000000"
+ scene.add(this.outlineEl)
+ },
+ updateOutline: function(){
+ if (! this.outline) { return }
+ if (! this.outlineEl) {
+ this.buildOutline()
+ }
+ this.outlineEl.x = this.mx.x
+ this.outlineEl.y = sculpture_distance_from_floor
+ this.outlineEl.z = this.mx.z
+ this.outlineEl.width = this.naturalDimensions.a
+ this.outlineEl.height = this.naturalDimensions.c
+
+ this.outlineEl.scale = this.mx.scale
+ },
+
+ remove: function(){
+ if (this.removed) return
+ this.removed = true
+
+ UndoStack.push({
+ type: 'destroy-sculpture',
+ undo: this.serialize(),
+ redo: { id: this.id },
+ })
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+
+ Sculpture.remove(this.id)
+
+ Sculpture.resize.hide()
+ if (app.controller.sculptureEditor) {
+ app.controller.sculptureEditor.tainted = false
+ app.controller.sculptureEditor.hide()
+ }
+ },
+
+ destroy: function(){
+ this.unbind()
+ scene.remove(this.mx)
+ this.mx.media = null
+ this.mx.ops = null
+ this.mx = null
+ this.move = null
+ this.media = null
+ this.dimensions = null
+ this.naturalDimensions = null
+ this.wall = null
+ this.bounds = null
+ this.center = null
+ },
+
+ serialize: function(){
+ var data = {
+ id: this.id,
+ dimensions: this.dimensions.serialize(),
+ position: app.position(this.mx),
+ scale: this.scale,
+ media: this.media,
+ billboard: this.billboard,
+ outline: this.outline,
+ outlineColor: this.outlineColor || "#000000",
+ backface: this.backface,
+ }
+ return data
+ },
+
+ deserialize: function(data){
+ this.mx.move(data.position)
+ this.mx.ops.width = data.dimensions.a
+ this.mx.ops.height = data.dimensions.b
+ this.billboard = data.billboard
+ this.outline = data.outline
+ this.outlineColor = data.outlineColor || "#000000"
+ this.backface = data.backface
+ if (! this.backface) this.mx.el.classList.remove("backface-visible")
+ this.dimensions.deserialize(data.dimensions)
+ if (this.outline) {
+ this.buildOutline()
+ }
+ },
+ }
+
+ return exports
+
+})
diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/image.js b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js
new file mode 100644
index 0000000..1a53f5b
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js
@@ -0,0 +1,38 @@
+
+Sculpture.types.image = Sculpture.types.base.extend(function(base){
+
+ var exports = {
+
+ type: 'image',
+
+ init: function(opt){
+
+ opt.scale = opt.scale || (opt.data && opt.data.scale) || DEFAULT_PICTURE_WIDTH / max(DEFAULT_PICTURE_WIDTH, opt.media.width)
+
+ base.init.call(this, opt)
+
+ this.build(opt)
+ this.bind()
+ this.place(opt)
+ },
+
+ build: function(opt){
+ this.mx = new MX.Image({
+ src: this.media.url,
+ scale: this.scale,
+ media: this.media,
+ backface: true,
+ })
+
+ if (opt.position) {
+ opt.position.y = opt.position.y || this.scale * this.media.height/2 + sculpture_distance_from_floor
+ opt.position.rotationY = opt.position.rotationY || scene.camera.rotationY
+ }
+
+ scene.add( this.mx )
+ },
+
+ }
+
+ return exports
+})
diff --git a/public/assets/javascripts/rectangles/engine/shapes/ortho.js b/public/assets/javascripts/rectangles/engine/shapes/ortho.js
new file mode 100644
index 0000000..163f646
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/ortho.js
@@ -0,0 +1,66 @@
+// An OrthoPolyline is a Polyline where all angles are 90 degrees.
+
+if (! ('window' in this) ) {
+ var Polyline = require("./polyline.js")
+}
+
+var OrthoPolyline = Polyline.extend(function(base){
+ var exports = {}
+ exports.type = function(){
+ return "ortho"
+ }
+ exports.instantiate = function(){
+ return new OrthoPolyline
+ }
+ exports.canCloseWith = function(p){
+ return (this.points.length > 2 && this.points[0].distanceTo( p ) < 10/map.zoom)
+ }
+ exports.draw = function(ctx, fillStyle, strokeStyle){
+ var points = this.points
+ if (! points.length) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(this.points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = fillStyle
+ ctx.strokeStyle = strokeStyle
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ strokeStyle && ctx.stroke()
+ if (! map.ui.placing || this.closed) {
+ fillStyle && ctx.fill()
+ }
+ }
+ }
+ exports.translateSegment = function(src, dest, dx, dy) {
+ if (src[0].a == src[1].a) {
+ dest[0].a = src[0].a + dx
+ dest[1].a = src[1].a + dx
+ if (src.length == 3) {
+ dest[2].a = src[2].a + dx
+ }
+ }
+ else {
+ dest[0].b = src[0].b + dy
+ dest[1].b = src[1].b + dy
+ if (src.length == 3) {
+ dest[2].b = src[2].b + dy
+ }
+ }
+ }
+ exports.close = function(){
+ this.points[this.points.length] = this.points[0]
+ this.closed = true
+ }
+ return exports
+})
+
+
+if (! ('window' in this) ) {
+ module.exports = OrthoPolyline
+}
diff --git a/public/assets/javascripts/rectangles/engine/shapes/polyline.js b/public/assets/javascripts/rectangles/engine/shapes/polyline.js
new file mode 100644
index 0000000..b2cd92f
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/polyline.js
@@ -0,0 +1,212 @@
+// A Polyline is a set of points inputted by the user using the V2 editor to trace a blueprint.
+// Additionally, it manages a set of MX objects which correspond to the walls in 3D.
+// In this way, it attempts to bridge the 2D (canvas, imperative) and 3D (css, declarative) views.
+
+if (! ('window' in this) ) {
+ var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js")
+ var vec2 = require("../../models/vec2")
+}
+
+var Polyline = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(){
+ this.points = []
+ this.mx_points = []
+ this.closed = false
+ }
+ exports.type = function(){
+ return "polyline"
+ }
+ exports.instantiate = function(){
+ return new Polyline
+ }
+ exports.add = function(p){
+ this.points.push( p )
+ this.mx_points.push( new MX.Point(p) )
+ }
+ exports.firstPoint = function(){
+ return this.points[0]
+ }
+ exports.lastPoint = function(){
+ return this.points[this.points.length-1]
+ }
+ exports.canCloseWith = function(p){
+ return (this.points.length > 2 && this.points[0].distanceTo( p ) < 10/map.zoom)
+ }
+ exports.getHeadAtIndex = function(index){
+ if (index == 0) { return null }
+ if (index == this.points.length-1) { return this.clone() }
+ var head = this.instantiate()
+ head.points = this.points.slice(0, index+1)
+ return head
+ }
+ exports.getTailAtIndex = function(index){
+ if (index == this.points.length-1) { return null }
+ if (index == 0) { return this.clone() }
+ var tail = this.instantiate()
+ tail.points = this.points.slice(index, this.points.length)
+ return tail
+ }
+ exports.clone = function(){
+ var clone = this.instantiate()
+ clone.points = this.points.concat()
+ }
+ exports.getSegment = function(segment){
+ var seg = [
+ this.points[segment.head],
+ this.points[segment.tail],
+ ]
+ if (segment.head == 0) {
+ seg.push( this.lastPoint() )
+ }
+ else if (segment.tail == this.points.length-1) {
+ seg.push( this.firstPoint() )
+ }
+ return seg
+ }
+ exports.cloneSegment = function(segment){
+ return this.getSegment(segment).map(function(point){ return point.clone() })
+ }
+ exports.translateSegment = function(src, dest, dx, dy){
+ dest[0].a = src[0].a + dx
+ dest[0].b = src[0].b + dy
+ dest[1].a = src[1].a + dx
+ dest[1].b = src[1].b + dy
+ if (src.length == 3) {
+ dest[2].a = src[2].a + dx
+ dest[2].b = src[2].b + dy
+ }
+ }
+ exports.hasPointNear = function(p){
+ var point
+ for (var i = 0; i < this.points.length; i++){
+ point = this.points[i]
+ if (point.distanceTo( p ) < 10/map.zoom) {
+ return point
+ }
+ }
+ return null
+ }
+ exports.hasEndPointNear = function(p){
+ if (this.closed || ! this.points.length) return null
+ if (this.firstPoint().distanceTo( p ) < 10/map.zoom) {
+ return this.firstPoint()
+ }
+ if (this.lastPoint().distanceTo( p ) < 10/map.zoom) {
+ return this.lastPoint()
+ }
+ return null
+ }
+ exports.hasSegmentNear = function(p, min_dist){
+ var p1, p2, d1, d2, sum, rat
+ var dx, dy, new_x, new_y, x, y, closest_distance = min_dist || Infinity
+ var closest_i = -1
+ var points = this.points
+ var p1, p2 = points[0]
+ for (var i = 1; i < points.length; i++) {
+ p1 = p2
+ p2 = points[i]
+ d1 = p2.a - p1.a
+ d2 = p2.b - p1.b
+ sum = d1*d1 + d2*d2
+ rat = ((p.a - p1.a) * d1 + (p.b - p1.b) * d2) / sum
+ rat = rat < 0 ? 0 : rat < 1 ? rat : 1
+ new_x = p1.a + rat * d1
+ new_y = p1.b + rat * d2
+ dx = new_x - p.a
+ dy = new_y - p.b
+ sum2 = sqrt(dx*dx+dy*dy)
+ if (sum2 < closest_distance) {
+ x = new_x
+ y = new_y
+ closest_distance = sum2
+ closest_i = i
+ }
+ }
+ if (closest_i == -1) return null
+ return {
+ x: x,
+ y: y,
+ distance: closest_distance,
+ head: closest_i-1,
+ tail: closest_i,
+ }
+ }
+ exports.draw = function(ctx, fillStyle, strokeStyle){
+ var points = this.points
+ if (! points.length) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(this.points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = fillStyle
+ ctx.strokeStyle = strokeStyle
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ strokeStyle && ctx.stroke()
+ if (! map.ui.placing || this.closed) {
+ fillStyle && ctx.fill()
+ }
+ }
+ }
+ exports.draw_line = function (ctx, p){
+ var last = this.points[this.points.length-1]
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(last.a, last.b)
+ ctx.lineTo(p.a, p.b)
+ ctx.stroke()
+ }
+ exports.close = function(){
+ this.points[this.points.length] = this.points[0]
+ this.closed = true
+ }
+ exports.build = function(){
+ this.mx_points && this.mx_points.forEach(function(mx){ scene.remove(mx) })
+ this.mx = new MX.Polyline(this)
+ }
+ exports.rebuild = function(){
+ this.mx.rebuild()
+ }
+ exports.getSegments = function(){
+ if (this.points.length == 1) {
+ return []
+ }
+ var segments = []
+ for (var i = 1; i < this.points.length; i++) {
+ segments.push( [ this.points[i-1], this.points[i] ] )
+ }
+ return segments
+ }
+ exports.serialize = function(){
+ return {
+ type: this.type(),
+ closed: this.closed,
+ points: this.points.map(function(point){ return [point.a, point.b] }),
+ }
+ }
+ exports.deserialize = function(data){
+ this.closed = data.closed || false
+ this.points = (data.points || data).map(function(point){ return new vec2(point[0], point[1]) })
+ }
+ exports.reset = function(){
+ this.mx_points.forEach(function(mx){ scene.remove(mx) })
+ this.mx_points.length = 0
+ this.points.length = 0
+ }
+ exports.destroy = function(){
+ this.reset()
+ this.mx && this.mx.destroy()
+ }
+ return exports
+})
+
+if (! ('window' in this) ) {
+ module.exports = Polyline
+}
diff --git a/public/assets/javascripts/rectangles/engine/shapes/regionlist.js b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js
new file mode 100644
index 0000000..8c9e732
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js
@@ -0,0 +1,240 @@
+// This algorithm takes the polylines from ShapeList as input and produces
+// a set of Rooms which can be used by the existing V1 mover and editor.
+
+// The algorithm assumes that
+// 1) all angles are orthogonal
+// 2) all polylines are closed
+
+if (! ('window' in this) ) {
+ var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js")
+ var vec2 = require("../../models/vec2")
+ var Rect = require("../../models/rect")
+ var sort = require("../../util/sort")
+}
+
+var RegionList = (function(){
+
+ var RegionList = {}
+ var regions = RegionList.regions
+
+ // Build a list of regions from the existing shapes.
+ // Operates on all the shapes at once.
+ RegionList.build = function(){
+ var segments = RegionList.getSortedSegments()
+ return RegionList.buildRoomsFromSegments(segments)
+ }
+
+ // Build a list of regions from the individual shapes.
+ // Same, but operates on the shapes individually
+ RegionList.buildByShape = function(){
+ var shapes = RegionList.getSortedSegmentsByShape()
+ var region_lists = shapes.map(function(shape){
+ return RegionList.buildRoomsFromSegments(shape.segments)
+ })
+ var regions = []
+ return regions.concat.apply(regions, region_lists);
+ }
+
+ RegionList.buildRoomsFromSegments = function(segments){
+
+ var rooms = []
+ var seen_rooms = {}
+ var open_segments = []
+
+ var segment, open_segment, x_segment, y_segments, overlapped, seen_segments
+
+ // first pass: generate rooms from the vertical segments only
+ for (var i = 0; i < segments.length; i++) {
+ segment = segments[i]
+ if (! segment.isVertical()) {
+ continue
+ }
+
+ // check all the "open segments" we know about, i.e. rooms where we've only found
+ // the right wall.
+ overlapped = false
+ for (var j = 0; j < open_segments.length; j++) {
+ open_segment = open_segments[j]
+
+ // if these two segments overlap each other, then there is a room between them.
+ if (segment.y.overlaps(open_segment.y)) {
+ overlapped = true
+ open_segments.splice(j--, 1)
+
+ // the X part of the room will be the span between these two vertical segments'
+ // X components. the Y part of the room is the "split" or subdivision between
+ // the two horizontal vectors.
+
+ // the split function is non-commutative,
+ // so we need to call A split B and B split A,
+ // then dedupe the segments we got back..
+ x_segment = new vec2( open_segment.x.a, segment.x.b )
+ y_segments = open_segment.y.split(segment.y, 0, 0)
+
+ seen_segments = {}
+
+ // check each of the splits.. if the two segments overlap, then we definitely
+ // have a room here.
+ y_segments.forEach(function(seg){
+ seen_segments[ seg[0]+"" ] = true
+ var room = new Rect( x_segment, seg[0] )
+
+ if (seen_rooms[ room+"" ]) return
+ seen_rooms[ room+"" ] = true
+
+ room.sides = 0
+
+ rooms.push(room)
+ var new_seg = new Rect( segment.x, seg[0] )
+ open_segments.unshift(new_seg)
+ j++
+ })
+
+ // splitting the other way..
+ y_segments = segment.y.split(open_segment.y, 0, 0)
+ y_segments.forEach(function(seg){
+ if (seen_segments[ seg[0]+"" ]) return;
+ var new_seg = new Rect( segment.x, seg[0] )
+ open_segments.unshift(new_seg)
+ j++
+ })
+ }
+ }
+
+ // if we have overlap, then re-sort the open segments Y-wise
+ // and (again) dedupe..
+ if (overlapped) {
+ open_segments = open_segments.sort(function(a,b){
+ if (a.y.a < b.y.a) { return -1 }
+ if (a.y.a == b.y.a) { return 0 }
+ if (a.y.a > b.y.a) { return 1 }
+ })
+
+ if (open_segments.length < 2) { continue }
+
+ for (var k = 1; k < open_segments.length; k++) {
+ if (open_segments[k-1].y.containsVec(open_segments[k].y)) {
+ open_segments.splice(k--, 1)
+ }
+ else if (open_segments[k-1].y.overlaps(open_segments[k].y)) {
+ open_segments[k].y = open_segments[k].y.clone()
+ open_segments[k].y.a = open_segments[k-1].y.b
+ }
+ }
+ }
+ // if we don't have any overlap, then this is a new open segment.
+ else {
+ open_segments.push(segment)
+ }
+ }
+
+ var splits, splitter
+
+ // second pass: now that we have a bunch of rooms, assign sides to all of them.
+ // sides are used in the "mover" script to do bounds checking.
+ for (var i = 0; i < segments.length; i++) {
+ segment = segments[i]
+ var horizontal = segment.isHorizontal(), vertical = segment.isVertical()
+ for (var r = 0; r < rooms.length; r++){
+ room = rooms[r]
+
+ // vertical segments determine the left and right edges of the room, fairly simply.
+ if (vertical) {
+ if (segment.y.containsVec(room.y)) {
+ if (segment.x.a == room.x.a) {
+ room.sides |= LEFT
+ }
+ if (segment.x.a == room.x.b) {
+ room.sides |= RIGHT
+ }
+ }
+ }
+
+ // horizontal segments determine the front and back edges of the room.
+ if (horizontal) {
+ if (segment.x.containsVec(room.x)) {
+ if (segment.y.a == room.y.a) {
+ room.sides |= FRONT
+ }
+ if (segment.y.a == room.y.b) {
+ room.sides |= BACK
+ }
+ }
+
+ // however, since we did not split on horizontal segments, our rooms may
+ // only have partial overlap with these segments, in which case we need to
+ // split the rooms apart.
+ else if ((segment.y.a == room.y.a || segment.y.a == room.y.b) && room.x.overlaps(segment.x)) {
+
+ // split the room across the segment. preserve whether or not we know the
+ // room borders a segment on the left or right.
+ splits = room.x.split(segment.x, room.sides & LEFT, room.sides & RIGHT)
+ rooms.splice(r--, 1)
+ for (var k = 0; k < splits.length; k++) {
+ splitter = splits[k]
+ var new_room = new Rect( splitter[0], room.y )
+ new_room.sides = splitter[1] | ( room.sides & FRONT_BACK )
+ if (segment.x.overlaps( splitter[0] )) {
+ if (segment.y.a == new_room.y.a) {
+ new_room.sides |= FRONT
+ }
+ if (segment.y.a == new_room.y.b) {
+ new_room.sides |= BACK
+ }
+ }
+ rooms.unshift(new_room)
+ r++
+ }
+ }
+
+ }
+ }
+ }
+
+ return rooms
+ }
+
+ // Gets a list of polylines from the ShapeList and sorts the segments.
+ RegionList.getSortedSegments = function(){
+ // get a list of all segments from these polylines
+ var segments = shapes.getAllSegments()
+
+ segments = segments.map(RegionList.segmentsToRects)
+
+ return sort.rects_by_position(segments)
+ }
+
+ RegionList.getSortedSegmentsByShape = function(){
+ return shapes.getAllShapeSegments().map(function(shape){
+ var segments = shape.map(RegionList.segmentsToRects)
+ return {
+ shape: shape,
+ segments: sort.rects_by_position(segments)
+ }
+ })
+ }
+
+ // re-orient a segment so it's either facing up or right and make it into a rect
+ RegionList.segmentsToRects = function(segment){
+ // vertical
+ if (segment[0].a == segment[1].a) {
+ if (segment[0].b > segment[1].b) {
+ segment.push(segment.shift())
+ }
+ }
+ // horizontal
+ else if (segment[0].b == segment[1].b) {
+ if (segment[0].a > segment[1].a) {
+ segment.push(segment.shift())
+ }
+ }
+ return new Rect( segment[0].a, segment[0].b, segment[1].a, segment[1].b )
+ }
+
+ if (! ('window' in this) ) {
+ module.exports = RegionList
+ }
+
+ return RegionList
+
+})() \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js
new file mode 100644
index 0000000..21beb76
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js
@@ -0,0 +1,124 @@
+// The ShapeList manages the list of polylines which form a V2 layout.
+
+if (! ('window' in this) ) {
+ var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js")
+ var Polyline = require("./polyline.js")
+ var OrthoPolyline = require("./ortho.js")
+}
+
+var ShapeList = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(){
+ this.shapes = []
+ this.workline = null
+ }
+ exports.add = function(shape){
+ this.shapes.push(shape)
+ }
+ exports.remove = function(shape){
+ var index = this.shapes.indexOf(shape)
+ if (index !== -1) {
+ this.shapes.splice(index, 1)
+ }
+ }
+ exports.destroy = function(){
+ this.shapes.forEach(function(shape){
+ shape.destroy()
+ })
+ this.shapes = []
+ }
+ exports.count = function(){
+ return this.shapes.length
+ }
+ exports.removeSegment = function (segment){
+ var shape = segment.shape
+ var head = shape.getHeadAtIndex(segment.head)
+ var tail = shape.getTailAtIndex(segment.tail)
+ this.remove(shape)
+ shape.destroy()
+ if (head) {
+ this.add(head)
+ head.build()
+ }
+ if (tail) {
+ this.add(tail)
+ tail.build()
+ }
+ }
+ exports.findClosestPoint = function (p){
+ var point
+ for (var i = 0; i < this.shapes.length; i++) {
+ point = this.shapes[i].hasPointNear(p)
+ if (point) return { point: point, shape: this.shapes[i] }
+ }
+ return null
+ }
+ exports.findClosestEndPoint = function (p){
+ var point
+ for (var i = 0; i < this.shapes.length; i++) {
+ point = this.shapes[i].hasEndPointNear(p)
+ if (point) return { point: point, shape: this.shapes[i] }
+ }
+ return null
+ }
+ exports.findClosestSegment = function (p){
+ var segment = null, closest_segment = null
+ for (var i = 0; i < this.shapes.length; i++) {
+ segment = this.shapes[i].hasSegmentNear(p, 10)
+ if (segment && (! closest_segment || segment.distance < closest_segment.distance)) {
+ closest_segment = segment
+ closest_segment.shape = this.shapes[i]
+ }
+ }
+ return closest_segment
+ }
+ exports.forEach = function(fn){
+ this.shapes.forEach(fn)
+ }
+ exports.getAllShapeSegments = function(){
+ return this.shapes.map(function(shape){ return shape.getSegments() })
+ }
+ exports.getAllSegments = function(){
+ var segments = []
+ this.shapes.forEach(function(shape){
+ segments = segments.concat( shape.getSegments() )
+ })
+ return segments
+ }
+ exports.draw = function(ctx, fillStyle, strokeStyle) {
+ this.shapes.forEach(function(shape){
+ shape.draw(ctx, fillStyle, strokeStyle)
+ })
+ }
+ exports.serialize = function(){
+ return this.shapes.map(function(shape){
+ return shape.serialize()
+ })
+ }
+ exports.deserialize = function(data){
+ data && data.forEach(function(shape_data){
+ var line
+ switch (shape_data.type) {
+ case 'ortho':
+ line = new OrthoPolyline()
+ break
+ default:
+ line = new Polyline()
+ break
+ }
+ line.deserialize(shape_data)
+ shapes.add(line)
+ }.bind(this))
+ }
+ exports.build = function(){
+ this.shapes.forEach(function(shape){
+ shape.build()
+ })
+ }
+ return exports
+})
+
+if (! ('window' in this) ) {
+ shapes = new ShapeList
+ module.exports = shapes
+}
diff --git a/public/assets/javascripts/rectangles/models/floor.js b/public/assets/javascripts/rectangles/models/floor.js
new file mode 100644
index 0000000..63eebcc
--- /dev/null
+++ b/public/assets/javascripts/rectangles/models/floor.js
@@ -0,0 +1,218 @@
+(function(){
+
+ var vec2, Rect, sort
+ if ('window' in this) {
+ vec2 = window.vec2
+ Rect = window.Rect
+ sort = window.sort
+ }
+ else {
+ vec2 = require('./vec2')
+ Rect = require('./rect')
+ UidGenerator = require('../util/uid')
+ }
+
+ var Floor = function(opt){
+ this.id = opt.id
+ this.side = opt.side
+ this.ceiling = opt.side & CEILING
+ this.mx = opt.mx
+ }
+
+ Floor.prototype.serialize = function(){
+ return {
+ id: this.id,
+ background: this.background,
+ }
+ }
+
+ Floor.prototype.deserialize = function(data){
+ this.wallpaper( data.background )
+ }
+
+ Floor.prototype.bind = function(){
+ var base = this
+ base.$els = $( this.mx.map(function(mx){ return mx.el }) )
+
+ this.mx.forEach(function(mx, index){
+ $(mx.el).bind({
+ contextmenu: function(e){
+ if (! (e.ctrlKey || e.metaKey || e.shiftKey) ) {
+ e.preventDefault()
+ }
+ if (Scenery.nextMedia) {
+ e.preventDefault()
+ Scenery.nextMedia = null
+ app.tube('cancel-scenery')
+ }
+ else if (Scenery.nextWallpaper) {
+ e.preventDefault()
+ Scenery.nextWallpaper = null
+ app.tube('cancel-wallpaper')
+ }
+ },
+
+ mousedown: function(e){
+
+ // right-click
+ if (e.which == 3) {
+ if (Scenery.nextMedia) {
+ e.preventDefault()
+ Scenery.nextMedia = null
+ app.tube('cancel-scenery')
+ }
+ else if (Scenery.nextWallpaper) {
+ e.preventDefault()
+ Scenery.nextWallpaper = null
+ app.tube('cancel-wallpaper')
+ }
+ return
+ }
+
+
+ var offset = offsetFromPoint(e, mx.el)
+ if (! offset) { return }
+
+ var x = mx.x + mx.width * (offset.left-0.5)
+ var z = mx.z + mx.height * (0.5-offset.top)
+
+ if (Scenery.nextMedia) {
+ e.preventDefault()
+
+ var sculpture = Sculpture.addNext({
+ position: { x: x, y: 0, z: z },
+ })
+
+ // scenery was not placed
+ if (! sculpture) {
+ e.stopPropagation()
+ return
+ }
+
+ app.controller.toolbar.resetPermissions()
+ Sculpture.resize.show(sculpture)
+ Sculpture.hovering = true
+
+ // app.controller.pick(sculpture)
+
+ UndoStack.push({
+ type: 'create-sculpture',
+ undo: { id: sculpture.id },
+ redo: sculpture.serialize(),
+ })
+
+ // TODO: watch individual sculpture object here
+ Minotaur.watch( app.router.editorView.settings )
+ }
+ else if (Scenery.nextWallpaper) {
+ var oldState = base.serialize()
+ base.wallpaper(Scenery.nextWallpaper)
+ // Scenery.nextWallpaper = null
+
+ UndoStack.push({
+ type: 'update-wallpaper',
+ undo: oldState,
+ redo: base.serialize(),
+ })
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+
+ app.controller.pickWall(base, null)
+ }
+ else {
+ app.controller.pickWall(base, null)
+ }
+ }
+ })
+ })
+
+ // flip the mx order
+ var shouldFlip = this.side & (CEILING)
+ if (! shouldFlip) {
+ this.mx.reverse()
+ }
+ }
+
+ Floor.prototype.color = function(color){
+ this.$els.css("background-color", color)
+ }
+
+ Floor.prototype.wallpaper = function(background){
+ if (! background) {
+ background = { src: "none" }
+ }
+ else if (typeof background == "string") {
+ background = { src: background }
+ }
+ else if (! background.src) {
+ background = { src: "none" }
+ }
+ background.x = background.x || 0
+ background.y = background.y || 0
+ background.scale = background.scale || 1
+
+ this.background = background
+ this.background.src = this.background.src.replace(/url\(\"?\'?/,"").replace(/\"?\'?\)/,"")
+
+ if (this.background.src == "none") {
+ this.wallpaperLoad(this.background.src)
+ return
+ }
+
+ var img = new Image ()
+ img.onload = function(){
+ this.backgroundImage = img
+ this.wallpaperLoad(this.background.src)
+ this.wallpaperPosition(background)
+ }.bind(this)
+ img.src = this.background.src
+ img.complete && img.onload()
+ }
+
+ Floor.prototype.wallpaperLoad = function(url){
+ if (url !== "none") {
+ url = "url(" + url + ")"
+ }
+ this.mx.forEach(function(mx){
+ mx.el.style.backgroundImage = url
+ })
+ }
+
+ Floor.prototype.wallpaperPosition = function(background){
+ if (this.background.src == "none") { return }
+
+ this.background.x = background.x || this.background.x || 0
+ this.background.y = background.y || this.background.y || 0
+ this.background.scale = background.scale || this.background.scale || 1
+
+ var mx, dx, dy
+ var w = Math.round( this.backgroundImage.naturalWidth * this.background.scale )
+ var h = Math.round( this.backgroundImage.naturalHeight * this.background.scale )
+
+ this.mx.forEach(function(mx, i){
+
+ var region = mx.rect
+
+ if (this.ceiling) {
+ dx = Math.round( this.background.x - region.x.a )
+ dy = Math.round( this.background.y - region.y.a )
+ }
+ else {
+ dx = Math.round( this.background.x - region.x.a )
+ dy = Math.round( this.background.y + region.y.b )
+ }
+
+ mx.el.style.backgroundPosition = dx + 'px ' + dy + 'px'
+ mx.el.style.backgroundSize = w + 'px ' + h + 'px'
+ }.bind(this))
+ bbb = this
+ }
+
+ if ('window' in this) {
+ window.Floor = Floor
+ }
+ else {
+ module.exports = Floor
+ }
+})()
diff --git a/public/assets/javascripts/rectangles/models/mat4.js b/public/assets/javascripts/rectangles/models/mat4.js
deleted file mode 100644
index b061199..0000000
--- a/public/assets/javascripts/rectangles/models/mat4.js
+++ /dev/null
@@ -1,78 +0,0 @@
-function mat4(e){
- this.elements = [ 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1 ]
- return this
-}
-mat4.prototype.set = function (a) {
- var els = this.elements
- a.forEach(function(n,i){ els[i] = n })
- return this
-}
-mat4.prototype.clone = function(){
- return (new mat4).set(this.els)
-}
-mat4.prototype.identity = function () {
- this.set([
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1
- ]);
- return this;
-}
-mat4.prototype.getInverse = function (m, throwOnInvertible) {
-
- // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
- var te = this.elements;
- var me = m.elements;
-
- var n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12];
- var n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13];
- var n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14];
- var n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15];
-
- te[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
- te[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
- te[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
- te[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
- te[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
- te[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
- te[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
- te[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
- te[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
- te[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
- te[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
- te[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
- te[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
- te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
- te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
- te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
-
- var det = n11 * te[ 0 ] + n21 * te[ 4 ] + n31 * te[ 8 ] + n41 * te[ 12 ];
-
- if ( det == 0 ) {
- var msg = "Matrix4.getInverse(): can't invert matrix, determinant is 0";
-
- if ( throwOnInvertible || false ) {
- throw new Error( msg )
- }
- else {
- console.warn( msg )
- }
- this.identity();
- return this
- }
- this.multiplyScalar( 1 / det );
- return this
-}
-mat4.prototype.multiplyScalar = function (n) {
- var els = this.elements
- els[0] *= n; els[4] *= n; els[8] *= n; els[12] *= n
- els[1] *= n; els[5] *= n; els[9] *= n; els[13] *= n
- els[2] *= n; els[6] *= n; els[10] *= n; els[14] *= n
- els[3] *= n; els[7] *= n; els[11] *= n; els[15] *= n
- return this
-}
-
diff --git a/public/assets/javascripts/rectangles/models/rect.js b/public/assets/javascripts/rectangles/models/rect.js
index a08176a..4f73bec 100644
--- a/public/assets/javascripts/rectangles/models/rect.js
+++ b/public/assets/javascripts/rectangles/models/rect.js
@@ -1,4 +1,3 @@
-
(function(){
var vec2
if ('window' in this) {
@@ -8,17 +7,17 @@
vec2 = require('./vec2')
FRONT = 0x1, BACK = 0x2, LEFT = 0x4, RIGHT = 0x8, FLOOR = 0x10, CEILING = 0x20
TOP = CEILING, BOTTOM = FLOOR
- function sidesToString(sides){
- var s = ""
- if (sides & FRONT) s += "front "
- if (sides & BACK) s += "back "
- if (sides & LEFT) s += "left "
- if (sides & RIGHT) s += "right "
- if (sides & TOP) s += "top "
- if (sides & BOTTOM) s += "bottom "
- return s
- }
}
+ function sidesToString(sides){
+ var s = ""
+ if (sides & FRONT) s += "front "
+ if (sides & BACK) s += "back "
+ if (sides & LEFT) s += "left "
+ if (sides & RIGHT) s += "right "
+ if (sides & TOP) s += "top "
+ if (sides & BOTTOM) s += "bottom "
+ return s
+ }
var Rect = function (x0,y0,x1,y1){
if (x0 instanceof vec2) {
@@ -39,6 +38,12 @@
Rect.prototype.clone = function(){
return new Rect( this.x.clone(), this.y.clone() )
}
+ Rect.prototype.x_component = function(){
+ return new vec2( this.x.a, this.y.a )
+ }
+ Rect.prototype.y_component = function(){
+ return new vec2( this.x.b, this.y.b )
+ }
Rect.prototype.assign = function(r) {
this.x.assign(r.x)
this.y.assign(r.y)
@@ -56,6 +61,12 @@
Rect.prototype.maxDimension = function(){
return abs(this.width) > abs(this.height) ? this.width : this.height
}
+ Rect.prototype.isVertical = function(){
+ return this.x.isPoint()
+ }
+ Rect.prototype.isHorizontal = function(){
+ return this.y.isPoint()
+ }
Rect.prototype.mul = function(n){
this.x.mul(n)
@@ -141,11 +152,40 @@
Rect.prototype.width = function(){ return this.x.length() }
Rect.prototype.height = function(){ return this.y.length() }
Rect.prototype.delta = function(){ return new vec2( this.x.magnitude(), this.y.magnitude() ) }
+ Rect.prototype.expand = function(rect){
+ this.x.a = Math.min( this.x.a, rect.x.a )
+ this.x.b = Math.max( this.x.b, rect.x.b )
+ this.y.a = Math.min( this.y.a, rect.y.a )
+ this.y.b = Math.max( this.y.b, rect.y.b )
+ return this
+ }
+ Rect.prototype.square = function(){
+ var width = this.x.length()
+ var height = this.y.length()
+ var diff
+ if (width < height) {
+ diff = (height - width) / 2
+ this.x.a -= diff
+ this.x.b += diff
+ }
+ else {
+ diff = (width - height) / 2
+ this.y.a -= diff
+ this.y.b += diff
+ }
+ return this
+ }
Rect.prototype.toString = function(){
var sides = sidesToString(this.sides)
var s = "[" + this.x.toString() + " " + this.y.toString() + "] " + sides
return s
}
+ Rect.prototype.exactString = function(){
+ var sides = sidesToString(this.sides)
+ var s = "[" + this.x.exactString() + " " + this.y.exactString() + "] " + sides
+ return s
+ }
+
Rect.prototype.serialize = function(){
return { x: this.x.serialize(), y: this.y.serialize() }
}
diff --git a/public/assets/javascripts/rectangles/models/room.js b/public/assets/javascripts/rectangles/models/room.js
index 0f09325..1abe2ba 100644
--- a/public/assets/javascripts/rectangles/models/room.js
+++ b/public/assets/javascripts/rectangles/models/room.js
@@ -31,10 +31,14 @@
var Room = function(opt){
this.id = opt.id || Rooms.uid("room_")
this.rect = opt.rect
- this.regions = []
+ this.regions = opt.regions || []
this.height = opt.height || 200
this.focused = false
+
+ this.mx_walls = []
+ this.mx_floor = []
+ this.mx_ceiling = []
}
Room.prototype.copy = function(){
@@ -122,8 +126,10 @@
return collision
}
- Room.prototype.collidesDisc = function(x,y,radius){
+ Room.prototype.collidesDisc = function(src, dest, radius){
+ var x = dest.x, y = dest.z
var collision = 0, wall_collision, contains_x, contains_y
+
this.regions.forEach(function(r){
if (! r.sides) return
@@ -152,25 +158,10 @@
if (contains_y) {
collision |= wall_collision & LEFT_RIGHT
}
-// if (bitcount(wall_collision) > 1) {
-// collision |= wall_collision
-// }
})
return collision
}
-
- Room.prototype.setFloorColor = function(rgbColor) {
- this.mx_floor.map(function(mx){
- mx.el.style.backgroundColor = rgbColor
- })
- }
-
- Room.prototype.setCeilingColor = function(rgbColor) {
- this.mx_ceiling.map(function(mx){
- mx.el.style.backgroundColor = rgbColor
- })
- }
-
+
if ('window' in this) {
window.Room = Room
}
diff --git a/public/assets/javascripts/rectangles/models/surface.js b/public/assets/javascripts/rectangles/models/surface.js
index 53977c8..f031665 100644
--- a/public/assets/javascripts/rectangles/models/surface.js
+++ b/public/assets/javascripts/rectangles/models/surface.js
@@ -12,6 +12,7 @@
var Surface = function (face){
this.bounds = new Rect (new vec2(0, 0), new vec2(0, 0))
+ this.vec = new Rect (new vec2(0, 0), new vec2(0, 0))
this.faces = []
if (face) {
this.add(face)
@@ -36,7 +37,7 @@
Surface.prototype.fits = function(v){
var faces = this.faces
var scratch
- if (this.bounds.x.b < v.a || this.bounds.y.b < v.b) {
+ if (this.bounds.width() < v.a || this.bounds.height() < v.b) {
return null
}
for (var i = 0; i < faces.length; i++) {
@@ -46,7 +47,7 @@
}
scratch = new Rect (0,0,0,0)
for (var i = 0; i < faces.length; i++) {
- if (faces[i].y.length() < v.b) {
+ if (faces[i].height() < v.b) {
continue
}
scratch.x.a = faces[i].x.a
@@ -108,7 +109,7 @@
this.clamp_delta( this.bounds, dimension, position, delta )
var new_delta = delta.clone()
- if (this.clamp_delta(old_bounds, dimension, position, new_delta).eq(delta)) {
+ if (old_bounds && this.clamp_delta(old_bounds, dimension, position, new_delta).eq(delta)) {
return old_bounds
}
@@ -154,6 +155,21 @@
}
return -1
}
+ Surface.prototype.face_for_x = function(x, min_i){
+ min_i = min_i || 0
+ for (var i = min_i; i < this.faces.length; i++) {
+ if (this.faces[i].x.contains(x)) {
+ return this.faces[i]
+ }
+ }
+ if (x < this.faces[0].x.a) {
+ return this.faces[0]
+ }
+ else {
+ return this.faces[this.faces.length-1]
+ }
+ return null
+ }
Surface.prototype.bounds_at_index_with_dimensions = function(index, dimensions){
var faces = this.faces
diff --git a/public/assets/javascripts/rectangles/models/vec2.js b/public/assets/javascripts/rectangles/models/vec2.js
index 0040435..8942d92 100644
--- a/public/assets/javascripts/rectangles/models/vec2.js
+++ b/public/assets/javascripts/rectangles/models/vec2.js
@@ -37,9 +37,15 @@
vec2.prototype.midpoint = function(){
return lerp(0.5, this.a, this.b)
}
+ vec2.prototype.lerp = function(n){
+ return lerp(n, this.a, this.b)
+ }
vec2.prototype.eq = function(v){
return this.a == v.a && this.b == v.b
}
+ vec2.prototype.isPoint = function(){
+ return this.a == this.b
+ }
vec2.prototype.add = function(n){
this.a += n
this.b += n
@@ -60,9 +66,28 @@
this.b /= n
return this
}
+ vec2.prototype.addVec = function(v){
+ this.a += v.a
+ this.b += v.b
+ return this
+ }
+ vec2.prototype.subVec = function(v){
+ this.a -= v.a
+ this.b -= v.b
+ return this
+ }
vec2.prototype.zero = function(){
this.a = this.b = 0
}
+ vec2.prototype.round = function(){
+ this.a = Math.round(this.a)
+ this.b = Math.round(this.b)
+ }
+ vec2.prototype.distanceTo = function(v){
+ var va = (this.a - v.a)
+ var vb = (this.b - v.b)
+ return Math.sqrt( va*va + vb*vb )
+ }
vec2.prototype.setPosition = function(n){
var len = this.length()
this.a = n
@@ -86,6 +111,12 @@
vec2.prototype.containsDisc = function(n,r){
return this.a <= n-r && n+r <= this.b
}
+ vec2.prototype.containsVec = function(v){
+ return this.a <= v.a && v.b <= this.b
+ }
+ vec2.prototype.containsCenterVec = function(v){
+ return this.a < v.a && v.b < this.b
+ }
vec2.prototype.clamp = function(n){
return clamp(n, this.a, this.b)
}
@@ -183,10 +214,17 @@
}
vec2.prototype.toString = function(){
- return "[" + ~~this.a + " " + ~~this.b + "]"
+ return "[" + Math.round(this.a) + " " + Math.round(this.b) + "]"
+ }
+ vec2.prototype.exactString = function(){
+ return "[" + this.a + " " + this.b + "]"
}
vec2.prototype.serialize = function(){
- return [ ~~this.a, ~~this.b ]
+ return [ Math.round(this.a), Math.round(this.b) ]
+ }
+ vec2.prototype.deserialize = function(data){
+ this.a = data[0]
+ this.b = data[1]
}
vec2.prototype.quantize = function(n){
n = n || 10
diff --git a/public/assets/javascripts/rectangles/models/vec3.js b/public/assets/javascripts/rectangles/models/vec3.js
index 4e00b0c..b3825a9 100644
--- a/public/assets/javascripts/rectangles/models/vec3.js
+++ b/public/assets/javascripts/rectangles/models/vec3.js
@@ -15,6 +15,9 @@ vec3.prototype.sub = function(v){
this.c -= v.c
return this
}
+vec3.prototype.clone = function(){
+ return new vec3(this.a, this.b, this.c)
+}
// input: mat4 projection matrix
vec3.prototype.apply_projection = function (m) {
@@ -29,3 +32,28 @@ vec3.prototype.apply_projection = function (m) {
return this;
}
+
+vec3.prototype.serialize = function(){
+ return [ round(this.a), round(this.b), round(this.c) ]
+}
+vec3.prototype.deserialize = function(data){
+ this.a = data[0]
+ this.b = data[1]
+ this.c = data[2] || data[0]
+ return this
+}
+vec3.prototype.clone = function(){
+ return new vec3(this.a, this.b, this.c)
+}
+vec3.prototype.assign = function(v){
+ this.a = v.a
+ this.b = v.b
+ this.c = v.c
+ return this
+}
+vec3.prototype.mul = function(n) {
+ this.a *= n
+ this.b *= n
+ this.c *= n
+ return this
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js
index 1a3ef7c..cf3cea8 100644
--- a/public/assets/javascripts/rectangles/models/wall.js
+++ b/public/assets/javascripts/rectangles/models/wall.js
@@ -10,21 +10,55 @@
vec2 = require('./vec2')
Rect = require('./rect')
UidGenerator = require('../util/uid')
+ wall_rotation = {}
+ wall_rotation[FRONT] = PI
+ wall_rotation[BACK] = 0
+ wall_rotation[LEFT] = HALF_PI
+ wall_rotation[RIGHT] = -HALF_PI
}
var Wall = function(opt){
- this.id = [ opt.side, opt.edge, opt.vec.a ].join("_")
+ this.id = [ opt.side|0, opt.edge|0, opt.vec.a|0 ].join("_")
this.vec = opt.vec
this.edge = opt.edge
this.side = opt.side
this.surface = opt.surface
+ this.rotationY = ('rotationY' in opt) ? opt.rotationY : wall_rotation[opt.side]
this.mx = opt.mx
- this.background = ""
+ this.background = { src: "none" }
}
Wall.prototype.toString = function(){
return this.vec.toString()
}
+ Wall.prototype.get_points = function(wall_vec){
+ wall_vec = wall_vec || new Rect ()
+ if (this.side & LEFT) {
+ wall_vec.x.a = this.edge
+ wall_vec.x.b = this.vec.b
+ wall_vec.y.a = this.edge
+ wall_vec.y.b = this.vec.a
+ }
+ else if (this.side & RIGHT) {
+ wall_vec.x.a = this.edge
+ wall_vec.x.b = this.vec.a
+ wall_vec.y.a = this.edge
+ wall_vec.y.b = this.vec.b
+ }
+ else if (this.side & FRONT) {
+ wall_vec.x.a = this.vec.a
+ wall_vec.x.b = this.edge
+ wall_vec.y.a = this.vec.b
+ wall_vec.y.b = this.edge
+ }
+ else if (this.side & BACK) {
+ wall_vec.x.a = this.vec.b
+ wall_vec.x.b = this.edge
+ wall_vec.y.a = this.vec.a
+ wall_vec.y.b = this.edge
+ }
+ return wall_vec
+ }
Wall.prototype.reset = function(){
}
@@ -50,13 +84,66 @@
index: index,
})
},
+/*
mousemove: function(e){
+ var offset = offsetFromPoint(e, mx.el)
+ if (offset) {
+ var pos = base.mxOffsetToPosition( offset, index )
+
+ var mx_pos = base.positionToMx(pos, new vec2(5,5))
+ var mx_dot = new MX.Object3D
+ mx_dot.move(mx_pos)
+ mx_dot.width = 5
+ mx_dot.height = 5
+ mx_dot.rotationY = base.rotationY
+ mx_dot.el.style.backgroundColor = "red"
+ scene.add(mx_dot)
+ }
},
+*/
+ contextmenu: function(e){
+ if (! (e.ctrlKey || e.metaKey || e.shiftKey) ) {
+ e.preventDefault()
+ }
+ if (Scenery.nextMedia) {
+ e.preventDefault()
+ Scenery.nextMedia = null
+ app.tube('cancel-scenery')
+ }
+ else if (Scenery.nextWallpaper) {
+ e.preventDefault()
+ Scenery.nextWallpaper = null
+ app.tube('cancel-wallpaper')
+ }
+ },
+
mousedown: function(e){
+
+ // right-click
+ if (e.which == 3) {
+ if (Scenery.nextMedia) {
+ e.preventDefault()
+ Scenery.nextMedia = null
+ app.tube('cancel-scenery')
+ }
+ else if (Scenery.nextWallpaper) {
+ e.preventDefault()
+ Scenery.nextWallpaper = null
+ app.tube('cancel-wallpaper')
+ }
+ return
+ }
+
+ var offset = offsetFromPoint(e, mx.el)
+ if (! offset) { return }
+
+ var pos = base.mxOffsetToPosition( offset, index )
+
if (Scenery.nextMedia) {
var scenery = Scenery.addNextToWall({
wall: base,
- index: index
+ index: index,
+ position: pos,
})
// scenery was not placed
@@ -64,20 +151,26 @@
e.stopPropagation()
return
}
-
+
+ app.controller.toolbar.resetPermissions()
+ Scenery.resize.show(scenery)
+ Scenery.hovering = true
+
+ app.controller.pick(scenery)
+
UndoStack.push({
type: 'create-scenery',
undo: { id: scenery.id },
redo: scenery.serialize(),
})
-
+
// TODO: watch individual scenery object here
Minotaur.watch( app.router.editorView.settings )
}
else if (Scenery.nextWallpaper) {
var oldState = base.serialize()
base.wallpaper(Scenery.nextWallpaper)
- Scenery.nextWallpaper = null
+ // Scenery.nextWallpaper = null
UndoStack.push({
type: 'update-wallpaper',
@@ -87,11 +180,13 @@
// TODO: watch individual scenery object here
Minotaur.watch( app.router.editorView.settings )
+
+ app.controller.pickWall(base, pos)
}
else {
- app.controller.hideExtras()
+ app.controller.pickWall(base, pos)
}
- }
+ },
})
})
@@ -100,12 +195,10 @@
if (! shouldFlip) {
this.mx.reverse()
}
-
- // this.outline(wallColor, outlineColor)
}
Wall.prototype.serialize = function(){
- return {
+ return {
id: this.id,
background: this.background,
}
@@ -149,7 +242,7 @@
x: x,
y: position.b + dimension.b / 2,
z: z,
- rotationY: wall_rotation[ this.side ],
+ rotationY: this.rotationY,
}
}
Wall.prototype.mxToPosition = function(mx, dimension) {
@@ -172,30 +265,104 @@
}
return position
}
-
+ Wall.prototype.mxOffsetToPosition = function( offset, index ) {
+ var face = this.surface.faces[index]
+ var shouldFlip = this.side & (RIGHT | FRONT)
+ var position = new vec2(0,0)
+ position.a = face.x.lerp(shouldFlip ? 1-offset.left : offset.left)
+ position.b = face.y.lerp(1-offset.top)
+ position.round()
+ return position
+ }
+
Wall.prototype.color = function(color){
this.$walls.css("background-color", color)
}
- Wall.prototype.wallpaper = function(background){
- var useX = this.side & FRONT_BACK
- var shouldFlip = this.side & (LEFT | BACK)
-
- this.background = background || "none"
+ Wall.prototype.wallpaper = function(background, img){
+ if (! background) {
+ background = { src: "none" }
+ }
+ else if (typeof background == "string") {
+ background = { src: background }
+ }
+ else if (! background.src) {
+ background = { src: "none" }
+ }
+ background.x = background.x || 0
+ background.y = background.y || 0
+ background.scale = background.scale || 1
+
+ this.background = background
+ this.background.src = this.background.src.replace(/url\(\"?\'?/,"").replace(/\"?\'?\)/,"")
+
+ if (this.background.src == "none") {
+ this.wallpaperLoad(this.background.src)
+ return
+ }
+ img = img || new Image ()
+ img.onload = function(){
+ this.backgroundImage = img
+ this.wallpaperLoad(this.background.src)
+ this.wallpaperPosition(background)
+ }.bind(this)
+ img.src = this.background.src
+ img.complete && img.onload()
+ }
+
+ Wall.prototype.wallpaperLoad = function(url){
+ if (url !== "none") {
+ url = "url(" + url + ")"
+ }
this.mx.forEach(function(mx){
- var partitionOffset = useX ? mx.x : mx.z
- if (shouldFlip) partitionOffset *= -1
- partitionOffset += mx.width/2
- var floorOffset = mx.y + mx.height/2
-
- mx.el.style.backgroundImage = background
- mx.el.style.backgroundPosition = (~~partitionOffset) + "px " + (~~floorOffset) + "px"
+ if (mx.el) mx.el.style.backgroundImage = url
})
}
+
+ Wall.prototype.wallpaperPosition = function(background){
+ if (this.background.src == "none") { return }
+
+ this.background.x = background.x || this.background.x || 0
+ this.background.y = background.y || this.background.y || 0
+ this.background.scale = background.scale || this.background.scale || 1
+
+ var mx, dx, dy
+ var w = Math.round( this.backgroundImage.naturalWidth * this.background.scale )
+ var h = Math.round( this.backgroundImage.naturalHeight * this.background.scale )
+
+ this.surface.faces.forEach(function(face, i){
+ // this.mx[i].el.innerHTML = sidesToString(this.side)
+
+ switch (this.side) {
+ case LEFT:
+ mx = this.mx[this.mx.length-1-i]
+ dx = Math.round( this.background.x + face.x.a )
+ dy = Math.round( this.background.y + face.y.b )
+ break
+ case RIGHT:
+ mx = this.mx[this.mx.length-1-i]
+ dx = Math.round( this.background.x + face.x.b )
+ dy = Math.round( this.background.y + face.y.b )
+ break
+ case FRONT:
+ mx = this.mx[this.mx.length-1-i]
+ dx = Math.round( this.background.x + face.x.b )
+ dy = Math.round( this.background.y + face.y.b )
+ break
+ case BACK:
+ mx = this.mx[i]
+ dx = Math.round( this.background.x - face.x.a )
+ dy = Math.round( this.background.y + face.y.b )
+ break
+ }
+
+ mx.el.style.backgroundPosition = dx + 'px ' + dy + 'px'
+ mx.el.style.backgroundSize = w + 'px ' + h + 'px'
+ }.bind(this))
+ }
Wall.prototype.outline = function(wallColor, outlineColor){
- var useX = this.side & FRONT_BACK
var mx = this.mx
var len = this.mx.length
diff --git a/public/assets/javascripts/rectangles/util/constants.js b/public/assets/javascripts/rectangles/util/constants.js
index 4c6b3cc..522689b 100644
--- a/public/assets/javascripts/rectangles/util/constants.js
+++ b/public/assets/javascripts/rectangles/util/constants.js
@@ -1,5 +1,6 @@
var FRONT = 0x1, BACK = 0x2, LEFT = 0x4, RIGHT = 0x8, FLOOR = 0x10, CEILING = 0x20
- FRONT_BACK = FRONT | BACK, LEFT_RIGHT = LEFT | RIGHT, FLOOR_CEILING = FLOOR | CEILING
+var FRONT_BACK = FRONT | BACK, LEFT_RIGHT = LEFT | RIGHT, FLOOR_CEILING = FLOOR | CEILING
+var WALL_SIDES = FRONT | BACK | LEFT | RIGHT
var TOP = CEILING, BOTTOM = FLOOR,
TOP_LEFT = TOP | LEFT,
@@ -19,10 +20,13 @@ var height_min = 200,
side_min = 10,
side_max = 5000,
resize_margin = 8,
- cursor_amp = 1.5
+ cursor_amp = 1.5,
+ DEFAULT_PICTURE_WIDTH = 350,
+ MAP_GRID_SIZE = 36 // 10 feet
var painting_distance_from_wall = 10,
- dot_distance_from_picture = 3
+ dot_distance_from_picture = 3,
+ sculpture_distance_from_floor = 3
var dot_hide_delay = 50, // ms
dot_side = 20
diff --git a/public/assets/javascripts/rectangles/util/coords.js b/public/assets/javascripts/rectangles/util/coords.js
new file mode 100644
index 0000000..ff56199
--- /dev/null
+++ b/public/assets/javascripts/rectangles/util/coords.js
@@ -0,0 +1,33 @@
+function offsetFromPoint(event, element) {
+ function a(width) {
+ var l = 0, r = 200;
+ while (r - l > 0.0001) {
+ var mid = (r + l) / 2;
+ var a = document.createElement('div');
+ a.style.cssText = 'position: absolute;left:0;top:0;background: red;z-index: 1000;';
+ a.style[width ? 'width' : 'height'] = mid.toFixed(3) + '%';
+ a.style[width ? 'height' : 'width'] = '100%';
+ element.appendChild(a);
+ var x = document.elementFromPoint(event.clientX, event.clientY);
+ element.removeChild(a);
+ if (x === a) {
+ r = mid;
+ } else {
+ if (r === 200) {
+ return null;
+ }
+ l = mid;
+ }
+ }
+ return mid;
+ }
+ var l = a(1),
+ t = a(0);
+ return l && t ? {
+ left: l / 100,
+ top: t / 100,
+ toString: function () {
+ return 'left: ' + l + '%, top: ' + t + '%';
+ }
+ } : null;
+} \ No newline at end of file
diff --git a/public/assets/javascripts/rectangles/util/measurement.js b/public/assets/javascripts/rectangles/util/measurement.js
index d6a0b35..6346eac 100644
--- a/public/assets/javascripts/rectangles/util/measurement.js
+++ b/public/assets/javascripts/rectangles/util/measurement.js
@@ -28,6 +28,10 @@ function measurementToString( n ) {
case 'ft':
ft = floor(n / 36)
inch = abs(round((n % 36) / 3))
+ if (inch == 12) {
+ inch = 0
+ ft += 1
+ }
s = ft + "'"
if (inch > 0) {
s += " " + inch + '"'
diff --git a/public/assets/javascripts/rectangles/util/minotaur.js b/public/assets/javascripts/rectangles/util/minotaur.js
index 0fcc766..8b1abfe 100644
--- a/public/assets/javascripts/rectangles/util/minotaur.js
+++ b/public/assets/javascripts/rectangles/util/minotaur.js
@@ -4,7 +4,7 @@
var base = this
base.$el = $("#minotaur")
base.timeout = null
- base.delay = 1000
+ base.delay = 2500
base.objects = {}
base.init = function () {
@@ -38,7 +38,7 @@
for (var id in base.objects[type]) {
var obj = base.objects[type][id]
if (obj) {
- obj.save(null, function(){ base.hide() }, function(){})
+ obj.save(null, function(){ base.hide() }, function(){ base.hide() })
}
delete base.objects[type][id]
saving = true
@@ -53,9 +53,7 @@
}
base.hide = function () {
- setTimeout(function(){
- base.$el.removeClass()
- }, 500)
+ base.$el.removeClass('saving')
}
base.init();
diff --git a/public/assets/javascripts/rectangles/util/mouse.js b/public/assets/javascripts/rectangles/util/mouse.js
index cb36038..6d9862c 100644
--- a/public/assets/javascripts/rectangles/util/mouse.js
+++ b/public/assets/javascripts/rectangles/util/mouse.js
@@ -54,10 +54,20 @@ function mouse (opt) {
opt.up && base.tube.on("up", opt.up)
opt.rightclick && base.tube.on("rightclick", opt.rightclick)
- var offset = (opt.use_offset && opt.el) ? opt.el.getBoundingClientRect() : null
+ var offset;
base.init = function (){
base.bind()
+ base.set_offset()
+ }
+
+ base.set_offset = function(){
+ if (opt.use_offset && opt.el) {
+ offset = opt.el.getBoundingClientRect()
+ }
+ else {
+ offset = null
+ }
}
base.on = function(){
@@ -73,9 +83,20 @@ function mouse (opt) {
opt.el.addEventListener("mousedown", base.mousedown)
opt.el.addEventListener("contextmenu", base.contextmenu)
}
+ if (opt.use_offset) {
+ window.addEventListener("resize", base.set_offset)
+ }
window.addEventListener("mousemove", base.mousemove)
window.addEventListener("mouseup", base.mouseup)
}
+ base.unbind = function(){
+ if (opt.el) {
+ opt.el.removeEventListener("mousedown", base.mousedown)
+ opt.el.removeEventListener("contextmenu", base.contextmenu)
+ }
+ window.removeEventListener("mousemove", base.mousemove)
+ window.removeEventListener("mouseup", base.mouseup)
+ }
base.bind_el = function(el){
el.addEventListener("mousedown", base.mousedown)
@@ -126,7 +147,7 @@ function mouse (opt) {
}
var x = pos.a, y = pos.b
-
+
if (base.down) {
base.cursor.x.b = x
base.cursor.y.b = y
diff --git a/public/assets/javascripts/rectangles/util/permissions.js b/public/assets/javascripts/rectangles/util/permissions.js
index 1b5a1b5..9e3ef4d 100644
--- a/public/assets/javascripts/rectangles/util/permissions.js
+++ b/public/assets/javascripts/rectangles/util/permissions.js
@@ -31,7 +31,7 @@ Permissions.prototype.add = function (key) {
Permissions.prototype.remove = function (key) {
var base = this
- base[key] = true
+ base[key] = false
}
Permissions.prototype.clear = function () {
diff --git a/public/assets/javascripts/rectangles/util/undostack.js b/public/assets/javascripts/rectangles/util/undostack.js
index 959e3d1..040a4eb 100644
--- a/public/assets/javascripts/rectangles/util/undostack.js
+++ b/public/assets/javascripts/rectangles/util/undostack.js
@@ -10,6 +10,7 @@
this.pointer++
this.stack[this.pointer] = action
this.purge()
+ this.debug && console.log("push", action.type)
}
UndoStack.prototype.purge = function(){
if (this.stack.length-1 == this.pointer) return
diff --git a/public/assets/javascripts/rectangles/util/wheel.js b/public/assets/javascripts/rectangles/util/wheel.js
index 6836772..4155a70 100644
--- a/public/assets/javascripts/rectangles/util/wheel.js
+++ b/public/assets/javascripts/rectangles/util/wheel.js
@@ -3,8 +3,8 @@
base.wheel = new wheel({
el: document.querySelector("#map"),
- update: function(e, val, delta){
- // do something with val
+ update: function(e, delta){
+ // do something with delta
},
})
@@ -13,7 +13,7 @@
function wheel (opt) {
opt = defaults(opt, {
el: document,
- fn: function(e, val, delta){},
+ update: function(e, delta){},
propagate: false,
locked: false,
reversible: true,
@@ -21,37 +21,46 @@ function wheel (opt) {
val: 0,
})
- opt.el.addEventListener('mousewheel', onMouseWheel, false);
+ opt.el.addEventListener('wheel', onMouseWheel, false);
+ // opt.el.addEventListener('mousewheel', onMouseWheel, false);
opt.el.addEventListener('DOMMouseScroll', onMouseWheel, false);
function onMouseWheel (e) {
if (opt.locked) {
return
}
+
if (! opt.propagate) {
e.stopPropagation()
e.preventDefault()
}
- var delta = 0;
+ var deltaX = 0, deltaY = 0;
// WebKit
- if ( event.wheelDeltaY ) {
- delta -= event.wheelDeltaY * opt.ratio
+ if ( event.deltaY ) {
+ deltaY -= event.deltaY * opt.ratio
+ deltaX -= event.deltaX * opt.ratio
+ }
+ else if ( event.wheelDeltaY ) {
+ deltaY -= event.wheelDeltaY * opt.ratio
+ deltaX -= event.wheelDeltaX * opt.ratio
}
// Opera / Explorer 9
else if ( event.wheelDelta ) {
- delta -= event.wheelDelta * opt.ratio
+ deltaY -= event.wheelDelta * opt.ratio
}
// Firefox
else if ( event.detail ) {
- delta += event.detail * 2
+ deltaY += event.detail * 2
}
- if (! opt.reversible && delta < 0) return;
+ if (! opt.reversible && (deltaY < 0 && deltaX < 0)) return;
- opt.val = clamp(opt.val + delta, opt.min, opt.max)
+ // opt.val = clamp(opt.val + delta, opt.min, opt.max)
- opt.update(e, opt.val, delta)
+ // deltaX is also passed, but these values tend to be unusable
+ // try http://vvalls.com/assets/test/wheel.html with a trackpad
+ opt.update(e, deltaY, deltaX)
}
opt.lock = function(){ opt.locked = true }
diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js
index 794079e..61b1d1b 100644
--- a/public/assets/javascripts/ui/_router.js
+++ b/public/assets/javascripts/ui/_router.js
@@ -9,6 +9,7 @@ var SiteRouter = Router.extend({
"click [data-role='new-project-modal']": 'newProject',
"click [data-role='edit-project-modal']": 'editProject',
"click [data-role='edit-profile-modal']": 'editProfile',
+ "click [data-role='edit-subscription-modal']": 'editSubscription',
"click [data-role='new-document-modal']": 'newDocument',
"click [data-role='edit-document-modal']": 'editDocument',
"click [data-role='destroy-document-modal']": 'destroyDocument',
@@ -17,36 +18,55 @@ var SiteRouter = Router.extend({
},
routes: {
+ "/": 'home',
+ "/home": 'home',
+ "/login": 'signin',
+ "/signin": 'signin',
+ "/signup": 'signup',
+
+ "/auth/usernameTaken": 'usernameTaken',
+ "/auth/password": 'passwordReset',
+ "/auth/forgotPassword": 'passwordForgot',
+
+ "/profile": 'profile',
+ "/profile/edit": 'editProfile',
+ "/profile/billing": 'editSubscription',
+ "/profile/:name": 'profile',
+ "/about/:name/edit": 'editDocument',
+ "/about/new": 'newDocument',
+
+ "/layout": 'layoutPicker',
+ "/layout/:name": 'layoutEditor',
+
+ "/blueprint": 'blueprintEditor',
+ "/blueprint/:name": 'blueprintEditor',
+
+ "/project": 'projectPicker',
+ "/project/new": 'newProject',
+ "/project/blueprint/:blueprint": 'projectNewWithBlueprint',
+ "/project/new/:layout": 'projectNewWithLayout',
+ "/project/:name": 'projectViewer',
+ "/project/:name/edit": 'projectEditor',
+ "/project/:name/view": 'projectViewer',
+
+ "/test/blueprint": 'blueprintEditor',
+ },
+
+ mobileRoutes: {
"/": 'home',
+ "/home": 'home',
"/login": 'signin',
+ "/signin": 'signin',
"/signup": 'signup',
-
"/auth/usernameTaken": 'usernameTaken',
"/auth/password": 'passwordReset',
"/auth/forgotPassword": 'passwordForgot',
"/profile": 'profile',
"/profile/edit": 'editProfile',
+ "/profile/billing": 'editSubscription',
"/profile/:name": 'profile',
- "/about/:name/edit": 'editDocument',
- "/about/new": 'newDocument',
-
- "/layout": 'layoutPicker',
- "/layout/:name": 'layoutEditor',
- "/project": 'projectPicker',
- "/project/new": 'newProject',
- "/project/new/:layout": 'projectNewWithLayout',
- "/project/:name": 'projectViewer',
- "/project/:name/edit": 'projectEditor',
- "/project/:name/view": 'projectViewer',
-
- "/test/wallpaper": 'testWallpaper',
- },
-
- mobileRoutes: {
- "/": 'home',
- "/profile": 'profile',
"/project/:name": 'projectViewer',
},
@@ -58,6 +78,7 @@ var SiteRouter = Router.extend({
this.newProjectModal = new NewProjectModal()
this.editProjectModal = new EditProjectModal()
this.editProfileModal = new EditProfileModal()
+ this.editSubscriptionModal = new EditSubscriptionModal()
this.passwordForgotModal = new PasswordForgot()
this.documentModal = new DocumentModal()
this.profileView = new ProfileView()
@@ -65,16 +86,22 @@ var SiteRouter = Router.extend({
this.route()
if (is_mobile) {
- $(".topLinks").hide()
- $(".share").hide()
+ // $(".topLinks").hide()
+ // $(".share").hide()
+ $('.projectItem').each(function(){
+ this.href = this.href.replace(/\/edit$/, "")
+ })
}
- $("body").removeClass("loading")
+ setTimeout(function(){
+ $("body").removeClass("loading")
+ }, 200)
},
layoutEditor: function(e, name){
app.mode.builder = true
app.launch()
+ if (app.unsupported) return
this.builderView = app.controller = new BuilderView()
this.builderView.load(name)
@@ -97,12 +124,29 @@ var SiteRouter = Router.extend({
window.history.pushState(null, document.title, "/project/new")
this.newProjectModal.load()
},
+
+ projectNewWithBlueprint: function(e, blueprint){
+ e && e.preventDefault()
+
+ Rooms.shapesMode = true
+
+ app.mode.editor = true
+ app.launch()
+ if (app.unsupported) return
+
+ blueprint = slugify(blueprint)
+
+ window.history.pushState(null, document.title, "/project/blueprint/" + blueprint)
+ this.editorView = app.controller = new EditorView()
+ this.editorView.loadBlueprint(blueprint)
+ },
projectNewWithLayout: function(e, layout){
e && e.preventDefault()
app.mode.editor = true
app.launch()
+ if (app.unsupported) return
layout = slugify(layout)
@@ -123,6 +167,7 @@ var SiteRouter = Router.extend({
projectEditor: function(e, name){
app.mode.editor = true
app.launch()
+ if (app.unsupported) return
this.editorView = app.controller = new EditorView()
this.editorView.load(name)
@@ -131,10 +176,20 @@ var SiteRouter = Router.extend({
projectViewer: function(e, name){
app.mode.editor = true
app.launch()
+ if (app.unsupported) return
this.readerView = app.controller = new ReaderView()
this.readerView.load(name)
},
+
+ blueprintEditor: function(e, name){
+ environment.init = environment.minimal
+ app.launch()
+ if (app.unsupported) return
+
+ this.blueprintView = app.controller = new BlueprintView ()
+ this.blueprintView.load(name)
+ },
signup: function(e){
e && e.preventDefault()
@@ -177,7 +232,12 @@ var SiteRouter = Router.extend({
this.editProfileModal.load()
},
+ editSubscription: function(e){
+ e && e.preventDefault()
+ window.history.pushState(null, document.title, "/profile/billing")
+ this.editSubscriptionModal.load()
+ },
newDocument: function(e){
e && e.preventDefault()
@@ -212,30 +272,5 @@ var SiteRouter = Router.extend({
// this.documentModal.destroy(name)
},
-
- testWallpaper: function(e){
- var content = document.getElementById("content")
- content.style.width = "680px"
- content.style.margin = "0 auto"
- var wm = new WallpaperManager()
- app.on('wallpaper-ready', function(){
- var black = [0,0,0,0]
- var white = [255,255,255,1.0]
- var swatches = wm.buildSwatches(black, white, 4)
- document.body.style.backgroundColor = "#eee"
- swatches.forEach(function(swatch){
- swatch.style.margin = "4px"
- swatch.style.border = "1px solid lime"
- swatch.style.backgroundColor = "#888"
- content.appendChild(swatch)
- swatch.onclick = function(){
- dataUrl = swatch.toDataURL()
- document.body.style.backgroundImage = "url(" + dataUrl + ")"
- }
- })
- })
- wm.init()
- },
-
})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js
new file mode 100644
index 0000000..7704689
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js
@@ -0,0 +1,129 @@
+
+var wallHeight = 180
+var shapes = new ShapeList
+var last_point = new vec2 (0,0)
+
+var BlueprintEditor = View.extend(AnimatedView.prototype).extend({
+
+ regions: [],
+
+ initialize: function(opt){
+ this.parent = opt.parent
+
+ $(window).resize(this.resize.bind(this))
+
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+ cam = scene.camera
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ movements = new MX.Movements(cam, viewHeight)
+ movements.init()
+ movements.lock()
+
+ app.on("move", function(pos){
+ cam.x = pos.x
+ cam.y = pos.y
+ cam.z = pos.z
+ })
+
+ var floorplan = this.floorplan = new MX.Image({
+ backface: true,
+ })
+ scene.add(this.floorplan)
+
+ // recenter perspective view by rightclicking map
+ this.floorplan.el.addEventListener("contextmenu", function(e){
+ e.preventDefault()
+ var offset = offsetFromPoint(e, this)
+ var x = (offset.left - 0.5) * floorplan.width * floorplan.scale
+ var z = (offset.top - 0.5) * floorplan.height * floorplan.scale
+ controls.opt.center.x = -x
+ controls.opt.center.y = 0
+ controls.opt.center.z = z
+ }, true)
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ el: scene.el,
+ radius: 3000,
+ radiusRange: [ 10, 10000 ],
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+ },
+
+ resize: function(){
+ if (this.parent.orbiting) {
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ this.parent.map.resize( window.innerWidth/2, window.innerHeight )
+ this.parent.map.canvas.style.display = "block"
+ }
+ else {
+ scene.width = window.innerWidth
+ scene.height = window.innerHeight
+ this.parent.map.canvas.style.display = "none"
+ }
+ },
+
+ loadFloorplan: function(media){
+ // console.log(media)
+ this.floorplan.load({
+ media: media,
+ keepImage: true,
+ rotationX: -PI/2,
+ rotationY: PI,
+ scale: media.scale,
+ })
+ this.startAnimating()
+ this.regions = RegionList.buildByShape()
+ },
+
+ animate: function(t, dt){
+ map.update(t)
+
+ movements.update(dt)
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ this.floorplan.draw(map.draw.ctx, true)
+
+ map.draw.coords()
+
+ if (shapes.workline) {
+ shapes.workline.draw(map.draw.ctx, "rgba(255,255,0,0.1)", "#f80")
+ if (map.ui.placing && last_point) {
+ shapes.workline.draw_line( map.draw.ctx, last_point )
+ }
+ }
+
+ shapes.draw(map.draw.ctx, "rgba(255,255,0,0.1)", "#f80")
+
+ map.draw.ctx.strokeStyle = "#f00";
+ map.draw.x_at( this.parent.startPosition )
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+// var colors = ["rgba(0,0,0,0.1)"]
+// var colors = ["rgba(255,255,255,1)"]
+
+// map.draw.regions(this.regions, colors, "#000")
+
+// this.regions.forEach(function(room,i){
+// map.draw.ctx.fillStyle = colors[i % colors.length]
+// map.draw.ctx.fillRect( room.x.a, room.y.a, room.width(), room.height() )
+// })
+
+ map.draw.ctx.restore()
+ },
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintInfo.js b/public/assets/javascripts/ui/blueprint/BlueprintInfo.js
new file mode 100644
index 0000000..51b310e
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintInfo.js
@@ -0,0 +1,92 @@
+
+var BlueprintInfo = View.extend({
+ el: "#blueprintInfo",
+
+ events: {
+ "mousedown": "stopPropagation",
+ "keydown": 'stopPropagation',
+ "change [name=height]": 'changeHeight',
+ "keydown [name=height]": 'enterHeight',
+ "change [name=units]": 'changeUnits',
+ "keydown [name=viewHeight]": 'enterViewHeight',
+ "change [name=viewHeight]": 'changeViewHeight',
+ "click .openScaler": 'openScaler',
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.$height = this.$("[name=height]")
+ this.$units = this.$("[name=units]")
+ this.$viewHeight = this.$("[name=viewHeight]")
+ this.$unitName = this.$(".unitName")
+ this.$blueprintScaleDisplay = this.$("#blueprintScaleDisplay")
+ },
+
+ load: function(data){
+ this.$viewHeight.unitVal( window.viewHeight = data.viewHeight || app.defaults.viewHeight )
+ this.$height.unitVal( window.wallHeight = data.wallHeight || app.defaults.wallHeight )
+ this.$units.val( data.units )
+ this.$('span.units').html( data.units )
+ this.$unitName.html( data.units )
+
+ var resolution
+ switch (data.units) {
+ case 'ft':
+ resolution = app.defaults.footResolution
+ break
+ case 'm':
+ resolution = app.defaults.meterResolution
+ break
+ case 'px':
+ default:
+ resolution = 1
+ break
+ }
+ this.$blueprintScaleDisplay.html( ((1/data.scale) * resolution).toFixed(1) )
+ this.show()
+ },
+
+ toggle: function(state){
+ this.$el.toggleClass("active", state)
+ this.$viewHeight.unitVal( window.viewHeight )
+ },
+
+ openScaler: function(){
+ this.parent.scaler.pick( this.parent.data, true )
+ this.parent.scaler.show()
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+
+ hide: function(){
+ this.toggle(false)
+ },
+
+ deselect: function(){
+ this.toggle(true)
+ },
+
+ enterHeight: function(e){
+ if (e.keyCode == 13) this.changeHeight(e)
+ },
+ changeHeight: function(e){
+ e.stopPropagation()
+ window.wallHeight = this.$height.unitVal()
+ shapes.forEach(function(line){
+ line.mx.set_height( window.wallHeight )
+ })
+ },
+ changeUnits: function(){
+ app.units = this.$units.val()
+ this.$('.units').resetUnitVal()
+ },
+ enterViewHeight: function(e){
+ if (e.keyCode == 13) this.changeViewHeight(e)
+ },
+ changeViewHeight: function(){
+ window.viewHeight = this.$viewHeight.unitVal()
+ }
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintNotice.js b/public/assets/javascripts/ui/blueprint/BlueprintNotice.js
new file mode 100644
index 0000000..4b799a6
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintNotice.js
@@ -0,0 +1,62 @@
+var BlueprintNotice = View.extend(ToggleableView.prototype).extend({
+
+ el: "#blueprintNotice",
+
+ events: {
+ "click .next": "next",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.$notice = this.$(".notice")
+ this.$next = this.$(".next")
+ },
+
+ notice: function(msg){
+ this.$notice.html(msg)
+ },
+
+ showCreateProjectNotice: function(){
+ this.notice("<a href='/project/blueprint/" + this.parent.data.slug +
+ "'>Start a new project</a> with this blueprint.")
+ this.$next.hide()
+ this.nextFn = null
+ this.show()
+ },
+
+ showStartPositionNotice: function(){
+ this.parent.settings.hide()
+ this.notice("First, click the map to set the starting location.")
+ this.$next.show().html("Next")
+ this.show()
+ this.nextFn = this.showStartAngleNotice.bind(this)
+ },
+
+ showStartAngleNotice: function(){
+ this.parent.settings.hide()
+ this.notice("Next, rotate the camera to the desired orientation.")
+ this.$next.show().html("Done")
+ this.show()
+ this.nextFn = this.doneSettingPosition.bind(this)
+ this.parent.toolbar.toggleOrbitMode(false)
+ },
+
+ doneSettingPosition: function(){
+ this.nextFn = null
+ this.$next.hide()
+ this.hide()
+ this.parent.settings.show()
+ this.parent.startPosition.rotationX = cam.rotationX
+ this.parent.startPosition.rotationY = cam.rotationY
+ this.parent.toolbar.toggleOrbitMode(true)
+ this.parent.toolbar.orthoPolylineMode()
+ },
+
+ nextFn: null,
+ next: function(){
+ if (this.nextFn) {
+ this.nextFn()
+ }
+ },
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js
new file mode 100644
index 0000000..cd370ef
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js
@@ -0,0 +1,158 @@
+
+var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({
+ el: ".blueprintScaler",
+
+ fixedClose: true,
+
+ action: "/api/blueprint/scale",
+
+ events: {
+ "change [name=blueprint-dimensions]": "changeDimensions",
+ "change [name=blueprint-units]": "changeUnits",
+ "click .uploadNewBlueprint": "showUploader",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+
+ this.$blueprintMap = this.$("#blueprintMap")
+ this.$blueprintDimensionsRapper = this.$("#blueprintDimensions")
+ this.$dimensions = this.$("[name=blueprint-dimensions]")
+ this.$pixels = this.$("[name=blueprint-pixels]")
+ this.$units = this.$("[name=blueprint-units]")
+ this.$save = this.$("#saveBlueprint")
+
+ this.map = new Map ({
+ type: "ortho",
+ el: this.$blueprintMap.get(0),
+ width: window.innerWidth,
+ height: window.innerHeight,
+ zoom: -2,
+ zoom_min: -7.0,
+ zoom_max: 2,
+ })
+ this.lineTool = new LineTool
+ this.map.ui.add_tool("line", this.lineTool)
+ this.map.ui.set_tool("line")
+
+ scene = scene || { camera: { x: 0, y: 0, z: 0 } }
+
+ this.floorplan = new MX.Image ()
+ },
+
+ showUploader: function(){
+ this.parent.uploader.show()
+ },
+
+ pick: function(media, shouldEdit){
+ this.media = media
+
+ this.floorplan.load({ media: media, scale: 1, keepImage: true })
+
+ if (!! media.units && ! shouldEdit) {
+ this.parent.ready(media)
+ this.hide()
+ this.stopAnimating()
+ return
+ }
+
+ if (media.units && media.line && media.scale) {
+ var points = media.line.split(",")
+ this.lineTool.line[0] = new vec2( +points[0], +points[1] )
+ this.lineTool.line[1] = new vec2( +points[2], +points[3] )
+
+ app.units = media.units
+ this.$units.val( media.units )
+ this.$dimensions.unitVal( media.scale * this.lineLength() )
+ }
+
+ this.startAnimating()
+ },
+
+ animate: function(t, dt){
+ this.map.update(t)
+
+ this.map.draw.ctx.save()
+ this.map.draw.translate()
+
+ this.floorplan.draw(this.map.draw.ctx, true)
+
+ this.map.draw.ctx.save()
+ this.map.draw.ctx.strokeStyle = "#f00"
+ this.map.draw.ctx.lineWidth = 1/map.zoom
+ switch (this.lineTool.line.length) {
+ case 1:
+ this.map.draw.line(
+ this.lineTool.line[0].a,
+ this.lineTool.line[0].b,
+ this.lineTool.cursor.x.a,
+ this.lineTool.cursor.y.a
+ )
+ break
+ case 2:
+ this.map.draw.line(
+ this.lineTool.line[0].a,
+ this.lineTool.line[0].b,
+ this.lineTool.line[1].a,
+ this.lineTool.line[1].b
+ )
+ break
+ }
+ this.map.draw.ctx.restore()
+
+ this.map.draw.coords()
+
+ this.map.draw.mouse(this.map.ui.mouse.cursor)
+
+ this.map.draw.ctx.restore()
+ },
+
+ changeDimensions: function(){
+ app.units = this.$units.val()
+ this.$dimensions.unitVal()
+ },
+ changeUnits: function(){
+ app.units = this.$units.val()
+ this.$dimensions.resetUnitVal()
+ },
+ lineLength: function(){
+ if (this.lineTool.line.length !== 2) return 0
+ var line = this.lineTool.line
+ return dist( line[0].a, line[0].b, line[1].a, line[1].b )
+ },
+
+ validate: function(){
+ var val = this.$dimensions.unitVal()
+ var errors = []
+ if (! this.lineLength()) {
+ errors.push("no line")
+ this.$dimensions.val("")
+ alert("Please click two corners of a wall and then specify how long it is in feet or meters.")
+ }
+ else if (val == 0) {
+ errors.push("no measurement")
+ alert("Please tell us how long the wall is in feet or meters.")
+ }
+ return errors
+ },
+
+ showErrors: function(){},
+
+ serialize: function(){
+ var fd = new FormData(), line = this.lineTool.line
+ fd.append( "_id", this.media._id)
+ fd.append( "units", this.$units.val() )
+ fd.append( "scale", this.$dimensions.unitVal() / this.lineLength() )
+ fd.append( "line", [line[0].a,line[0].b,line[1].a,line[1].b].join(",") )
+ fd.append( "_csrf", $("[name=_csrf]").val())
+ return fd
+ },
+
+ success: function(){
+ this.media.scale = this.$dimensions.unitVal() / this.lineLength()
+ this.stopAnimating()
+ this.parent.ready(this.media)
+ this.hide()
+ },
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintSettings.js b/public/assets/javascripts/ui/blueprint/BlueprintSettings.js
new file mode 100644
index 0000000..8addb9c
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintSettings.js
@@ -0,0 +1,123 @@
+
+var BlueprintSettings = FormView.extend(ToggleableView.prototype).extend({
+ el: "#blueprintSettings",
+
+ action: "/api/blueprint/edit",
+ destroyAction: "/api/blueprint/destroy",
+
+ events: {
+ "mousedown": "stopPropagation",
+ "keydown": 'stopPropagation',
+ "keydown [name=name]": 'enterSubmit',
+ "click [data-role='save-layout']": 'clickSave',
+ "click [data-role='clear-layout']": 'clear',
+ "click [data-role='destroy-layout']": 'destroy',
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ this.$id = this.$("[name=_id]")
+ this.$csrf = this.$("[name=_csrf]")
+ this.$name = this.$("[name=name]")
+ },
+
+ load: function(data){
+ this.$id.val(data._id)
+ if (data.name) {
+ this.$name.val(data.name)
+ this.hide()
+ }
+ else {
+ this.$name.val("")
+ }
+ if (data.shapes) {
+ shapes.destroy()
+ shapes.deserialize( data.shapes )
+ shapes.build()
+ }
+ },
+
+ clear: function(){
+ shapes.destroy()
+ },
+
+ destroy: function(){
+ var msg = "Are you sure you want to delete the blueprint " + sanitize(this.$name.val()) + "?"
+ ConfirmModal.confirm(msg, function(){
+ $.ajax({
+ url: this.destroyAction,
+ type: "delete",
+ data: { _id: this.$id.val(), _csrf: this.$csrf.val() },
+ success: function(data){
+ window.location.href = "/layout"
+ }
+ })
+ }.bind(this))
+ },
+
+ enterSubmit: function (e) {
+ e.stopPropagation()
+ var base = this
+ if (e.keyCode == 13) {
+ setTimeout(function(){ base.save(e) }, 100)
+ }
+ },
+
+ validate: function(){
+ var errors = []
+ var name = this.$name.val()
+ if (! name || ! name.length) {
+ errors.push("Blueprint needs a name.")
+ }
+ if (shapes.count() == 0) {
+ errors.push("Please add some walls.")
+ }
+ return errors
+ },
+
+ showErrors: function(errors){
+ var $errors = $("<span>")
+ errors.forEach(function(err){
+ var $row = $("<div>")
+ $row.html(err)
+ $errors.append( $row )
+ })
+ ErrorModal.alert($errors)
+ },
+
+ serialize: function(){
+ var fd = new FormData()
+ fd.append( "_csrf", this.$csrf.val() )
+ fd.append( "_id", this.$id.val() )
+ fd.append( "name", this.$name.val() )
+ fd.append( "shapes", JSON.stringify( shapes.serialize() ) )
+ fd.append( "startPosition", JSON.stringify( this.parent.quantizeStartPosition() ) )
+ fd.append( "wallHeight", this.parent.info.$height.unitVal() )
+ fd.append( "units", this.parent.info.$units.val() )
+ return fd
+ },
+
+ clickSave: function(){
+ this.toggle(false)
+ this.save()
+ },
+
+ success: function(data){
+ this.parent.data = data
+
+ this.$id.val(data._id)
+ this.$name.val(data.name)
+ this.action = this.updateAction
+
+ this.hide()
+ this.parent.notice.showCreateProjectNotice()
+
+ Minotaur.unwatch(this)
+ Minotaur.hide()
+
+ window.history.pushState(null, document.title, "/blueprint/" + data.slug)
+ },
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js b/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js
new file mode 100644
index 0000000..458357d
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js
@@ -0,0 +1,97 @@
+var BlueprintToolbar = View.extend({
+
+ el: "#blueprintToolbar",
+
+ events: {
+ "click [data-role=upload-floorplan]": 'showUploader',
+ "click [data-role=toggle-orbit-mode]": 'toggleOrbitMode',
+ "click [data-role=arrow-mode]": 'arrowMode',
+ "click [data-role=polyline-mode]": 'polylineMode',
+ "click [data-role=ortho-polyline-mode]": 'orthoPolylineMode',
+ "click [data-role=eraser-mode]": 'eraserMode',
+ "click [data-role=start-position-mode]": 'startPositionMode',
+ "click [data-role=toggle-layout-settings]": 'toggleSettings',
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+
+ this.$modes = this.$('.mode')
+ this.$toggleOrbitMode = this.$('[data-role=toggle-orbit-mode]')
+ this.$arrowMode = this.$('[data-role=arrow-mode]')
+ this.$polylineMode = this.$('[data-role=polyline-mode]')
+ this.$orthoPolylineMode = this.$('[data-role=ortho-polyline-mode]')
+ this.$eraserMode = this.$('[data-role=eraser-mode]')
+ this.$startPositionMode = this.$('[data-role=start-position-mode]')
+
+ keys.on('escape', function(){
+ app.controller.toolbar.toggleOrbitMode()
+ })
+
+ this.arrowMode()
+ },
+
+ showUploader: function(){
+ this.parent.scaler.show()
+ this.parent.uploader.show()
+ },
+
+ toggleOrbitMode: function(state){
+ this.parent.orbiting = typeof state == "boolean" ? state : ! this.parent.orbiting
+ this.$toggleOrbitMode.toggleClass("inuse", ! this.parent.orbiting)
+ this.parent.editor.resize()
+ if (this.parent.orbiting) {
+ controls.toggle(true)
+ movements.lock()
+ }
+ else {
+ controls.toggle(false)
+ movements.unlock()
+ movements.gravity(true)
+ var pos = this.parent.quantizeStartPosition()
+ cam.rotationX = pos.rotationX
+ cam.rotationY = pos.rotationY
+ cam.x = pos.x
+ cam.y = viewHeight
+ cam.z = pos.z
+ }
+ },
+
+ toggleSettings: function(){
+ this.parent.settings.toggle()
+ this.parent.notice.toggle( ! this.parent.data.isNew && ! this.parent.settings.visible() )
+ },
+
+ setActiveMode: function( $el ) {
+ this.$modes.removeClass('active')
+ $el.addClass('active')
+ },
+
+ arrowMode: function(){
+ this.setActiveMode( this.$arrowMode )
+ this.parent.map.ui.set_tool("arrow")
+ },
+
+ polylineMode: function(){
+ this.setActiveMode( this.$polylineMode )
+ this.parent.map.ui.set_tool("polyline")
+ },
+
+ orthoPolylineMode: function(){
+ this.setActiveMode( this.$orthoPolylineMode )
+ this.parent.map.ui.set_tool("ortho-polyline")
+ },
+
+ eraserMode: function(){
+ this.setActiveMode( this.$eraserMode )
+ this.parent.map.ui.set_tool("eraser")
+ },
+
+ startPositionMode: function(){
+ this.setActiveMode( this.$startPositionMode )
+ this.parent.map.ui.set_tool("start-position")
+ this.parent.settings.hide()
+ this.parent.notice.showStartPositionNotice()
+ },
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js
new file mode 100644
index 0000000..aa62a4c
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js
@@ -0,0 +1,147 @@
+
+var BlueprintUploader = UploadView.extend({
+ el: ".blueprintUploader",
+
+ mediaTag: "blueprint",
+ createAction: "/api/blueprint/new",
+ uploadAction: "/api/blueprint/upload",
+ listAction: "/api/blueprint/user",
+ destroyAction: "/api/blueprint/destroy",
+
+ events: {
+ "mousedown": 'stopPropagation',
+ "change .url": "enterUrl",
+ "keydown .url": "enterSetUrl",
+
+ "click .blueprint": "pick",
+ "click .remove": "destroy",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ this.$url = this.$(".url")
+ this.$blueprints = this.$(".blueprints")
+ },
+
+ loaded: false,
+ nameToShow: null,
+ load: function(name){
+ this.nameToShow = name || ""
+ $.get(this.listAction, { tag: this.mediaTag }, this.populate.bind(this))
+ },
+
+ populate: function(data){
+ this.loaded = true
+ if (data && data.length) {
+ this.$blueprints.show()
+ data.forEach(this.append.bind(this))
+ if (this.nameToShow === "new") {
+ // don't pick anything..
+ this.show()
+ }
+ else if (! this.nameToShow) {
+ this.hide()
+ data.some(function(el){
+ if (el.slug == this.nameToShow) {
+ this.parent.scaler.pick(el)
+ return true
+ }
+ }.bind(this))
+ }
+ else {
+ this.hide()
+ this.parent.scaler.pick(data[0])
+ }
+ }
+ else {
+ this.parent.scaler.hideClose()
+ this.show()
+ }
+ },
+
+ pick: function(e){
+ var $el = $(e.currentTarget)
+ var media = $el.data("media")
+ this.hide()
+ this.parent.scaler.pick(media)
+ if (media.slug) {
+ window.history.pushState(null, document.title, "/blueprint/" + media.slug)
+ }
+ },
+
+ destroy: function(e){
+ e.stopPropagation()
+ var $el = $(e.currentTarget)
+ var _id = $el.closest(".blueprint").data("id")
+ $el.remove()
+ $.ajax({
+ type: "delete",
+ url: this.destroyAction,
+ data: { _id: _id, _csrf: $("[name=_csrf]").val() }
+ }).complete(function(){
+ })
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+ hide: function(){
+ this.toggle(false)
+ },
+ toggle: function (state) {
+ this.$el.toggleClass("active", state)
+ },
+
+ addUrl: function (url){
+ Parser.loadImage(url, function(media){
+ if (! media) return
+ media._csrf = $("[name=_csrf]").val()
+ media.tag = this.mediaTag
+
+ var request = $.ajax({
+ type: "post",
+ url: this.createAction,
+ data: media,
+ })
+ request.done(this.add.bind(this))
+
+ }.bind(this))
+ },
+ enterUrl: function(){
+ var url = this.$url.sanitize()
+ this.addUrl(url)
+ this.$url.val("")
+ },
+ enterSetUrl: function (e) {
+ e.stopPropagation()
+ if (e.keyCode == 13) {
+ setTimeout(this.enterUrl.bind(this), 100)
+ }
+ },
+
+ add: function(media){
+ this.$blueprints.show()
+ this.append(media)
+ this.hide()
+ this.parent.scaler.pick(media, true)
+ },
+
+ append: function(media){
+ var $el = $("<span>")
+ var img = new Image ()
+ img.src = media.url
+ var remove = document.createElement("span")
+ remove.className = "remove"
+ remove.innerHTML = "<span>x</span>"
+
+ $el.data("id", media._id)
+ $el.data("media", media)
+ $el.append(img)
+ $el.append(remove)
+ $el.addClass("blueprint")
+ this.$blueprints.append($el)
+ },
+
+})
diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js
new file mode 100644
index 0000000..1858c3d
--- /dev/null
+++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js
@@ -0,0 +1,106 @@
+
+var BlueprintView = View.extend({
+ el: "#blueprintView",
+
+ action: "/api/blueprint/show/",
+
+ events: {
+ },
+
+ initialize: function(){
+// this.colorControl = new ColorControl ({ parent: this })
+// this.cursor = new HelpCursor({ parent: this })
+ this.map = this.buildMap()
+ this.editor = new BlueprintEditor ({ parent: this })
+ this.toolbar = new BlueprintToolbar ({ parent: this })
+ this.uploader = new BlueprintUploader ({ parent: this })
+ this.scaler = new BlueprintScaler ({ parent: this })
+ this.info = new BlueprintInfo ({ parent: this })
+ this.settings = new BlueprintSettings ({ parent: this })
+ this.notice = new BlueprintNotice ({ parent: this })
+ Rooms.shapesMode = true
+ },
+
+ load: function(name){
+ name = sanitize(name) || "new"
+ this.uploader.load(name)
+// name = sanitize(name)
+// $.get(this.action + name, this.ready.bind(this))
+ },
+
+ orbiting: true,
+ startPosition: {},
+ quantizeStartPosition: function(){
+ //
+ var regions = RegionList.build()
+ var pos = this.startPosition
+ var startPositionIsInARoom = regions.some(function(region){
+ return region.contains(pos.x, pos.z)
+ })
+ if (startPositionIsInARoom) {
+ return this.startPosition
+ }
+ else if (! regions.length) {
+ return {
+ x: 0,
+ y: viewHeight,
+ z: 0,
+ rotationX: 0,
+ rotationY: Math.PI/2,
+ }
+ }
+ else {
+ var center = regions[0].center()
+ return {
+ x: center.a,
+ y: viewHeight,
+ z: center.b,
+ rotationX: 0,
+ rotationY: Math.PI/2,
+ }
+ }
+ },
+
+ buildMap: function(){
+ // i forget if this has to be global
+ map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: -2,
+ zoom_min: -6.2,
+ zoom_max: 1,
+ })
+ map.ui.add_tool("arrow", new ArrowTool)
+ map.ui.add_tool("polyline", new PolylineTool)
+ map.ui.add_tool("ortho-polyline", new OrthoPolylineTool)
+ map.ui.add_tool("eraser", new EraserTool)
+ map.ui.add_tool("position", new PositionTool)
+ map.ui.add_tool("start-position", new StartPositionTool)
+ map.ui.placing = false
+ return map
+ },
+
+ ready: function(data){
+ this.data = data
+ this.info.load(data)
+ this.settings.load(data)
+ this.editor.loadFloorplan(data)
+ if (! data.shapes || data.shapes.length == 0) {
+ this.startPosition = { x: 0, y: 0, z: 0, rotationX: 0, rotationY: Math.PI/2 }
+ }
+ else {
+ this.startPosition = data.startPosition
+ }
+ this.notice.hide()
+ this.settings.show()
+ },
+
+ hideExtras: function(){
+ },
+
+ pickWall: function(wall, pos){
+ },
+
+})
diff --git a/public/assets/javascripts/ui/builder/BuilderInfo.js b/public/assets/javascripts/ui/builder/BuilderInfo.js
index e6b7e97..aa58d6e 100644
--- a/public/assets/javascripts/ui/builder/BuilderInfo.js
+++ b/public/assets/javascripts/ui/builder/BuilderInfo.js
@@ -3,15 +3,21 @@ var BuilderInfo = View.extend({
el: "#builderInfo",
events: {
+ "mousedown": "stopPropagation",
"keydown": 'stopPropagation',
"change [name=x]": 'changeX',
"change [name=y]": 'changeY',
"change [name=width]": 'changeWidth',
"change [name=depth]": 'changeDepth',
"change [name=height]": 'changeHeight',
+ "keydown [name=width]": 'enterWidth',
+ "keydown [name=depth]": 'enterDepth',
+ "keydown [name=height]": 'enterHeight',
"change [name=units]": 'changeUnits',
- "change [name=resolution]": 'changeResolution',
+ "keydown [name=viewHeight]": 'enterViewHeight',
"change [name=viewHeight]": 'changeViewHeight',
+ "change [name=heightGlobal]": 'changeHeightGlobal',
+ "click [data-role=destroy-room]": 'destroy',
},
initialize: function(opt){
@@ -24,25 +30,51 @@ var BuilderInfo = View.extend({
this.$units = this.$("[name=units]")
this.$viewHeight = this.$("[name=viewHeight]")
this.$unitName = this.$(".unitName")
+ this.$noSelection = this.$(".no-selection")
+ this.$settings = this.$(".setting")
+ this.$heightGlobalCheckbox = this.$("[name=heightGlobal]")
app.on("builder-pick-room", this.pick.bind(this))
- app.on("builder-destroy-room", this.destroy.bind(this))
+ app.on("builder-destroy-room", this.hide.bind(this))
+ app.on("builder-pick-nothing", this.deselect.bind(this))
},
load: function(data){
- this.$viewHeight.unitVal( data.viewHeight || app.defaults.viewHeight )
- this.$units.val( "ft" )
- this.$unitName.html( "ft" )
+ this.$viewHeight.unitVal( window.viewHeight = data.viewHeight || app.defaults.viewHeight )
+ this.$units.val( data.units || "ft" )
+ this.$unitName.html( data.units || "ft" )
+
+ if (Rooms.regions.length == 0) {
+ this.changeHeightGlobal(true)
+ }
+ else {
+ var rooms = Rooms.values()
+ var height = rooms[0].height
+ var differentHeights = Rooms.some(function(room){
+ return room.height != height
+ })
+ this.changeHeightGlobal( ! differentHeights )
+ }
},
toggle: function(state){
+ this.$settings.toggle( !! this.room )
+ this.$noSelection.toggle( ! this.room )
this.$el.toggleClass("active", state)
+ if (state) {
+ this.$viewHeight.unitVal( window.viewHeight )
+ this.parent.cursor.message("builder")
+ }
+ else {
+ this.parent.cursor.message("start")
+ }
},
show: function(){
this.toggle(true)
},
- hide: function(){
+ hide: function(){
+ this.room = null
this.toggle(false)
},
@@ -57,43 +89,84 @@ var BuilderInfo = View.extend({
this.$y.unitVal( room.rect.y.a )
this.show()
},
+
+ deselect: function(){
+ this.room = null
+ this.toggle(true)
+ },
+
+ destroy: function(){
+ UndoStack.push({
+ type: "destroy-room",
+ undo: this.room.copy(),
+ redo: { id: this.room.id },
+ })
+
+ Rooms.remove(this.room)
+ app.tube("builder-destroy-room", this.room)
- destroy: function(room){
this.room = null
this.hide()
},
+ enterWidth: function(e){
+ if (e.keyCode == 13) this.changeWidth(e)
+ },
changeWidth: function(e){
e.stopPropagation()
this.room.rect.x.setLength( this.$width.unitVal() )
- Rooms.clipper.update()
+ Rooms.rebuild()
+ },
+
+ enterDepth: function(e){
+ if (e.keyCode == 13) this.changeDepth(e)
},
changeDepth: function(e){
e.stopPropagation()
this.room.rect.y.setLength( this.$depth.unitVal() )
- Rooms.clipper.update()
+ Rooms.rebuild()
+ },
+
+ enterHeight: function(e){
+ if (e.keyCode == 13) this.changeHeight(e)
},
changeHeight: function(e){
e.stopPropagation()
- this.room.height = this.$height.unitVal()
- Rooms.clipper.update()
+ var height = this.room.height = this.$height.unitVal()
+ if (window.heightIsGlobal) {
+ Rooms.forEach(function(room){
+ room.height = height
+ })
+ }
+ Rooms.rebuild()
},
changeX: function(e){
e.stopPropagation()
this.room.rect.x.setPosition( this.$x.unitVal() )
- Rooms.clipper.update()
+ Rooms.rebuild()
},
changeY: function(e){
e.stopPropagation()
this.room.rect.y.setPosition( this.$y.unitVal() )
- Rooms.clipper.update()
+ Rooms.rebuild()
},
changeUnits: function(){
app.units = this.$units.val()
this.$('.units').resetUnitVal()
},
- changeViewHeight: function(){
+ enterViewHeight: function(e){
+ if (e.keyCode == 13) this.changeViewHeight(e)
+ },
+ changeViewHeight: function(){
window.viewHeight = this.$viewHeight.unitVal( )
},
+ changeHeightGlobal: function(state){
+ if (typeof state == "boolean") {
+ this.$heightGlobalCheckbox.prop("checked", state)
+ window.heightIsGlobal = state
+ return
+ }
+ window.heightIsGlobal = this.$heightGlobalCheckbox.prop("checked")
+ },
})
diff --git a/public/assets/javascripts/ui/builder/BuilderSettings.js b/public/assets/javascripts/ui/builder/BuilderSettings.js
index 94eed29..256bffe 100644
--- a/public/assets/javascripts/ui/builder/BuilderSettings.js
+++ b/public/assets/javascripts/ui/builder/BuilderSettings.js
@@ -7,6 +7,7 @@ var BuilderSettings = FormView.extend({
destroyAction: "/api/layout/destroy",
events: {
+ "mousedown": "stopPropagation",
"keydown": 'stopPropagation',
"keydown [name=name]": 'enterSubmit',
"click [data-role='save-layout']": 'clickSave',
@@ -29,7 +30,7 @@ var BuilderSettings = FormView.extend({
this.$id.val(data._id)
this.$name.val(data.name)
- this.parent.lightControl.loadDefaults()
+ this.parent.colorControl.loadDefaults()
data.rooms && Rooms.deserialize(data.rooms)
data.startPosition && scene.camera.move(data.startPosition)
@@ -51,7 +52,7 @@ var BuilderSettings = FormView.extend({
this.$name.val( names.join(" ") )
this.action = this.createAction
- window.history.pushState(null, document.title, "/builder/new")
+ window.history.pushState(null, document.title, "/layout/new")
},
clear: function(){
@@ -107,7 +108,7 @@ var BuilderSettings = FormView.extend({
},
serialize: function(){
- map.draw.render()
+ var thumbnail = map.draw.render()
var fd = new FormData()
fd.append( "_csrf", this.$csrf.val() )
fd.append( "_id", this.$id.val() )
@@ -115,7 +116,7 @@ var BuilderSettings = FormView.extend({
fd.append( "privacy", this.$privacy.filter(":checked").val() == "private" )
fd.append( "rooms", JSON.stringify( Rooms.serialize() ) )
fd.append( "startPosition", JSON.stringify( app.position(scene.camera) ) )
- fd.append( "thumbnail", dataUriToBlob(map.canvas.toDataURL()) )
+ fd.append( "thumbnail", dataUriToBlob(thumbnail.toDataURL()) )
return fd
},
diff --git a/public/assets/javascripts/ui/builder/BuilderToolbar.js b/public/assets/javascripts/ui/builder/BuilderToolbar.js
index 2eb7590..e9dcce3 100644
--- a/public/assets/javascripts/ui/builder/BuilderToolbar.js
+++ b/public/assets/javascripts/ui/builder/BuilderToolbar.js
@@ -3,6 +3,7 @@ var BuilderToolbar = View.extend({
el: "#builderToolbar",
events: {
+ "mousedown": "stopPropagation",
"click [data-role='toggle-map-view']": 'toggleMap',
"click [data-role='toggle-layout-settings']": 'toggleSettings',
"click [data-role='undo']": 'undo',
@@ -59,6 +60,9 @@ var BuilderToolbar = View.extend({
var state = map.ui.permissions.toggle("destroy")
$(".inuse").removeClass("inuse")
$(e.currentTarget).toggleClass("inuse", state)
+ if (! state) {
+ this.resetPermissions()
+ }
},
})
diff --git a/public/assets/javascripts/ui/builder/BuilderView.js b/public/assets/javascripts/ui/builder/BuilderView.js
index 81dce52..b975499 100644
--- a/public/assets/javascripts/ui/builder/BuilderView.js
+++ b/public/assets/javascripts/ui/builder/BuilderView.js
@@ -11,12 +11,8 @@ var BuilderView = View.extend({
this.info = new BuilderInfo ({ parent: this })
this.toolbar = new BuilderToolbar ({ parent: this })
this.settings = new BuilderSettings ({ parent: this })
- this.lightControl = new LightControl ({ parent: this })
-
- app.on("rooms-built", function(){
- Walls.paint()
- })
-
+ this.colorControl = new ColorControl ({ parent: this })
+ this.cursor = new HelpCursor({ parent: this })
},
load: function(name){
@@ -36,6 +32,9 @@ var BuilderView = View.extend({
},
hideExtras: function(){
- }
+ },
+
+ pickWall: function(wall, pos){
+ },
})
diff --git a/public/assets/javascripts/ui/editor/Collaborators.js b/public/assets/javascripts/ui/editor/Collaborators.js
index 452ad15..b57510d 100644
--- a/public/assets/javascripts/ui/editor/Collaborators.js
+++ b/public/assets/javascripts/ui/editor/Collaborators.js
@@ -9,6 +9,7 @@ var Collaborators = ModalFormView.extend({
destroyAction: function(){ return "/api/collaborator/" + this.parent.data.slug + "/destroy" },
events: {
+ "mousedown": "stopPropagation",
"keydown [name=email]": "enterSubmit",
"click [data-role=destroy-collaborator]": "destroy",
},
diff --git a/public/assets/javascripts/ui/editor/ColorControl.js b/public/assets/javascripts/ui/editor/ColorControl.js
new file mode 100644
index 0000000..54a6a2e
--- /dev/null
+++ b/public/assets/javascripts/ui/editor/ColorControl.js
@@ -0,0 +1,153 @@
+
+var ColorControl = View.extend({
+ el: ".colorcontrol",
+
+ events: {
+ "mousedown": "stopPropagation",
+ "click .color-swatches span": "setSurface",
+ "click .colors span": "setHue",
+ },
+
+ colors: [
+ [255,94,58],
+ [255,149,0],
+ [255,219,76],
+ [76,217,100],
+ [52,170,220],
+ [29,98,240],
+ [198,68,252],
+ [0,0,0],
+ [74,74,74],
+ [125,126,127],
+ [209,211,212],
+ [235,235,235],
+ [255,255,255],
+ ],
+
+ initialize: function(opt){
+ this.parent = opt.parent
+
+ this.colorPicker = new LabColorPicker(this, 155, 155)
+ this.$(".color-picker").append( this.colorPicker.canvas )
+ this.$(".color-picker").append( this.colorPicker.cursor )
+ this.$(".slider").append( this.colorPicker.brightness )
+
+ this.$swatches = this.$(".swatch")
+ this.$labels = this.$(".swatch + label")
+ this.$swatch = {
+ wall: this.$("#wall-color"),
+ outline: this.$("#outline-color"),
+ floor: this.$("#floor-color"),
+ ceiling: this.$("#ceiling-color"),
+ }
+
+ this.$colors = this.$(".colors")
+ this.colors.forEach(function(color){
+ var $swatch = $("<span>")
+ $swatch.css("background-color","rgb(" + color + ")")
+ $swatch.data('color', color)
+ this.$colors.append($swatch)
+ }.bind(this))
+
+ if ($.browser.mozilla) {
+ $("#floor-color").parent().hide()
+ $("#ceiling-color").parent().hide()
+ }
+ },
+
+ modes: [ "wall", "outline", "floor", "ceiling" ],
+
+ load: function(data){
+ this.modes.forEach(function(mode){
+ Walls.setColor[mode](data[mode])
+ this.$swatch[ mode ].css("background-color", rgb_string(data[mode]))
+ }.bind(this))
+ this.setMode("wall")
+ },
+
+ loadDefaults: function(){
+ var colors = {
+ wall: app.defaults.colors.wall.slice(),
+ outline: app.defaults.colors.outline.slice(),
+ floor: app.defaults.colors.floor.slice(),
+ ceiling: app.defaults.colors.ceiling.slice(),
+ }
+ this.load(colors)
+ },
+
+ toggle: function(state){
+ if (state) {
+ this.parent.cursor.message("colors")
+ }
+ this.$el.toggleClass("active", state);
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+
+ hide: function(){
+ this.toggle(false)
+ },
+
+ pickColor: function(rgb, Lab){
+ this.labColor = Lab
+ this.setSwatchColor(this.mode, rgb)
+ // console.log(rgb)
+ Walls.setColor[ this.mode ](rgb)
+ this.parent.presets.modified = true
+ },
+
+ setSwatchColor: function(mode, rgb) {
+ this.$swatch[ mode ].css("background-color", rgb_string(rgb))
+ },
+
+ initialState: null,
+
+ begin: function(){
+ this.initialState = this.serialize()
+ },
+
+ serialize: function(){
+ return {
+ mode: this.mode,
+ rgb: Walls.colors[ this.mode ]
+ }
+ },
+
+ finalize: function(){
+ if (! this.initialState) { return }
+ UndoStack.push({
+ type: 'update-colors',
+ undo: this.initialState,
+ redo: this.serialize(),
+ })
+
+ this.initialState = null
+
+ // TODO: watch individual wall object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+
+ setMode: function (mode) {
+ var color, brightness
+ this.mode = mode
+ this.$(".active").removeClass("active")
+ this.$swatch[ mode ].parent().addClass("active")
+ color = Walls.colors[ mode ]
+
+ this.labColor = this.colorPicker.load(color)
+ },
+
+ setSurface: function(e){
+ var mode = $('.swatch', e.currentTarget).data('mode')
+ this.setMode(mode)
+ },
+
+ setHue: function(e){
+ var color = $(e.currentTarget).data('color')
+ this.labColor = this.colorPicker.load(color)
+ this.pickColor(color, this.labColor)
+ }
+
+})
diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js
index 8a88f7a..5aa88e9 100644
--- a/public/assets/javascripts/ui/editor/EditorSettings.js
+++ b/public/assets/javascripts/ui/editor/EditorSettings.js
@@ -5,8 +5,11 @@ var EditorSettings = FormView.extend({
createAction: "/api/project/new",
updateAction: "/api/project/edit",
destroyAction: "/api/project/destroy",
+
+ useMinotaur: true,
events: {
+ "mousedown": "stopPropagation",
"keydown": 'stopPropagation',
"keydown [name=name]": 'enterSubmit',
"click [data-role='show-collaborators']": 'showCollaborators',
@@ -14,6 +17,12 @@ var EditorSettings = FormView.extend({
"click [data-role='clone-project']": 'clone',
"click [data-role='clear-project']": 'clear',
"click [data-role='destroy-project']": 'destroy',
+ "click [data-role='toggle-map']": 'toggleMap',
+ "click [data-role='view-project']": 'viewProject',
+ "click #startText": "setStartPosition",
+ "click #moveText": "confirmStartPosition",
+ "click #confirmText": "setStartPosition",
+ "click #goText": "goToStartPosition",
},
initialize: function(opt){
@@ -25,21 +34,30 @@ var EditorSettings = FormView.extend({
this.$name = this.$("[name=name]")
this.$description = this.$("[name=description]")
this.$privacy = this.$("[name=privacy]")
+ this.$startPoint = this.$("#startpoint")
},
load: function(data){
this.action = data.isNew ? this.createAction : this.updateAction
this.parent.data = data
- data.rooms && Rooms.deserialize(data.rooms)
- data.walls && Walls.deserialize(data.walls)
- data.startPosition && scene.camera.move(data.startPosition)
+ if (data.shapes && data.shapes.length) {
+ Rooms.deserializeFromShapes(data, data.walls)
+ }
+ else if (data.rooms) {
+ Rooms.deserialize(data.rooms, data.walls)
+ }
+ if (data.startPosition) {
+ scene.camera.move(data.startPosition)
+ this.startPosition = data.startPosition
+ this.$startPoint.addClass("confirmed")
+ }
if (data.colors && data.colors.wall) {
- this.parent.lightControl.load(data.colors)
+ this.parent.colorControl.load(data.colors)
}
else {
- this.parent.lightControl.loadDefaults()
+ this.parent.colorControl.loadDefaults()
}
if (data.walls) {
@@ -53,7 +71,7 @@ var EditorSettings = FormView.extend({
}
if (data.isNew) {
- this.$name.val( "Untitled Room" )
+ this.$name.val( "Untitled" )
}
else {
this.thumbnailIsStale()
@@ -64,6 +82,7 @@ var EditorSettings = FormView.extend({
data.privacy && this.$privacy.find("[value=" + data.privacy + "]").prop("checked", "checked")
data.media && Scenery.deserialize(data.media)
+ data.sculpture && Sculpture.deserialize(data.sculpture)
}
},
@@ -72,7 +91,14 @@ var EditorSettings = FormView.extend({
this.parent.collaborators.show()
},
- clone: function(){
+ toggleMap: function(e){
+ e.preventDefault()
+ app.controller.toolbar.toggleMap()
+ },
+
+ clone: function(e){
+ e.preventDefault()
+
var names = this.$name.val().split(" ")
if ( ! isNaN(Number( names[names.length-1] )) ) {
names[names.length-1] = Number( names[names.length-1] ) + 1
@@ -84,12 +110,15 @@ var EditorSettings = FormView.extend({
this.$id.val('new')
this.$name.val( names.join(" ") )
this.action = this.createAction
+ this.thumbnailState = null
- window.history.pushState(null, document.title, "/builder/new")
+ window.history.pushState(null, document.title, "/project/new")
},
- clear: function(){
- Rooms.removeAll()
+ clear: function(e){
+ e.preventDefault()
+ Scenery.removeAll()
+ Sculpture.removeAll()
},
destroy: function(){
@@ -100,7 +129,7 @@ var EditorSettings = FormView.extend({
type: "delete",
data: { _id: this.$id.val(), _csrf: this.$csrf.val() },
success: function(data){
- window.location.href = "/project"
+ window.location.href = "/profile"
}
})
}.bind(this))
@@ -109,8 +138,12 @@ var EditorSettings = FormView.extend({
toggle: function(state){
var state = typeof state == 'boolean' ? state : ! this.$el.hasClass("active")
this.$el.toggleClass("active", state)
-
+
+ $(".inuse").removeClass("inuse")
$("[data-role='toggle-project-settings']").toggleClass("inuse", state)
+ if (state) {
+ this.parent.cursor.message("settings")
+ }
},
enterSubmit: function (e) {
@@ -140,22 +173,43 @@ var EditorSettings = FormView.extend({
ErrorModal.alert($errors)
},
+ startPosition: null,
+ setStartPosition: function(){
+ this.$startPoint.addClass("active").removeClass("confirmed")
+ },
+ confirmStartPosition: function(){
+ this.$startPoint.removeClass("active").addClass("confirmed")
+ this.startPosition = app.position(scene.camera)
+ },
+ goToStartPosition: function(){
+ if (! this.startPosition) return
+ scene.camera.move(this.startPosition)
+ },
+
serialize: function(){
- map.draw.render()
var fd = new FormData()
fd.append( "_csrf", this.$csrf.val() )
fd.append( "_id", this.$id.val() )
fd.append( "name", this.$name.val() )
fd.append( "description", this.$description.val() )
fd.append( "privacy", this.$privacy.filter(":checked").val() == "private" )
- fd.append( "rooms", JSON.stringify( Rooms.serialize() ) )
+ fd.append( "viewHeight", window.viewHeight )
+ if (Rooms.shapesMode) {
+ fd.append( "shapes", JSON.stringify( shapes.serialize() ) )
+ }
+ else {
+ fd.append( "rooms", JSON.stringify( Rooms.serialize() ) )
+ }
fd.append( "walls", JSON.stringify( Walls.serialize() ) )
fd.append( "colors", JSON.stringify( Walls.colors ) )
fd.append( "media", JSON.stringify( Scenery.serialize() ) )
- fd.append( "startPosition", JSON.stringify( app.position(scene.camera) ) )
+ fd.append( "sculpture", JSON.stringify( Sculpture.serialize() ) )
+ fd.append( "startPosition", JSON.stringify( this.startPosition || false ) )
+ fd.append( "lastPosition", JSON.stringify( app.position(scene.camera) ) )
if (this.thumbnailIsStale()) {
- fd.append( "thumbnail", dataUriToBlob(map.canvas.toDataURL()) )
+ var thumbnail = map.draw.render()
+ fd.append( "thumbnail", dataUriToBlob(thumbnail.toDataURL()) )
}
return fd
},
@@ -174,6 +228,16 @@ var EditorSettings = FormView.extend({
clickSave: function(){
this.toggle(false)
this.save()
+ this.isVisible = true
+ },
+
+ viewAfterSave: false,
+ viewProject: function(e){
+ e.preventDefault()
+ Minotaur.unwatch(this)
+ Minotaur.hide()
+ this.viewAfterSave = true
+ this.save()
},
success: function(data){
@@ -181,11 +245,22 @@ var EditorSettings = FormView.extend({
this.$name.val(data.name)
this.action = this.updateAction
+ if (this.viewAfterSave) {
+ window.location.pathname = "/project/" + data.slug
+ return
+ }
+
Minotaur.unwatch(this)
Minotaur.hide()
window.history.pushState(null, document.title, "/project/" + data.slug + "/edit")
-
+
+ this.parent.share.setLink( "http://vvalls.com/project/" + data.slug )
+ if (this.isVisible) {
+ this.isVisible = false
+ this.parent.share.show()
+ }
+
this.parent.data = data
},
diff --git a/public/assets/javascripts/ui/editor/EditorToolbar.js b/public/assets/javascripts/ui/editor/EditorToolbar.js
index e91da0f..a5ad2dd 100644
--- a/public/assets/javascripts/ui/editor/EditorToolbar.js
+++ b/public/assets/javascripts/ui/editor/EditorToolbar.js
@@ -3,86 +3,86 @@ var EditorToolbar = View.extend({
el: "#editorToolbar",
events: {
+ "mousedown": 'stopPropagation',
+ "mouseenter": 'mouseenter',
+ "mouseleave": 'mouseleave',
+ "click [data-role='undo']": 'undo',
"click [data-role='toggle-map-view']": 'toggleMap',
"click [data-role='toggle-project-settings']": 'toggleSettings',
"click [data-role='open-media-viewer']": 'openMediaViewer',
- "click [data-role='resize-media']": 'resizeMedia',
- "click [data-role='destroy-media']": 'destroyMedia',
+ "click [data-role='toggle-presets']": 'togglePresets',
"click [data-role='toggle-wallpaper-panel']": 'toggleWallpaper',
- "click [data-role='toggle-light-control']": 'toggleLightControl',
- "click [data-role='edit-wall-text']": 'editWallText',
+ "click [data-role='toggle-color-control']": 'toggleColorControl',
+ "click [data-role='toggle-text-editor']": 'toggleTextEditor',
},
initialize: function(opt){
this.parent = opt.parent
},
- toggleMap: function(){
- map.toggle()
- // $("#minimap").toggleClass("hide");
+ undo: function(e){
+ if (e.shiftKey) {
+ var canRedo = UndoStack.redo()
+ console.log("can redo", canRedo)
+ }
+ else {
+ var canUndo = UndoStack.undo()
+ console.log("can undo", canUndo)
+ }
+ },
+
+ toggleMap: function(state){
+// if (typeof state != "boolean") {
+// state = ! $("[data-role='toggle-map-view']").hasClass("inuse")
+// this.resetControls()
+// }
+// $("[data-role='toggle-map-view']").toggleClass("inuse", state)
+ var state = map.toggle(state)
+ if (state) { map.ui.blur() }
+ $("#minimap").toggleClass("hide", state)
+ this.parent.info.toggle(state)
},
toggleSettings: function(){
- this.resetMode()
- $(".inuse").removeClass("inuse")
- this.parent.lightControl.hide()
+// this.resetMode()
+ this.toggleMap(false)
+ this.parent.textEditor.hide()
+ this.parent.presets.hide()
+ this.parent.colorControl.hide()
this.parent.wallpaperPicker.hide()
this.parent.mediaEditor.hide()
this.parent.settings.toggle()
},
openMediaViewer: function(){
- this.parent.mediaViewer.show()
- this.parent.mediaUpload.show()
this.resetMode()
this.resetControls()
+ this.toggleMap(false)
+ this.parent.mediaViewer.show()
},
-
+
resetMode: function(){
- this.resizeMedia(false)
- this.destroyMedia(false)
+ $(".inuse").removeClass("inuse")
+ $("body").removeClass("addText")
+ this.parent.hideExtras()
+ this.resetPermissions()
},
resetControls: function(){
+ $(".inuse").removeClass("inuse")
+ this.toggleMap(false)
+ this.parent.textEditor.hide()
this.parent.wallpaperPicker.hide()
- this.parent.lightControl.hide()
- },
-
- resizeMedia: function(e, state){
- this.resetControls()
- if (! state && typeof e == "boolean") {
- state = e
- editor.permissions.assign("resize", state)
- }
- else {
- state = editor.permissions.toggle("resize")
- }
- ! state && editor.permissions.assign("move", true)
- $(".inuse").removeClass("inuse")
- $("[data-role='resize-media']").toggleClass("inuse", state)
- if (state) {
- if (this.parent.mediaEditor.scenery) {
- Scenery.resize.show( this.parent.mediaEditor.scenery )
- }
- }
- else {
- Scenery.resize.hide()
- }
+ this.parent.presets.hide()
+ this.parent.colorControl.hide()
+ this.parent.settings.hide()
},
- destroyMedia: function(e, state){
- this.resetControls()
- if (! state && typeof e == "boolean") {
- state = e
- editor.permissions.assign("destroy", state)
- }
- else {
- state = editor.permissions.toggle("destroy")
- }
- ! state && editor.permissions.assign("move", true)
- $(".inuse").removeClass("inuse")
- $("[data-role='destroy-media']").toggleClass("inuse", state)
- $("body").toggleClass("destroyActive", state)
+ resetPermissions: function(){
+ editor.permissions.add("pick")
+ editor.permissions.add("move")
+ editor.permissions.add("resize")
+ editor.permissions.remove("destroy")
},
toggleWallpaper: function(){
@@ -90,31 +90,67 @@ var EditorToolbar = View.extend({
this.resetMode()
$("[data-role='toggle-wallpaper-panel']").toggleClass("inuse", state)
this.parent.mediaEditor.hide()
- this.parent.lightControl.hide()
+ this.parent.colorControl.hide()
+ this.parent.textEditor.hide()
this.parent.settings.hide()
+ this.parent.presets.hide()
+ this.toggleMap(false)
this.parent.wallpaperPicker.toggle(state)
},
- toggleLightControl: function(){
- var state = ! $("[data-role='toggle-light-control']").hasClass("inuse")
+ toggleColorControl: function(){
+ var state = ! $("[data-role='toggle-color-control']").hasClass("inuse")
this.resetMode()
- $("[data-role='toggle-light-control']").toggleClass("inuse", state)
+ $("[data-role='toggle-color-control']").toggleClass("inuse", state)
this.parent.mediaEditor.hide()
this.parent.wallpaperPicker.hide()
+ this.parent.textEditor.hide()
this.parent.settings.hide()
- this.parent.lightControl.toggle(state)
+ this.parent.presets.hide()
+ this.toggleMap(false)
+ this.parent.colorControl.toggle(state)
},
- editWallText: function(){
- },
+ toggleTextEditor: function(){
+ var state = ! $("[data-role='toggle-text-editor']").hasClass("inuse")
+ this.resetMode()
+ $("[data-role='toggle-text-editor']").toggleClass("inuse", state)
+ this.parent.mediaEditor.hide()
+ this.parent.wallpaperPicker.hide()
+ this.parent.colorControl.hide()
+ this.parent.settings.hide()
+ this.parent.presets.hide()
+ this.toggleMap(false)
+ this.parent.textEditor.toggle(state)
+ },
+ togglePresets: function(){
+ var state = ! $("[data-role='toggle-presets']").hasClass("inuse")
+ this.resetMode()
+ $("[data-role='toggle-presets']").toggleClass("inuse", state)
+ this.parent.mediaEditor.hide()
+ this.parent.wallpaperPicker.hide()
+ this.parent.textEditor.hide()
+ this.parent.settings.hide()
+ this.parent.colorControl.hide()
+ this.toggleMap(false)
+ this.parent.presets.toggle(state)
+ },
+
+ mouseenter: function(){
+ this.parent.cursor.hide()
+ },
+
+ mouseleave: function(){
+ this.parent.cursor.show()
+ },
})
var editor = new function(){
this.permissions = new Permissions({
'pick': true,
'move': true,
- 'resize': false,
+ 'resize': true,
'destroy': false,
})
} \ No newline at end of file
diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js
index e11f189..c05b373 100644
--- a/public/assets/javascripts/ui/editor/EditorView.js
+++ b/public/assets/javascripts/ui/editor/EditorView.js
@@ -2,6 +2,7 @@
var EditorView = View.extend({
el: "#editorView",
+ blueprintAction: "/api/blueprint/user/",
projectAction: "/api/project/",
layoutAction: "/api/layout/",
@@ -9,14 +10,21 @@ var EditorView = View.extend({
},
initialize: function(){
+ this.cursor = new HelpCursor ({ parent: this })
this.toolbar = new EditorToolbar ({ parent: this })
this.settings = new EditorSettings ({ parent: this })
+ this.info = new BuilderInfo ({ parent: this })
this.mediaViewer = new MediaViewer ({ parent: this })
this.mediaUpload = new MediaUpload ({ parent: this })
+ this.mediaTumblr = new MediaTumblr ({ parent: this })
this.mediaEditor = new MediaEditor ({ parent: this })
+ this.sculptureEditor = new SculptureEditor ({ parent: this })
this.wallpaperPicker = new WallpaperPicker ({ parent: this })
- this.lightControl = new LightControl ({ parent: this })
+ this.colorControl = new ColorControl ({ parent: this })
+ this.textEditor = new TextEditor ({ parent: this })
this.collaborators = new Collaborators ({ parent: this })
+ this.presets = new Presets ({ parent: this })
+ this.share = new ShareView ({ parent: this })
},
load: function(name){
@@ -25,27 +33,65 @@ var EditorView = View.extend({
},
loadLayout: function(layout){
+ if (layout == "empty") {
+ this.readyLayout({})
+ this.toolbar.toggleMap()
+ return
+ }
layout = sanitize(layout)
$.get(this.layoutAction + layout, this.readyLayout.bind(this))
},
+ loadBlueprint: function(blueprint){
+ $.get(this.blueprintAction + blueprint, this.readyLayout.bind(this))
+ },
+
ready: function(data){
$("#map").hide()
-
+
+ this.data = data
+
this.settings.load(data)
+ this.info.load(data)
},
readyLayout: function(data){
data.isNew = true
+ // $('#help-button').trigger("click")
this.ready(data)
},
pick: function(scenery){
- this.mediaEditor.pick(scenery)
+ if (scenery.isSculpture) {
+ this.mediaEditor.hide()
+ this.textEditor.hide()
+ this.sculptureEditor.pick(scenery)
+ }
+ else if (scenery.type == "text") {
+ this.mediaEditor.hide()
+ this.sculptureEditor.hide()
+ this.textEditor.pick(scenery)
+ }
+ else {
+ this.textEditor.hide()
+ this.sculptureEditor.hide()
+ this.mediaEditor.pick(scenery)
+ }
+ },
+
+ pickWall: function(wall, pos){
+ this.hideExtras()
+ this.wallpaperPicker.pickWall(wall)
},
hideExtras: function(){
+ this.sculptureEditor.hide()
this.mediaEditor.hide()
- }
+ this.textEditor.hide()
+ this.share.hide()
+ Sculpture.resize.hide()
+ Scenery.resize.hide()
+ Scenery.hovering = false
+ }
})
diff --git a/public/assets/javascripts/ui/editor/HelpCursor.js b/public/assets/javascripts/ui/editor/HelpCursor.js
new file mode 100644
index 0000000..4c8ff0c
--- /dev/null
+++ b/public/assets/javascripts/ui/editor/HelpCursor.js
@@ -0,0 +1,79 @@
+
+var HelpCursor = View.extend({
+ el: "#helpCursor",
+
+ active: false,
+
+ messages: {
+ start: "Welcome to VValls! Click one of the tools at right to learn about it.",
+ media: "This is where you pick media to go on the walls. You can upload media and paste links.",
+ addmedia: "Great, now click a wall to place this image.",
+ resize: "Drag the image to position it, or use the dots to resize.",
+ presets: "These are some basic presets to get you started. Click em! :-)",
+ wallpaper: "Click the wallpaper you want then apply it to the walls. Feel free to upload your own too!",
+ colors: "Use these colors to change the color of the walls, floor, and ceiling.",
+ settings: "This is where you publish your project. Give it a name, hit save, and you'll have a URL you can share with your friends.",
+ builder: "This is a map of your rooms. Draw new boxes, or move and resize the ones that are there. Hit ESCAPE to toggle the map.",
+ },
+
+ initialize: function(){
+ this.helpButton = $('#help-button')
+
+ this.helpButton.click(this.toggle.bind(this))
+ this.$el.html(this.messages['start'])
+ },
+
+ toggle: function(){
+ this.active ? this.stop() : this.start()
+ },
+
+ start: function(){
+ if (this.active) return
+ this.active = true
+ this.helpButton.addClass('active')
+ this.$el.show()
+ this.move({ pageX: -1000, pageY: -10000 })
+ this.moveFn = this.move.bind(this)
+ document.addEventListener("mousemove", this.moveFn)
+ },
+
+ stop: function(){
+ this.active = false
+ this.$el.hide()
+ this.helpButton.removeClass('active')
+ document.removeEventListener("mousemove", this.moveFn)
+ },
+
+ offset: 100,
+ lastPosition: { pageX: 0, pageY: 0 },
+ move: function(e){
+ this.el.style.right = clamp(window.innerWidth - e.pageX, this.offset, window.innerWidth) + "px"
+ this.el.style.top = e.pageY + "px"
+ this.lastPosition = e
+ },
+
+ show: function(name){
+ if (this.active) {
+ this.$el.show()
+ }
+ },
+ hide: function(){
+ this.$el.hide()
+ },
+
+ message: function(name){
+ if (! this.active) return
+ if (name == "start" || name == "media" || name == "settings") {
+ this.offset = 100
+ }
+ else if (name == "colors") {
+ this.offset = 270
+ }
+ else {
+ this.offset = 290
+ }
+ this.move(this.lastPosition)
+ this.$el.html(this.messages[name])
+ },
+
+})
diff --git a/public/assets/javascripts/ui/editor/MediaEditor.js b/public/assets/javascripts/ui/editor/MediaEditor.js
index 9b20a43..6068c48 100644
--- a/public/assets/javascripts/ui/editor/MediaEditor.js
+++ b/public/assets/javascripts/ui/editor/MediaEditor.js
@@ -3,7 +3,7 @@ var MediaEditor = FormView.extend({
el: "#mediaEditor",
events: {
- "keydown": 'stopPropagation',
+ "keydown": 'taint',
"focus [name]": "clearMinotaur",
"click [data-role=play-media]": "togglePaused",
"mousedown [name=keyframe]": "stopPropagation",
@@ -51,40 +51,56 @@ var MediaEditor = FormView.extend({
},
pick: function(scenery) {
- if (this.scenery) {
+ if (this.scenery && scenery !== this.scenery) {
this.unbind()
}
this.bind(scenery)
this.$el.addClass("active")
+// app.controller.toolbar.resetMode()
+ app.controller.toolbar.resetControls()
+ Scenery.resize.show(scenery)
+ Scenery.hovering = true
+
var media = scenery.media
- this.$name.val(media.title)
+ // console.log(media)
+
+ this.$name.val(media.title) // || filenameFromUrl(media.url) )
this.$description.val(media.description)
this.setDimensions()
this.$units.val( "ft" )
switch (media.type) {
case "image":
- this.$(".image").show()
this.$(".video").hide()
-
+ this.$(".audio").hide()
+ this.$(".image").show()
break
case "youtube":
case "vimeo":
case "video":
- this.$(".video").show()
this.$(".image").hide()
+ this.$(".audio").hide()
+ this.$(".video").show()
this.$playButton.toggleClass("paused", ! this.scenery.paused())
this.$autoplay.prop('checked', !! media.autoplay)
this.$loop.prop('checked', !! media.loop)
this.$mute.prop('checked', !! media.mute)
this.$keyframe.val( Number(media.keyframe || 0) )
-
break
+
+ case "soundcloud":
+ this.$(".image").hide()
+ this.$(".video").hide()
+ this.$(".audio").show()
+ this.$playButton.toggleClass("paused", ! this.scenery.paused())
+ this.$autoplay.prop('checked', !! media.autoplay)
+ this.$loop.prop('checked', !! media.loop)
+ break
}
},
@@ -98,12 +114,14 @@ var MediaEditor = FormView.extend({
seek: function(){
var n = parseFloat( this.$keyframe.val() )
this.scenery.seek(n)
+ this.tainted = true
this.scenery.media.keyframe = n
},
setAutoplay: function(){
var checked = this.$autoplay.prop('checked')
this.scenery.media.autoplay = checked
+ this.tainted = true
if (checked && this.scenery.paused()) {
this.togglePaused()
}
@@ -111,17 +129,20 @@ var MediaEditor = FormView.extend({
setLoop: function(){
var checked = this.$loop.prop('checked')
this.scenery.setLoop(checked)
+ this.tainted = true
},
setMute: function(){
var checked = this.$mute.prop('checked')
this.scenery.media.mute = checked
this.scenery.mute(checked)
+ this.tainted = true
},
setDimensions: function(){
if (! this.scenery) return
this.$width.unitVal( Number(this.scenery.naturalDimensions.a * this.scenery.scale) || "" )
this.$height.unitVal( Number(this.scenery.naturalDimensions.b * this.scenery.scale) || "" )
+ this.tainted = true
},
changeWidth: function(e){
e.stopPropagation()
@@ -137,6 +158,11 @@ var MediaEditor = FormView.extend({
app.units = this.$units.val()
this.$('.units').resetUnitVal()
},
+
+ taint: function(e){
+ e.stopPropagation()
+ this.tainted = true
+ },
bind: function(scenery){
this.scenery = scenery
@@ -146,24 +172,29 @@ var MediaEditor = FormView.extend({
unbind: function(){
if (this.scenery) {
- this.scenery.media.title = this.$name.val()
- this.scenery.media.description = this.$description.val()
- Minotaur.watch( app.router.editorView.settings )
-
+ this.scenery.focused = false
+ if (this.tainted && this.scenery.media) {
+ this.scenery.media.title = this.$name.val()
+ this.scenery.media.description = this.$description.val()
+ Minotaur.watch( app.router.editorView.settings )
+ }
if (this.scenery.mx) {
this.scenery.mx.bound = false
this.scenery.mx.el.classList.remove("picked")
}
}
+ this.tainted = false
this.scenery = null
},
destroy: function(){
- ConfirmModal.confirm("Are you sure you want delete to this media?", function(){
- var scenery = this.scenery
- this.hide()
- Scenery.remove(scenery.id)
- }.bind(this))
+ var scenery = this.scenery
+ this.hide()
+
+ scenery.remove()
+
+ this.tainted = false
+ this.scenery = null
},
})
diff --git a/public/assets/javascripts/ui/editor/MediaTumblr.js b/public/assets/javascripts/ui/editor/MediaTumblr.js
new file mode 100644
index 0000000..47419ae
--- /dev/null
+++ b/public/assets/javascripts/ui/editor/MediaTumblr.js
@@ -0,0 +1,53 @@
+
+var MediaTumblr = ModalView.extend({
+ el: "#tumblrUpload",
+
+ events: {
+ 'mousedown': "stopPropagation",
+ "keydown .url": "enterSubmit",
+ "click .exampleTumblr": "loadExample",
+ },
+
+ initialize: function(opt){
+ this.__super__.initialize.call(this)
+ this.parent = opt.parent
+ this.$url = this.$(".url")
+ },
+
+ show: function(){
+ this.$el.addClass("active")
+ this.$url.val("")
+ },
+
+ hide: function(){
+ this.$el.removeClass("active")
+ },
+
+ enterSubmit: function(e){
+ e.stopPropagation()
+ if (e.keyCode == 13) {
+ e.preventDefault()
+ var url = this.$tumblrUrl.val()
+ this.loadTumblr(url)
+ }
+ },
+
+ loadTumblr: function(url){
+ Parser.tumblr(url, function(media_list){
+ console.log(media_list)
+ this.parent.mediaViewer.$foundMediaContainer.empty()
+ media_list.reverse().forEach(function(media){
+ this.parent.mediaViewer.add(media, this.parent.mediaViewer.$foundMediaContainer)
+ }.bind(this))
+ }.bind(this))
+ },
+
+ loadExample: function(e){
+ e.preventDefault()
+ var name = $(e.currentTarget).html()
+ var url = "http://" + name + ".tumblr.com/"
+ this.$url.val(url)
+ this.loadTumblr(url)
+ },
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/editor/MediaUpload.js b/public/assets/javascripts/ui/editor/MediaUpload.js
index 92cf2bd..d09e38c 100644
--- a/public/assets/javascripts/ui/editor/MediaUpload.js
+++ b/public/assets/javascripts/ui/editor/MediaUpload.js
@@ -1,11 +1,12 @@
var MediaUpload = UploadView.extend({
- el: ".fileUpload",
+ el: "#fileUpload",
createAction: "/api/media/new",
uploadAction: "/api/media/upload",
events: {
+ 'mousedown': "stopPropagation",
"keydown .url": "enterSubmit",
},
@@ -25,6 +26,7 @@ var MediaUpload = UploadView.extend({
},
enterSubmit: function(e){
+ e.stopPropagation()
if (e.keyCode == 13) {
e.preventDefault()
this.parse()
@@ -34,7 +36,10 @@ var MediaUpload = UploadView.extend({
parse: function(){
var url = this.$url.val()
this.$url.val("")
-
+ this.parseUrl(url)
+ },
+
+ parseUrl: function(url){
Parser.parse(url, function(media){
if (! media) {
alert("Not a valid image/video link")
@@ -42,7 +47,6 @@ var MediaUpload = UploadView.extend({
}
media._csrf = $("[name=_csrf]").val()
- console.log(media)
var request = $.ajax({
type: "post",
@@ -52,10 +56,15 @@ var MediaUpload = UploadView.extend({
request.done(this.add.bind(this))
}.bind(this))
},
-
+
add: function(media){
console.log(media)
- this.parent.mediaViewer.add(media)
+ this.parent.mediaViewer.addUploadedMedia(media)
+ },
+
+ error: function(error){
+ console.log(error)
+ alert(error.errors.media.message)
},
beforeUpload: function(){
diff --git a/public/assets/javascripts/ui/editor/MediaViewer.js b/public/assets/javascripts/ui/editor/MediaViewer.js
index 436c0cb..2ae5104 100644
--- a/public/assets/javascripts/ui/editor/MediaViewer.js
+++ b/public/assets/javascripts/ui/editor/MediaViewer.js
@@ -3,44 +3,82 @@ var MediaViewer = ModalView.extend({
el: ".mediaDrawer.mediaViewer",
destroyAction: "/api/media/destroy",
usesFileUpload: true,
-
+ loaded: false,
+ perPage: 12,
+ offset: 0,
+ fixedClose: true,
+
events: {
+ 'mousedown': "stopPropagation",
'click .foundToggle': "foundToggle",
'click .userToggle': "userToggle",
'click #deleteMedia': "deleteArmed",
+ 'click #randomize': "randomize",
'click .mediaContainer': "pick",
+ 'click .viewMore': "load",
+ 'keydown #tumblr-url': 'enterTumblrUrl',
},
initialize: function(opt){
this.__super__.initialize.call(this)
this.parent = opt.parent
+
+ this.$myMedia = this.$(".myMedia").addClass('active')
+ this.$myMediaContainer = this.$(".myMedia > .container")
+ this.$userToggle = this.$(".userToggle")
+
this.$foundMedia = this.$(".foundMedia")
- this.$myMedia = this.$(".myMedia")
+ this.$foundMediaContainer = this.$(".foundMedia > .container")
this.$foundToggle = this.$(".foundToggle")
- this.$userToggle = this.$(".userToggle")
+
+ this.$wallpaperMedia = this.$(".wallpaperMedia")
+ this.$wallpaperMediaContainer = this.$(".wallpaperMedia > .container")
+ this.$wallpaperToggle = this.$(".wallpaperToggle")
+
this.$deleteMedia = this.$("#deleteMedia")
- },
+ this.$viewMore = this.$(".viewMore")
+ this.$noMedia = this.$(".noMedia")
+ },
+ mode: "user",
+ wallpaperToggle: function(){
+ this.mode = "wallpaper"
+ this.$wallpaperMedia.addClass("active")
+ this.$foundMedia.addClass("inactive")
+ this.$myMedia.addClass("inactive").removeClass('active')
+ this.$("a").removeClass("active")
+ this.$foundToggle.addClass("active")
+ },
+
foundToggle: function(){
- this.foundMedia.addClass("active");
- this.myMedia.addClass("inactive");
- this.$("a").removeClass("active");
- this.foundToggle.addClass("active");
+ this.mode = "found"
+ this.$wallpaperMedia.removeClass("active")
+ this.$foundMedia.addClass("active")
+ this.$myMedia.addClass("inactive").removeClass('active')
+ this.$("a").removeClass("active")
+ this.$foundToggle.addClass("active")
+ this.parent.mediaUpload.hide()
+ this.parent.mediaTumblr.show()
},
userToggle: function(){
- this.foundMedia.removeClass("active");
- this.myMedia.removeClass("inactive");
- this.$("a").removeClass("active");
- this.userToggle.addClass("active");
+ this.mode = "user"
+ this.$wallpaperMedia.removeClass("active")
+ this.$foundMedia.removeClass("active")
+ this.$myMedia.removeClass("inactive").addClass('active')
+ this.$("a").removeClass("active")
+ this.$userToggle.addClass("active")
+ this.parent.mediaUpload.show()
+ this.parent.mediaTumblr.hide()
},
show: function(){
if (! this.loaded) {
this.load()
+ // this.loadTrending()
}
else {
- this.__super__.show.call(this)
+ this.reallyShow()
}
},
@@ -48,24 +86,110 @@ var MediaViewer = ModalView.extend({
this.__super__.hide.call(this)
this.deleteArmed(false)
this.parent.mediaUpload.hide()
+ this.parent.mediaTumblr.hide()
+ this.parent.cursor.message('start')
+ },
+
+ reallyShow: function(){
+ this.__super__.show.call(this)
+ if (this.mode == "user") {
+ this.userToggle()
+ }
+ else {
+ this.foundToggle()
+ }
+ this.parent.cursor.message("media")
},
load: function(){
- $.get("/api/media/user", this.populate.bind(this))
+ $.get("/api/media/user", { offset: this.offset, limit: this.perPage }, this.populate.bind(this))
+ },
+
+/*
+ loadTrending: function(){
+ var trending_imagery = [
+ 'https://d1ycxz9plii3tb.cloudfront.net/post_images/52ec0e20c9dc24f1d8000067/large.jpg',
+ 'https://d1ycxz9plii3tb.cloudfront.net/additional_images/4e6bf67bc23f490001004579/1/tall.jpg',
+ 'https://d1ycxz9plii3tb.cloudfront.net/additional_images/52dcca28139b2135030002a8/tall.jpg',
+ 'https://d1ycxz9plii3tb.cloudfront.net/additional_images/52927bb2b202a3669d000704/larger.jpg',
+ 'https://d1ycxz9plii3tb.cloudfront.net/additional_images/4f9f3a3ce262e60001000fb3/large.jpg',
+ 'http://2.bp.blogspot.com/-GD6IxUvsdOo/UdrcMFLVYNI/AAAAAAAAF2E/kbRfxMxiUlQ/s1600/okeeffe.jpg',
+ 'http://www.bobkessel.com/wordpress/wp-content/uploads/2009/10/moma-bob-kessel-410.jpg',
+ 'http://static1.artsy.net/partner_show_images/52f28f348b3b81f2fc000364/large.jpg',
+ 'http://static3.artsy.net/partner_show_images/52e83674c9dc24397f0000d8/large.jpg',
+ 'http://static0.artsy.net/partner_show_images/52d96d484b84801ef0000273/large.jpg',
+ 'http://static1.artsy.net/partner_show_images/52778616275b24f95c00011d/1/large.jpg',
+ 'http://static1.artsy.net/partner_show_images/52dc65311a1e86be6b000205/large.jpg',
+ ]
+ trending_imagery.forEach(function(url){
+ var loaded = false
+ var img = new Image ()
+ img.onload = function(){
+ if (loaded) return
+ loaded = true
+ var media = {
+ type: 'image',
+ url: url,
+ width: img.naturalWidth,
+ height: img.naturalHeight,
+ }
+ this.add(media, this.$foundMediaContainer)
+ }.bind(this)
+ img.src = url
+ if (img.complete && ! loaded) { img.onload() }
+ }.bind(this))
},
+*/
+
+ randomize: function(){
+ var $divs = this.$(".active .container").find(".mediaContainer").toArray()
+ if ($divs.length < 3) {
+ $divs = $divs.concat( this.$foundMediaContainer.find(".mediaContainer").toArray() )
+ }
+ var media_objs = $divs.map(function(el){
+ return $(el).data("media")
+ })
+ Scenery.randomize.add( media_objs )
+ this.hide()
+ },
populate: function(data){
- this.loaded = true
+ var scrollTop = this.loaded ? $('.myMedia .container').height() : 0
if (data && data.length) {
- data.forEach(this.add.bind(this))
+ if (data.length < this.perPage) {
+ this.$viewMore.hide()
+ }
+ data.forEach(function(media){
+ this.add(media, this.$myMediaContainer)
+ this.offset += 1
+ }.bind(this))
+ this.$noMedia.hide()
+ this.$deleteMedia.show()
}
else {
+ this.$viewMore.hide()
+ this.$noMedia.show()
this.$deleteMedia.hide()
}
- this.__super__.show.call(this)
+ if (this.loaded) {
+ this.$el.delay(300).animate({ scrollTop: scrollTop }, 200)
+ }
+ else {
+ this.loaded = true
+ this.reallyShow()
+ }
+ },
+
+ addUploadedMedia: function(media){
+ this.$deleteMedia.show()
+ this.$noMedia.hide()
+ this.add(media, this.$myMedia, true) // prepend
+ this.userToggle()
+ this.$el.scrollTop(0)
+ this.offset += 1
},
- add: function(media){
+ add: function(media, $container, prepend){
var image = new Image ()
var $span = $("<span>")
$span.addClass("mediaContainer")
@@ -87,13 +211,17 @@ var MediaViewer = ModalView.extend({
image.src = media.url
image.load()
break
+
+ case 'soundcloud':
+ image.src = media.thumbnail
+ break
}
$span.data("media", media)
$span.append(image)
- this.$(".myMedia").prepend($span)
- this.$deleteMedia.show()
+ if (prepend) $container.prepend($span)
+ else $container.append($span)
},
deleteIsArmed: false,
@@ -131,35 +259,23 @@ var MediaViewer = ModalView.extend({
if ($(".myMedia .mediaContainer").length == 0) {
this.$deleteMedia.hide()
+ this.$noMedia.show()
this.deleteArmed(false)
}
return
}
-// else {
-// this.picked = {}
-// this.picked.media = media
-// this.picked.image = image
-// }
-// },
-//
-// drag: function(e){
-// if (! this.pickedMedia) return
-// var media = this.picked.media
-// var image = this.picked.image
-// this.picked = null
-
this.hide()
-
+ this.parent.cursor.message('addmedia')
+
var $ants = $('.ants');
var $floatingImg = $('.floatingImg');
Scenery.nextMedia = media
-// console.log(media.type)
-
switch (media.type) {
case "video":
+ case "soundcloud":
$floatingImg.attr('src', '/assets/img/playbutton.png')
break
@@ -185,12 +301,15 @@ var MediaViewer = ModalView.extend({
$floatingImg.attr('src', '')
$(window).off('mousemove', _followCursor)
$(window).off('mousedown', _hideCursor)
+ app.off('cancel-scenery', _hideCursor)
$floatingImg.parent().removeClass('edit')
+ app.controller.cursor.message('resize')
}
$(window).on('mousemove', _followCursor)
$(window).on('mousedown', _hideCursor)
+ app.on('cancel-scenery', _hideCursor)
$ants.addClass('edit')
_followCursor(e)
},
-
+
})
diff --git a/public/assets/javascripts/ui/editor/Presets.js b/public/assets/javascripts/ui/editor/Presets.js
new file mode 100644
index 0000000..5f5ac35
--- /dev/null
+++ b/public/assets/javascripts/ui/editor/Presets.js
@@ -0,0 +1,122 @@
+var Presets = View.extend({
+ el: "#presets",
+
+ events: {
+ "mousedown": "stopPropagation",
+ "click .presets span": "selectPreset",
+ },
+
+ presets: {
+ wireframe: {
+ wall: [255,255,255],
+ outline: [0,0,0],
+ floor: [246,246,246],
+ ceiling: [255,255,255],
+ },
+ shaded: {
+ wall: [205,205,204],
+ outline: [0,0,0],
+ floor: [109,116,106],
+ ceiling: [159,163,157],
+ background: [109,116,106],
+ },
+ "P.Funk": {
+ wall: [255,63,78],
+ outline: [255,246,0],
+ floor: [255,255,0],
+ ceiling: [225,118,252],
+ },
+ inverse: {
+ wall: [0,0,0],
+ outline: [255,255,255],
+ floor: [0,0,0],
+ ceiling: [0,0,0],
+ },
+ matrix: {
+ wall: { src: "http://dumpfm.s3.amazonaws.com/images/20130225/1361818675427-dumpfm-melipone-matrixremixtransfast.gif", scale: 4.0, color: [0,0,0] },
+ outline: [0,0,0],
+ floor: [10,15,10],
+ ceiling: [0,0,0],
+ },
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+
+ this.$presets = this.$(".presets")
+ _.keys(this.presets).forEach(function(name){
+ var $swatch = $("<span>")
+ $swatch.html(capitalize(name))
+ $swatch.data('preset', name)
+ this.$presets.append($swatch)
+ }.bind(this))
+ },
+
+ modified: true,
+ lastPreset: "wireframe",
+
+ toggle: function(state){
+ this.$el.toggleClass("active", state)
+ this.parent.cursor.message(state ? "presets" : "start")
+ if (this.modified) {
+ this.$(".active").removeClass('active')
+ }
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+
+ hide: function(){
+ this.toggle(false)
+ },
+
+ selectPreset: function(e){
+ var preset = $(e.currentTarget).data('preset')
+ if (! this.presets[preset]) return
+ this.$(".active").removeClass('active')
+ $(e.currentTarget).addClass('active')
+ if (this.modified) {
+ UndoStack.push({
+ type: "choose-preset",
+ undo: { walls: Walls.serialize(), colors: Walls.copyColors(Walls.colors) },
+ redo: preset,
+ })
+ Minotaur.watch( app.router.editorView.settings )
+ }
+ else {
+ UndoStack.push({
+ type: "choose-another-preset",
+ undo: this.lastPreset,
+ redo: preset,
+ })
+ Minotaur.watch( app.router.editorView.settings )
+ }
+ this.lastPreset = preset
+ this.load(this.presets[preset])
+ this.modified = false
+ },
+
+ loadByName: function(name){
+ var preset = this.presets[name]
+ this.load(preset)
+ },
+ load: function(preset){
+ this.parent.colorControl.modes.forEach(function(mode){
+ var color
+ if (! preset[mode].length) {
+ Walls.setWallpaper[mode](preset[mode])
+ color = preset[mode].color
+ }
+ else {
+ Walls.clearWallpaper[mode]()
+ color = preset[mode]
+ }
+ Walls.setColor[mode](color)
+ this.parent.colorControl.$swatch[ mode ].css("background-color", rgb_string(color))
+ }.bind(this))
+ this.parent.colorControl.setMode(preset.wall.color ? "wall" : "floor")
+ Walls.setBodyColor()
+ },
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js
new file mode 100644
index 0000000..953260c
--- /dev/null
+++ b/public/assets/javascripts/ui/editor/SculptureEditor.js
@@ -0,0 +1,237 @@
+
+var SculptureEditor = FormView.extend({
+ el: "#sculptureEditor",
+
+ events: {
+ "keydown": 'taint',
+ "focus [name]": "clearMinotaur",
+ "click [data-role=play-media]": "togglePaused",
+ "mousedown [name=keyframe]": "stopPropagation",
+ "mousedown": "stopPropagation",
+ "change [name=keyframe]": "seek",
+ "change [name=autoplay]": "setAutoplay",
+ "change [name=billboard]": "setBillboard",
+ "change [name=outline]": "setOutline",
+ "change [name=outlineColor]": "setOutlineColor",
+ "change [name=loop]": "setLoop",
+ "change [name=mute]": "setMute",
+ "change [name=width]": 'changeWidth',
+ "change [name=height]": 'changeHeight',
+ "change [name=depth]": 'changeDepth',
+ "change [name=units]": 'changeUnits',
+ "click [data-role=destroy-sculpture]": "destroy",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ this.$name = this.$("[name=name]")
+ this.$description = this.$("[name=description]")
+
+ this.$billboard = this.$("[name=billboard]")
+ this.$outline = this.$("[name=outline]")
+ this.$outlineColor = this.$("[name=outlineColor]")
+
+ // image fields
+ this.$width = this.$("[name=width]")
+ this.$height = this.$("[name=height]")
+ this.$depth = this.$("[name=depth]")
+ this.$units = this.$("[name=units]")
+
+ // video fields
+ this.$playButton = this.$("[data-role=play-media]")
+ this.$autoplay = this.$("[name=autoplay]")
+ this.$loop = this.$("[name=loop]")
+ this.$mute = this.$("[name=mute]")
+ this.$keyframe = this.$("[name=keyframe]")
+ },
+
+ toggle: function(state) {
+ if (state) {
+ this.parent.settings.toggle()
+ }
+ this.$el.toggleClass("active", state);
+ },
+
+ togglePaused: function(state){
+ var state = this.sculpture.toggle(state)
+ this.$playButton.toggleClass("paused", ! state)
+ },
+
+ pick: function(sculpture) {
+ if (this.sculpture && sculpture !== this.sculpture) {
+ this.unbind()
+ }
+
+ this.bind(sculpture)
+ this.$el.addClass("active")
+
+// app.controller.toolbar.resetMode()
+ app.controller.toolbar.resetControls()
+ Sculpture.resize.show(sculpture)
+ Sculpture.hovering = true
+
+ var media = sculpture.media
+
+ // console.log(media)
+ this.$name.val(media.title || "") // || filenameFromUrl(media.url) )
+ this.$description.val(media.description || "")
+ this.setDimensions()
+ this.$units.val( "ft" )
+
+ this.$outline.prop( 'checked', !! sculpture.outline )
+ this.$outlineColor.val( sculpture.outlineColor || "#000000" )
+ this.$billboard.prop( 'checked', !! sculpture.billboard )
+
+ switch (media.type) {
+ case "image":
+ this.$(".video").hide()
+ this.$(".audio").hide()
+ this.$(".image").show()
+ break
+
+ case "youtube":
+ case "vimeo":
+ case "video":
+ this.$(".image").hide()
+ this.$(".audio").hide()
+ this.$(".video").show()
+
+ this.$playButton.toggleClass("paused", ! this.sculpture.paused())
+ this.$autoplay.prop('checked', !! media.autoplay)
+ this.$loop.prop('checked', !! media.loop)
+ this.$mute.prop('checked', !! media.mute)
+ this.$keyframe.val( Number(media.keyframe || 0) )
+ break
+
+ case "soundcloud":
+ this.$(".image").hide()
+ this.$(".video").hide()
+ this.$(".audio").show()
+ this.$playButton.toggleClass("paused", ! this.sculpture.paused())
+ this.$autoplay.prop('checked', !! media.autoplay)
+ this.$loop.prop('checked', !! media.loop)
+ break
+ }
+ },
+
+ hide: function(sculpture){
+ if (this.sculpture) {
+ this.unbind()
+ }
+ this.toggle(false)
+ },
+
+ seek: function(){
+ var n = parseFloat( this.$keyframe.val() )
+ this.sculpture.seek(n)
+ this.tainted = true
+
+ this.sculpture.media.keyframe = n
+ },
+ setAutoplay: function(){
+ var checked = this.$autoplay.prop('checked')
+ this.sculpture.media.autoplay = checked
+ this.tainted = true
+ if (checked && this.sculpture.paused()) {
+ this.togglePaused()
+ }
+ },
+ setLoop: function(){
+ var checked = this.$loop.prop('checked')
+ this.sculpture.setLoop(checked)
+ this.tainted = true
+ },
+ setMute: function(){
+ var checked = this.$mute.prop('checked')
+ this.sculpture.media.mute = checked
+ this.sculpture.mute(checked)
+ this.tainted = true
+ },
+
+ setBillboard: function(){
+ var checked = this.$billboard.prop('checked')
+ this.sculpture.setBillboard(checked)
+ this.tainted = true
+ },
+ setOutline: function(){
+ var checked = this.$outline.prop('checked')
+ this.sculpture.setOutline(checked)
+ this.tainted = true
+ },
+ setOutlineColor: function(){
+ var color = this.$outlineColor.val()
+ this.sculpture.setOutlineColor(color)
+ this.tainted = true
+ },
+
+ setDimensions: function(){
+ if (! this.sculpture) return
+ this.$width.unitVal( Number(this.sculpture.naturalDimensions.a * this.sculpture.scale) || "" )
+ this.$height.unitVal( Number(this.sculpture.naturalDimensions.b * this.sculpture.scale) || "" )
+ this.$depth.unitVal( Number(this.sculpture.naturalDimensions.c * this.sculpture.scale) || "" )
+ this.tainted = true
+ },
+ changeWidth: function(e){
+ e.stopPropagation()
+ this.sculpture.set_scale( this.$width.unitVal() / this.sculpture.naturalDimensions.a )
+ this.setDimensions()
+ this.sculpture.updateOutline()
+ },
+ changeHeight: function(e){
+ e.stopPropagation()
+ this.sculpture.set_scale( this.$height.unitVal() / this.sculpture.naturalDimensions.b )
+ this.setDimensions()
+ this.sculpture.updateOutline()
+ },
+ changeDepth: function(e){
+ e.stopPropagation()
+ this.sculpture.set_depth( this.$depth.unitVal() )
+ this.$depth.unitVal( Number(this.sculpture.naturalDimensions.c * this.sculpture.scale) || "" )
+ this.sculpture.updateOutline()
+ },
+ changeUnits: function(){
+ app.units = this.$units.val()
+ this.$('.units').resetUnitVal()
+ },
+
+ taint: function(e){
+ e.stopPropagation()
+ this.tainted = true
+ },
+
+ bind: function(sculpture){
+ this.sculpture = sculpture
+ this.sculpture.mx.bound = true
+ this.sculpture.mx.el.classList.add("picked")
+ },
+
+ unbind: function(){
+ if (this.sculpture) {
+ this.sculpture.focused = false
+ if (this.tainted && this.sculpture.media) {
+ this.sculpture.media.title = this.$name.val()
+ this.sculpture.media.description = this.$description.val()
+ Minotaur.watch( app.router.editorView.settings )
+ }
+ if (this.sculpture.mx) {
+ this.sculpture.mx.bound = false
+ this.sculpture.mx.el.classList.remove("picked")
+ }
+ }
+ this.tainted = false
+ this.sculpture = null
+ },
+
+ destroy: function(){
+ var sculpture = this.sculpture
+ this.hide()
+
+ sculpture.remove()
+
+ this.tainted = false
+ this.sculpture = null
+ },
+
+})
diff --git a/public/assets/javascripts/ui/editor/TextEditor.js b/public/assets/javascripts/ui/editor/TextEditor.js
new file mode 100644
index 0000000..53d5b9f
--- /dev/null
+++ b/public/assets/javascripts/ui/editor/TextEditor.js
@@ -0,0 +1,238 @@
+
+var TextEditor = FormView.extend({
+ el: "#textEditor",
+ tainted: false,
+ scenery: null,
+
+ events: {
+ "keydown": 'taint',
+ "focus [name]": "clearMinotaur",
+ "mousedown": "stopPropagation",
+ "change [name=font-family]": 'changeFontFamily',
+ "change [name=font-size]": 'changeFontSize',
+ "change [name=text-align]": 'changeTextAlign',
+ "click .swatch": 'showColorPicker',
+ "click [data-role=hide-color-picker]": 'hideColorPicker',
+ "click [data-role=hide-text-editor]": 'hide',
+ "input [name=text-body]": 'changeText',
+ "click [data-role=destroy-text]": "destroy",
+ "click .colors span": "setHue",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ this.$textSettings = this.$(".text-setting")
+ this.$colorSettings = this.$(".color-setting")
+ this.$noTextMessage = this.$(".no-text")
+ this.$fontFamily = this.$("[name=font-family]")
+ this.$fontSize = this.$("[name=font-size]")
+ this.$textBody = this.$("[name=text-body]")
+ this.$textAlign = this.$("[name=text-align]")
+ this.$swatch = this.$(".swatch")
+
+ this.colorPicker = new LabColorPicker(this, 155, 155)
+ this.$(".color-picker").append( this.colorPicker.canvas )
+ this.$(".color-picker").append( this.colorPicker.cursor )
+ this.$(".slider").append( this.colorPicker.brightness )
+
+ this.$colors = this.$(".colors")
+ this.parent.colorControl.colors.forEach(function(color){
+ var $swatch = $("<span>")
+ $swatch.css("background-color","rgb(" + color + ")")
+ $swatch.data('color', color)
+ this.$colors.append($swatch)
+ }.bind(this))
+
+ this.$(".setting").hide()
+
+ app.on("cancel-scenery", function(){
+ this.createMode(true)
+ $("body").toggleClass("addText", false)
+ }.bind(this))
+
+ },
+
+ toggle: function(state){
+ this.$el.toggleClass("active", state)
+ if (state) {
+ $("#keyhint").fadeOut(200)
+ Scenery.nextMedia = {
+ type: 'text',
+ width: 600,
+ height: 450,
+ scale: 0.5,
+ font: { family: 'Lato', size: 24, align: 'left', color: "#000" },
+ }
+ this.createMode(true)
+ }
+ else {
+ $("[data-role='toggle-text-editor']").removeClass("inuse")
+ }
+ },
+
+ hide: function(scenery){
+ Scenery.nextMedia = null
+ if (this.scenery) {
+ this.unbind()
+ }
+ Scenery.resize.hide()
+ this.toggle(false)
+ },
+
+ taint: function(e){
+ e.stopPropagation()
+ this.tainted = true
+ },
+
+ bind: function(scenery){
+ this.tainted = false
+ this.scenery = scenery
+ this.scenery.mx.bound = true
+ this.scenery.mx.el.classList.add("picked")
+ this.scenery.media.font.color = this.scenery.media.font.color || [0,0,0]
+ },
+
+ unbind: function(){
+ if (this.scenery) {
+ this.scenery.focused = false
+ if (this.tainted) {
+ Minotaur.watch( app.router.editorView.settings )
+ }
+ if (this.scenery.mx) {
+ this.scenery.mx.bound = false
+ this.scenery.mx.el.classList.remove("picked")
+ }
+ if (! this.scenery.media || ! this.scenery.media.description || this.scenery.media.description == "") {
+ this.scenery.remove()
+ }
+ }
+ this.tainted = false
+ this.scenery = null
+ },
+
+ createMode: function(state){
+ this.hideColorPicker()
+ this.$textSettings.toggle(! state)
+ this.$noTextMessage.toggle(!! state)
+ $("body").toggleClass("addText", !! state)
+ },
+
+ pick: function(scenery){
+ if (this.scenery && scenery !== this.scenery) {
+ this.unbind()
+ }
+
+ this.parent.settings.hide()
+ Scenery.resize.show(scenery)
+ Scenery.hovering = true
+
+ this.bind(scenery)
+ this.$el.toggleClass("active", true)
+ this.$textBody.val( this.scenery.media.description )
+
+ this.$fontFamily.val( this.scenery.media.font.family )
+ this.$fontSize.val( this.scenery.media.font.size )
+ this.$textAlign.val( this.scenery.media.font.align )
+ this.setSwatchColor( this.scenery.media.font.color )
+
+ this.createMode(false)
+
+ if (! this.scenery.media.description) {
+ setTimeout(function(){
+ this.$textBody.focus()
+ }.bind(this), 100)
+ }
+ },
+
+ taint: function(e){
+ e.stopPropagation()
+ },
+
+ changeFontFamily: function(){
+ this.scenery.setFont({ family: this.$fontFamily.val() })
+ },
+
+ changeTextAlign: function(){
+ this.scenery.setFont({ align: this.$textAlign.val() })
+ },
+
+ changeFontSize: function(){
+ var size = parseInt( this.$fontSize.val() )
+ size && this.scenery.setFont({ size: size })
+ },
+
+ changeText: function(e){
+ e.stopPropagation()
+ var text = this.$textBody.val()
+ this.scenery.setText(text)
+ },
+
+ destroy: function(){
+ this.tainted = false
+ this.scenery.remove()
+ this.hide()
+ },
+
+ setSwatchColor: function(rgb){
+ this.$swatch.css("background-color", rgb_string(rgb))
+ },
+ showColorPicker: function(){
+ this.$textSettings.hide()
+ this.$colorSettings.show()
+
+ var color = this.scenery.media.font.color
+ this.labColor = this.colorPicker.load(color)
+ this.pickColor(color, this.labColor)
+
+ this.$el.addClass("color-mode")
+ },
+
+ hideColorPicker: function(e){
+ e && e.preventDefault()
+ this.$textSettings.show()
+ this.$colorSettings.hide()
+ this.$el.removeClass("color-mode")
+ },
+
+ pickColor: function(rgb, Lab){
+ this.labColor = Lab
+ this.setSwatchColor(rgb)
+ this.scenery.setFont({ color: rgb })
+ this.tainted = true
+ },
+
+ setHue: function(e){
+ var color = $(e.currentTarget).data('color')
+ this.labColor = this.colorPicker.load(color)
+ this.pickColor(color, this.labColor)
+ },
+
+ initialState: null,
+
+ begin: function(){
+ // this.initialState = this.serialize()
+ },
+
+ serialize: function(){
+ return {
+ rgb: Walls.colors[ this.mode ]
+ }
+ },
+
+ finalize: function(){
+ if (! this.initialState) { return }
+ UndoStack.push({
+ type: 'update-colors',
+ undo: this.initialState,
+ redo: this.serialize(),
+ })
+
+ this.initialState = null
+
+ // TODO: watch individual wall object here
+ Minotaur.watch( app.router.editorView.settings )
+ },
+
+})
diff --git a/public/assets/javascripts/ui/editor/WallpaperPicker.js b/public/assets/javascripts/ui/editor/WallpaperPicker.js
index 0dd2921..3640d6d 100644
--- a/public/assets/javascripts/ui/editor/WallpaperPicker.js
+++ b/public/assets/javascripts/ui/editor/WallpaperPicker.js
@@ -3,34 +3,57 @@ var WallpaperPicker = UploadView.extend({
el: ".wallpaper",
mediaTag: "wallpaper",
+ createAction: "/api/media/new",
uploadAction: "/api/media/upload",
+ destroyAction: "/api/media/destroy",
events: {
+ "contextmenu": 'contextmenu',
+ "mousedown": 'stopPropagation',
"click .swatch": 'pick',
"click .wallpaperRemove": 'remove',
+ "input [data-role='wallpaper-scale']": 'updateScale',
+ "change .url": "enterUrl",
+ "keydown .url": "enterSetUrl",
},
- initialize: function(){
+ initialize: function(opt){
+ this.parent = opt.parent
this.__super__.initialize.call(this)
this.$swatches = this.$(".swatches")
this.$remove = this.$(".wallpaperRemove")
- this.$remove.hide()
+
+ this.$url = this.$(".url")
+
+ this.$position = this.$("[data-role='wallpaper-position']")
+ this.$scale = this.$("[data-role='wallpaper-scale']")
+
+ this.$wallpaperResizeControls = this.$(".wallpaperResizeControls")
+ this.$wallpaperResizeControls.addClass('disabled')
+
+ this.initializePositionCursor()
},
loaded: false,
show: function(){
- if (! this.loaded) {
- this.load()
- }
- else {
- this.toggle(true)
- }
+ this.toggle(true)
},
-
hide: function(){
- this.__super__.hide.call(this)
+ this.toggle(false)
},
-
+
+ toggle: function (state) {
+ Scenery.nextWallpaper = null
+ app.tube('cancel-wallpaper')
+ this.$el.toggleClass("active", state)
+ if (state) {
+ this.parent.cursor.message("wallpaper")
+ if (! this.loaded) {
+ this.load()
+ }
+ }
+ },
+
load: function(){
$.get("/api/media/user", { tag: this.mediaTag }, this.populate.bind(this))
},
@@ -39,49 +62,98 @@ var WallpaperPicker = UploadView.extend({
this.loaded = true
if (data && data.length) {
data.forEach(this.add.bind(this))
+ this.$(".txt").hide()
+ }
+ else {
+ this.$(".txt").show()
}
this.toggle(true)
},
+ seenWallpapers: {},
add: function (media) {
if (media.type !== "image") { return }
+ if (this.seenWallpapers[ media.url ]) { return }
var swatch = document.createElement("div")
swatch.className = "swatch"
swatch.style.backgroundImage = "url(" + media.url + ")"
+ swatch.setAttribute("data-id", media._id)
this.$swatches.append(swatch)
this.$swatches.show()
- },
-
- toggle: function (state) {
- if (state && ! this.loaded) {
- this.show()
- }
- else {
- this.$el.toggleClass("active", state)
- }
- // toggle the class that makes the cursor a paintbucket
- // $("body").removeClass("pastePaper")
+ this.$(".txt").hide()
+ this.seenWallpapers[ media.url ] = true
},
- hide: function(){
- this.toggle(false)
+ addUrl: function (url){
+ Parser.loadImage(url, function(media){
+ if (! media) return
+ media._csrf = $("[name=_csrf]").val()
+ media.tag = this.mediaTag
+
+ var request = $.ajax({
+ type: "post",
+ url: this.createAction,
+ data: media,
+ })
+ request.done(this.add.bind(this))
+
+ }.bind(this))
},
-
+
beforeUpload: function(){
},
pick: function(e){
var $swatch = $(e.currentTarget)
- this.follow( e, $swatch.css('background-image') )
- this.$remove.show()
+ if (Scenery.nextWallpaper == "none") {
+ var _id = $swatch[0].getAttribute("data-id")
+ $swatch.remove()
+ this.destroy(_id, function(){})
+ }
+ else {
+ app.tube('cancel-wallpaper')
+ this.follow( e, $swatch.css('background-image') )
+ this.parent.presets.modified = true
+ }
},
remove: function(e){
- this.follow( e, "none" )
- $(".floatingSwatch").addClass("scissors")
+ if (Scenery.nextWallpaper) {
+ // remove red class to the wallpaper
+ Scenery.nextWallpaper = null
+ app.tube('cancel-wallpaper')
+ }
+ else {
+ // add red class to the wallpaper
+ this.follow( e, "none" )
+ $(".floatingSwatch").addClass("scissors")
+ this.$el.addClass("deleteArmed")
+ }
+ },
+
+ destroy: function(_id, cb){
+ $.ajax({
+ type: "delete",
+ url: this.destroyAction,
+ data: { _id: _id, _csrf: $("[name=_csrf]").val() }
+ }).complete(cb || function(){})
+ },
+
+ contextmenu: function(e){
+ if (Scenery.nextWallpaper) {
+ e.preventDefault()
+ this.cancel()
+ }
+ },
+ cancel: function(){
+ if (Scenery.nextWallpaper) {
+ Scenery.nextWallpaper = null
+ app.tube('cancel-wallpaper')
+ }
},
follow: function(e, wallpaper, icon){
+ var base = this
icon = icon || wallpaper
var $floatingSwatch = $(".floatingSwatch")
@@ -90,6 +162,8 @@ var WallpaperPicker = UploadView.extend({
Scenery.nextWallpaper = wallpaper
+ $(".floodMessage").show()
+
setTimeout(function(){
function _followCursor(e) {
$floatingSwatch.css({
@@ -97,14 +171,105 @@ var WallpaperPicker = UploadView.extend({
left: (e.pageX + 10) + 'px',
});
}
- $(window).on('mousemove', _followCursor)
- $(window).one('click', function () {
+ function _hideCursor (e) {
+ $(window).off('keydown', _floodRoom)
$(window).off('mousemove', _followCursor)
+ app.off('cancel-wallpaper', _hideCursor)
$floatingSwatch.removeClass("scissors").hide()
- });
+ $(".floodMessage").hide()
+ base.$el.removeClass("deleteArmed")
+ }
+ function _floodRoom (e) {
+ if (e.keyCode == 13) {
+ base.flood()
+ }
+ }
+ $(window).on('keydown', _floodRoom)
+ $(window).on('mousemove', _followCursor)
+ // $(window).one('click', _hideCursor);
+ app.on('cancel-wallpaper', _hideCursor)
$floatingSwatch.show()
_followCursor(e);
})
},
+ wall: null,
+ pickWall: function(wall){
+ if (! wall.background || wall.background.src == "none") {
+ this.$wallpaperResizeControls.addClass('disabled')
+ this.$scale.val( 0.0 )
+ return;
+ }
+ this.$wallpaperResizeControls.removeClass('disabled')
+ this.wall = wall
+ this.$scale.val( Math.log( this.wall.background.scale ) )
+ },
+
+ scaleTimeout: null,
+ updateScale: function(){
+ if (! this.wall) return;
+ var scale = Math.exp( parseFloat(this.$scale.val()) )
+ this.wall.wallpaperPosition({ scale: scale })
+
+ clearTimeout(this.scaleTimeout)
+ this.scaleTimeout = setTimeout(function(){
+
+ // TODO: watch individual scenery object here
+ Minotaur.watch( app.router.editorView.settings )
+
+ }.bind(this), 500)
+ },
+
+ enterUrl: function(){
+ var url = this.$url.sanitize()
+ this.addUrl(url)
+ this.$url.val("")
+ },
+ enterSetUrl: function (e) {
+ e.stopPropagation()
+ if (e.keyCode == 13) {
+ setTimeout(this.enterUrl.bind(this), 100)
+ }
+ },
+
+ flood: function(url){
+ url = url || Scenery.nextWallpaper
+ if (! url) return
+ Walls.setWallpaper.wall({ src: url })
+ Walls.setWallpaper.floor({ src: url })
+ Walls.setWallpaper.ceiling({ src: url })
+ this.cancel()
+ },
+
+ initializePositionCursor: function(){
+ var base = this
+ var dx = 0, dy = 0, dragging = false, delta
+ var x = 0, y = 0, s = 1
+ var mymouse = new mouse({
+ el: this.$position[0],
+ down: function(e, cursor){
+ if (! base.wall) return
+ dragging = true
+ // s = parseFloat( base.$scale.val() )
+ x = base.wall.background.x
+ y = base.wall.background.y
+ },
+ drag: function(e, cursor){
+ if (! dragging) return
+ delta = cursor.delta()
+ delta.a = - delta.a
+ dx = delta.a*s
+ dy = delta.b*s
+ base.wall.wallpaperPosition({
+ // scale: s,
+ x: x+dx,
+ y: y+dy,
+ })
+ },
+ up: function(e, cursor, new_cursor){
+ dragging = false
+ },
+ })
+ },
+
})
diff --git a/public/assets/javascripts/ui/lib/AlertModal.js b/public/assets/javascripts/ui/lib/AlertModal.js
index 1b0f40f..a4bf241 100644
--- a/public/assets/javascripts/ui/lib/AlertModal.js
+++ b/public/assets/javascripts/ui/lib/AlertModal.js
@@ -1,25 +1,25 @@
var AlertModal = new( ModalFormView.extend({
- el: ".mediaDrawer.alert",
+ el: ".mediaDrawer.alert",
- events: {
- "click .ok": "advance",
- "click .close": "advance",
- },
-
- alert: function(message, callback){
- this.$(".message").empty().append(message)
- this.callback = callback
- this.show()
- this.$(".ok").focus()
- },
-
- advance: function(e){
- e && e.preventDefault()
- this.hide()
- this.callback && this.callback()
- this.callback = null
- }
+ events: {
+ "click .ok": "advance",
+ "click .close": "advance",
+ },
+
+ alert: function(message, callback){
+ this.$(".message").empty().append(message)
+ this.callback = callback
+ this.show()
+ this.$(".ok").focus()
+ },
+
+ advance: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.callback && this.callback()
+ this.callback = null
+ }
}))
diff --git a/public/assets/javascripts/ui/lib/AnimatedView.js b/public/assets/javascripts/ui/lib/AnimatedView.js
new file mode 100644
index 0000000..3c50b0a
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/AnimatedView.js
@@ -0,0 +1,31 @@
+var AnimatedView = View.extend({
+
+ _animating: false,
+ last_t: 0,
+
+ startAnimating: function(){
+ if (this._animating) return
+ this._animating = true
+ this._animate()
+ },
+
+ stopAnimating: function(){
+ this._animating = false
+ },
+
+ _animate: function(t){
+ if (! this._animating) return
+
+ requestAnimationFrame(this._animate.bind(this))
+
+ var dt = t - this.last_t
+ this.last_t = t
+
+ if (! t) return
+
+ this.animate(t, dt)
+ },
+
+ animate: function(t, dt){},
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/ConfirmModal.js b/public/assets/javascripts/ui/lib/ConfirmModal.js
index 01720bb..7d9da67 100644
--- a/public/assets/javascripts/ui/lib/ConfirmModal.js
+++ b/public/assets/javascripts/ui/lib/ConfirmModal.js
@@ -1,24 +1,34 @@
var ConfirmModal = new( ModalFormView.extend({
- el: ".mediaDrawer.confirm",
+ el: ".mediaDrawer.confirm",
- events: {
- "click .yes": "advance",
- "click .no": "hide",
- },
-
- confirm: function(question, callback){
- this.$(".question").empty().append(question)
- this.callback = callback
- this.show()
- },
-
- advance: function(e){
- e && e.preventDefault()
- this.hide()
- this.callback && this.callback()
- this.callback = null
- }
+ events: {
+ "click .yes": "agree",
+ "click .no": "cancel",
+ },
+
+ confirm: function(question, agreeCallback, cancelCallback){
+ this.$(".question").empty().append(question)
+ this.agreeCallback = agreeCallback
+ this.cancelCallback = cancelCallback
+ this.show()
+ },
+
+ agree: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.agreeCallback && this.agreeCallback()
+ this.agreeCallback = null
+ this.cancelCallback = null
+ },
+
+ cancel: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.cancelCallback && this.cancelCallback()
+ this.agreeCallback = null
+ this.cancelCallback = null
+ }
}) ) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/ErrorModal.js b/public/assets/javascripts/ui/lib/ErrorModal.js
index 8b01077..cfc2e6d 100644
--- a/public/assets/javascripts/ui/lib/ErrorModal.js
+++ b/public/assets/javascripts/ui/lib/ErrorModal.js
@@ -1,26 +1,26 @@
var ErrorModal = new( ModalFormView.extend({
- el: ".mediaDrawer.error",
+ el: ".mediaDrawer.error",
- events: {
- "click .ok": "advance",
- "click .close": "advance",
- },
-
- alert: function(message, callback){
- this.$(".errorList").empty().append(message)
- this.callback = callback
- this.show()
- this.$(".ok").focus()
- },
-
- advance: function(e){
- e && e.preventDefault()
- this.hide()
- this.callback && this.callback()
- this.callback = null
- }
+ events: {
+ "click .ok": "advance",
+ "click .close": "advance",
+ },
+
+ alert: function(message, callback){
+ this.$(".errorList").empty().append(message)
+ this.callback = callback
+ this.show()
+ this.$(".ok").focus()
+ },
+
+ advance: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.callback && this.callback()
+ this.callback = null
+ }
}))
diff --git a/public/assets/javascripts/ui/lib/FormView.js b/public/assets/javascripts/ui/lib/FormView.js
index 17b748a..a952ecb 100644
--- a/public/assets/javascripts/ui/lib/FormView.js
+++ b/public/assets/javascripts/ui/lib/FormView.js
@@ -1,127 +1,138 @@
var FormView = View.extend({
- method: "post",
+ method: "post",
+ useMinotaur: false,
- events: {
- "submit form": "save"
- },
+ events: {
+ "submit form": "save"
+ },
- initialize: function(opt){
- if (opt && opt.parent) {
- this.parent = opt.parent
- }
- this.$form = this.$("form")
- this.$errors = this.$(".errors")
- this.$errorList = this.$(".errorList")
- },
+ initialize: function(opt){
+ if (opt && opt.parent) {
+ this.parent = opt.parent
+ }
+ this.$form = this.$("form")
+ this.$errors = this.$(".errors")
+ this.$errorList = this.$(".errorList")
+ },
- reset: function(){
- this.$("input,textarea").not("[type='submit']").not("[type='hidden']").val("")
- },
-
- showErrors: function(errors){
- if (errors && errors.length) {
- this.$errorList.empty();
- for (var i in errors) {
- this.$errorList.append('<div>' + errors[i] + '</div>');
- }
- this.$errors.css("opacity", 1.0);
- setTimeout(function(){
- this.$errors.show().css("opacity", 1.0);
- }.bind(this), 200)
- }
- },
-
- serialize: function(){
- var fd = new FormData(), hasCSRF = false
-
- this.$("input[name], select[name], textarea[name]").each( function(){
- if (this.type == "file") {
- if (this.files.length > 0) {
- fd.append(this.name, this.files[0]);
- }
- }
- else if (this.type == "password") {
- if (this.value.length > 0) {
- fd.append(this.name, SHA1.hex('lol$' + this.value + '$vvalls'))
- }
- }
- else {
- fd.append(this.name, this.value);
- hasCSRF = hasCSRF || this.name == "_csrf"
- }
- });
-
- if (! hasCSRF) {
+ reset: function(){
+ this.$("input,textarea").not("[type='submit']").not("[type='hidden']").val("")
+ },
+
+ showErrors: function(errors){
+ if (errors && errors.length) {
+ this.$errorList.empty();
+ for (var i in errors) {
+ this.$errorList.append('<div>' + errors[i] + '</div>');
+ }
+ this.$errors.css("opacity", 1.0);
+ setTimeout(function(){
+ this.$errors.show().css("opacity", 1.0);
+ }.bind(this), 200)
+ }
+ },
+
+ serialize: function(){
+ var fd = new FormData(), hasCSRF = false
+
+ this.$("input[name], select[name], textarea[name]").each( function(){
+ if (this.type == "file") {
+ if (this.files.length > 0) {
+ fd.append(this.name, this.files[0]);
+ }
+ }
+ else if (this.type == "password") {
+ if (this.value.length > 0) {
+ fd.append(this.name, SHA1.hex('lol$' + this.value + '$vvalls'))
+ }
+ }
+ else {
+ fd.append(this.name, this.value);
+ hasCSRF = hasCSRF || this.name == "_csrf"
+ }
+ });
+
+ if (! hasCSRF) {
fd.append("_csrf", $("[name=_csrf]").val())
}
-
- return fd
- },
-
- save: function(e, successCallback, errorCallback){
- e && e.preventDefault()
+
+ return fd
+ },
+
+ save: function(e, successCallback, errorCallback){
+ e && e.preventDefault()
- this.$errors.hide().css("opacity", 0.0);
-
- if (this.validate) {
- var errors = this.validate()
- if (errors && errors.length) {
- if (errorCallback) {
- errorCallback(errors)
- }
- else {
+ this.$errors && this.$errors.hide().css("opacity", 0.0);
+
+ if (this.validate) {
+ var errors = this.validate()
+ if (errors && errors.length) {
+ if (errorCallback) {
+ setTimeout(function(){
+ errorCallback(errors)
+ })
+ }
+ else {
this.showErrors(errors)
- }
- return
- }
- }
-
- var action = typeof this.action == "function" ? this.action() : this.action
- if (! action) return
+ }
+ return
+ }
+ }
+ var action = typeof this.action == "function" ? this.action() : this.action
+ if (! action) return
- var request = $.ajax({
- url: action,
- type: this.method,
- data: this.serialize(),
- dataType: "json",
- processData: false,
- contentType: false,
- })
-
- request.done($.proxy(function (response) {
- if (response.error) {
- var errors = []
- for (var key in response.error.errors) {
- errors.push(response.error.errors[key].message);
- }
- if (errorCallback) {
- errorCallback(errors)
- }
- else {
+ var request = $.ajax({
+ url: action,
+ type: this.method,
+ data: this.serialize(),
+ dataType: "json",
+ processData: false,
+ contentType: false,
+ })
+
+ if (this.useMinotaur) {
+ Minotaur.show()
+ }
+
+ request.done($.proxy(function (response) {
+ if (this.useMinotaur) {
+ Minotaur.hide()
+ }
+ if (response.error) {
+ var errors = []
+ for (var key in response.error.errors) {
+ errors.push(response.error.errors[key].message);
+ }
+ if (errorCallback) {
+ errorCallback(errors)
+ }
+ else {
this.showErrors(errors)
- }
- return
- }
- else {
- if (successCallback) {
- successCallback(response)
- }
- if (this.success) {
- this.success(response)
- }
- }
- }, this));
- }
+ }
+ return
+ }
+ else {
+ console.log("ok")
+ if (successCallback) {
+ console.log("use cb")
+ successCallback(response)
+ }
+ if (this.success) {
+ this.success(response)
+ }
+ }
+ }, this));
+ }
})
var ModalFormView = ModalView.extend(FormView.prototype).extend({
- load: function(){
- this.reset()
- this.show()
- }
+ load: function(){
+ this.reset()
+ this.show()
+ }
})
diff --git a/public/assets/javascripts/ui/editor/LightControl.js b/public/assets/javascripts/ui/lib/LabColorPicker.js
index 3eb2861..2c8fb90 100644
--- a/public/assets/javascripts/ui/editor/LightControl.js
+++ b/public/assets/javascripts/ui/lib/LabColorPicker.js
@@ -1,145 +1,22 @@
-
-var LightControl = View.extend({
- el: ".lightcontrol",
-
- events: {
- "mousedown": "stopPropagation",
- "click .color-swatches span": "select",
- "input #shadow-control": "updateShadow",
- "mousedown #brightness-control": "beginBrightness",
- "input #brightness-control": "updateBrightness",
- "input #outline-hue": "updateShadow",
- "input #wall-hue": "updateShadow",
- },
-
- initialize: function(){
-
- this.colorPicker = new LabColorPicker(this, 180, 180)
- this.$("#color-picker").append( this.colorPicker.canvas )
- this.$("#color-picker").append( this.colorPicker.cursor )
-
- this.$swatches = this.$(".swatch")
- this.$labels = this.$(".swatch + label")
- this.$swatch = {
- wall: this.$("#wall-color"),
- outline: this.$("#outline-color"),
- floor: this.$("#floor-color"),
- ceiling: this.$("#ceiling-color"),
- }
- this.$brightnessControl = this.$("#brightness-control")
- },
-
- modes: [ "wall", "outline", "floor", "ceiling" ],
-
- load: function(data){
- this.modes.forEach(function(mode){
- Walls.setColor[mode](data[mode])
- this.$swatch[ mode ].css("background-color", rgb_string(data[mode]))
- }.bind(this))
- this.setMode("wall")
- },
-
- loadDefaults: function(){
- var colors = {
- wall: app.defaults.colors.wall.slice(),
- outline: app.defaults.colors.outline.slice(),
- floor: app.defaults.colors.floor.slice(),
- ceiling: app.defaults.colors.ceiling.slice(),
- }
- this.load(colors)
- },
-
- toggle: function(state){
- this.$el.toggleClass("active", state);
- },
-
- show: function(){
- this.toggle(true)
- },
-
- hide: function(){
- this.toggle(false)
- },
-
- pick: function(rgb, Lab){
- this.labColor = Lab
- this.setSwatchColor(this.mode, rgb)
- Walls.setColor[ this.mode ](rgb)
- },
-
- setSwatchColor: function(mode, rgb) {
- this.$swatch[ mode ].css("background-color", rgb_string(rgb))
- },
-
- initialState: null,
-
- begin: function(){
- this.initialState = this.serialize()
- },
-
- serialize: function(){
- return {
- mode: this.mode,
- rgb: Walls.colors[ this.mode ]
- }
- },
-
- finalize: function(){
- if (! this.initialState) { return }
- UndoStack.push({
- type: 'update-colors',
- undo: this.initialState,
- redo: this.serialize(),
- })
-
- this.initialState = null
-
- // TODO: watch individual wall object here
- Minotaur.watch( app.router.editorView.settings )
- },
-
- setMode: function (mode) {
- var color, brightness
- this.mode = mode
- this.$(".active").removeClass("active")
- this.$swatch[ mode ].parent().addClass("active")
- color = Walls.colors[ mode ]
-
- this.labColor = this.colorPicker.load(color)
- this.$brightnessControl.val( this.labColor[0] )
- },
-
- select: function(e){
- var mode = $('.swatch', e.currentTarget).data('mode')
- this.setMode(mode)
- },
-
- beginBrightness: function(){
- this.begin()
- $(window).one("mouseup", this.finalize.bind(this))
- },
-
- updateBrightness: function(){
- this.labColor[0] = parseFloat( this.$brightnessControl.val() )
- var rgb = this.colorPicker.setLab( this.labColor )
- this.pick(rgb, this.labColor)
- },
-
-})
-
var LabColorPicker = function (parent, w, h) {
var base = this
var canvas = this.canvas = document.createElement('canvas')
- var ctx = this.ctx = canvas.getContext('2d')
- var imageData = ctx.createImageData(w,h)
- var data = imageData.data
+ canvas.width = w
+ canvas.height = h
+ var ctx = this.ctx = canvas.getContext('2d-lodpi')
+// canvas.className = "colorPicker"
+// var imageData = ctx.createImageData(w, h)
+// var data = imageData.data
var cursor = this.cursor = document.createElement("div")
cursor.className = "colorPickerCursor"
-
- canvas.width = w
- canvas.height = h
- canvas.className = "colorPicker"
+
+ var brightnessControl = this.brightness = document.createElement("input")
+ var $brightnessControl = $(brightnessControl)
+ brightnessControl.setAttribute("type", "range")
+ brightnessControl.setAttribute("min", "0")
+ brightnessControl.setAttribute("max", "110")
+ brightnessControl.setAttribute("value", "0")
var ww = w-1
var hh = h-1
@@ -168,6 +45,11 @@ var LabColorPicker = function (parent, w, h) {
}
})
+ $brightnessControl.on({
+ "mousedown": function(){ base.beginBrightness() },
+ "input": function(){ base.updateBrightness() },
+ })
+
this.setLab = function(Lab) {
val = Lab[0]
this.paint()
@@ -181,7 +63,7 @@ var LabColorPicker = function (parent, w, h) {
var y = mix( j/hh, b_range[0], b_range[1] )
var rgb = xyz2rgb(hunterlab2xyz(val, x, y)).map(Math.round)
this.moveCursor(i, j)
- parent.pick( rgb, [val,x,y] )
+ parent.pickColor( rgb, [val,x,y] )
}
this.load = function(rgba){
var Lab = xyz2hunterlab(rgb2xyz(rgba))
@@ -191,6 +73,8 @@ var LabColorPicker = function (parent, w, h) {
this.moveCursor(x,y)
this.setLab(Lab)
+ this.setBrightness(Lab)
+
return Lab
}
this.moveCursor = function(x,y){
@@ -199,11 +83,14 @@ var LabColorPicker = function (parent, w, h) {
}
this.paint = function() {
val = clamp(val, L_range[0], L_range[1])
- var x, y, t
- for (var i = 0; i < w; i++) {
- for (var j = 0; j < h; j++) {
- x = mix( i/ww, a_range[0], a_range[1] )
- y = mix( j/hh, b_range[0], b_range[1] )
+ var imageData = ctx.createImageData(canvas.width, canvas.height)
+ var data = imageData.data
+ var x, y, t, cw = imageData.width, ch = imageData.height
+ var cww = cw-1, chh = ch-1
+ for (var i = 0; i < cw; i++) {
+ for (var j = 0; j < ch; j++) {
+ x = mix( i/cww, a_range[0], a_range[1] )
+ y = mix( j/chh, b_range[0], b_range[1] )
t = (j*w + i) * 4
rgb = xyz2rgb(hunterlab2xyz(val, x, y))
data[t] = Math.round( rgb[0] )
@@ -214,6 +101,19 @@ var LabColorPicker = function (parent, w, h) {
}
ctx.putImageData(imageData,0,0)
}
+
+ this.beginBrightness = function(){
+ parent.begin()
+ $(window).one("mouseup", parent.finalize.bind(parent))
+ }
+ this.updateBrightness = function(){
+ parent.labColor[0] = parseFloat( $brightnessControl.val() )
+ var rgb = base.setLab( parent.labColor )
+ parent.pickColor(rgb, parent.labColor)
+ }
+ this.setBrightness = function(Lab){
+ $brightnessControl.val(Lab[0])
+ }
function hunterlab2xyz (L,a,b) {
var_Y = L / 10
diff --git a/public/assets/javascripts/ui/lib/ModalView.js b/public/assets/javascripts/ui/lib/ModalView.js
index d9b518a..e0070ce 100644
--- a/public/assets/javascripts/ui/lib/ModalView.js
+++ b/public/assets/javascripts/ui/lib/ModalView.js
@@ -1,42 +1,53 @@
var ModalView = View.extend({
- events: {
- "click .close": 'close',
- },
-
- initialize: function(opt){
- if (opt && opt.parent) {
- this.parent = opt.parent
- }
- },
-
- usesFileUpload: false,
-
- show: function(){
- $(".mediaDrawer").removeClass("active")
-
- if (! this.usesFileUpload) {
- $(".fileUpload").removeClass("active")
- }
-
- this.$el.addClass("active")
+ events: {
+ "click .close": 'close',
+ },
+
+ initialize: function(opt){
+ if (opt && opt.parent) {
+ this.parent = opt.parent
+ }
+ },
+
+ usesFileUpload: false,
+
+ show: function(){
+ $(".mediaDrawer").removeClass("active")
+ $(".fileUpload").removeClass("active")
+
+ if (this.fixedClose) {
+ $("#fixed_close").addClass("active")
+ $("#fixed_close").bind("click", this.hide.bind(this))
+ }
+
+ this.$el.addClass("active")
$("body").addClass("noOverflow")
- },
+ },
- hide: function(){
+ hide: function(){
// $(".mediaDrawer, .room1").removeClass("active editing");
- this.$el.removeClass("active");
+ if (this.fixedClose) {
+ $("#fixed_close").removeClass("active")
+ $("#fixed_close").unbind("click", this.hide.bind(this))
+ }
+ this.$el.removeClass("active");
$("body").removeClass("noOverflow");
- },
-
- close: function(){
- if (window.isModalView) {
- window.location.pathname = "/"
- }
- else {
- history.pushState(null, document.title, app.router.originalPath)
- this.hide()
- }
- }
+ },
+
+ hideClose: function(){
+ $("#fixed_close").removeClass("active")
+ $("#fixed_close").unbind("click", this.hide.bind(this))
+ },
+
+ close: function(){
+ if (window.isModalView) {
+ window.location.pathname = "/"
+ }
+ else {
+ history.pushState(null, document.title, app.router.originalPath)
+ this.hide()
+ }
+ }
})
diff --git a/public/assets/javascripts/ui/lib/Parser.js b/public/assets/javascripts/ui/lib/Parser.js
index 52c96e6..411f425 100644
--- a/public/assets/javascripts/ui/lib/Parser.js
+++ b/public/assets/javascripts/ui/lib/Parser.js
@@ -5,9 +5,12 @@ var Parser = {
fetch: function(url, done) {
var img = new Image ()
img.onload = function(){
+ if (!img) return
var width = img.naturalWidth, height = img.naturalHeight
img = null
done({
+ url: url,
+ type: "image",
token: "",
thumbnail: "",
title: "",
@@ -32,6 +35,8 @@ var Parser = {
var width = video.videoWidth, height = video.videoHeight
video = null
done({
+ url: url,
+ type: "video",
token: "",
thumbnail: "",
title: "",
@@ -63,6 +68,8 @@ var Parser = {
success: function(result){
var res = result.items[0]
done({
+ url: url,
+ type: "youtube",
token: id,
thumbnail: thumb,
title: res.snippet.title,
@@ -92,6 +99,8 @@ var Parser = {
return
}
done({
+ url: url,
+ type: "vimeo",
token: id,
thumbnail: res.thumbnail_large,
title: res.title,
@@ -103,10 +112,9 @@ var Parser = {
},
tag: function (media) {
// return '<img class="video" type="vimeo" vid="'+media.token+'" src="'+media.thumbnail+'"><span class="playvid">&#9654;</span>';
- return '<div class="video" style="width: ' + media.width + 'px; height: ' + media.height + 'px; overflow: hidden; position: relative;"><iframe frameborder="0" scrolling="no" seamless="seamless" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen" id="okplayer" src="http://player.vimeo.com/video/' + media.token + '?api=1&js_api=1&title=0&byline=0&portrait=0&playbar=0&player_id=okplayer&loop=0&autoplay=0" width="' + media.width + '" height="' + media.height + '" style="position: absolute; top: 0px; left: 0px; width: ' + media.width + 'px; height: ' + media.height + 'px;"></iframe></div>'
+ return '<div class="video" style="width: ' + media.width + 'px; height: ' + media.height + 'px; overflow: hidden; position: relative;"><iframe frameborder="0" scrolling="no" seamless="seamless" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen" id="okplayer" src="http://player.vimeo.com/video/' + media.token + '?api=1&title=0&byline=0&portrait=0&playbar=0&player_id=okplayer&loop=0&autoplay=0" width="' + media.width + '" height="' + media.height + '" style="position: absolute; top: 0px; left: 0px; width: ' + media.width + 'px; height: ' + media.height + 'px;"></iframe></div>'
}
},
- /*
{
type: 'soundcloud',
regex: /soundcloud.com\/[-a-zA-Z0-9]+\/[-a-zA-Z0-9]+\/?$/i,
@@ -118,26 +126,33 @@ var Parser = {
+ '&client_id='
+ '0673fbe6fc794a7750f680747e863b10',
success: function(result) {
+ // console.log(result)
done({
+ url: url,
+ type: "soundcloud",
token: result.id,
- thumbnail: "",
- title: "",
- width: 100,
- height: 100,
+ thumbnail: result.artwork_url || result.user.avatar_url,
+ title: result.user.username + " - " + result.title,
+ width: 166,
+ height: 166,
})
}
});
},
tag: function (media) {
- return '<iframe width="400" height="166" scrolling="no" frameborder="no"' +
+ return '<iframe width="166" height="166" scrolling="no" frameborder="no"' +
'src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/' + media.token +
'&amp;color=ff6600&amp;auto_play=false&amp;show_artwork=true"></iframe>'
}
- }, {
+ },
+ /*
+ {
type: 'link',
regex: /^http.+/i,
fetch: function(url, done) {
done({
+ url: url,
+ type: "link",
token: "",
thumbnail: "",
title: "",
@@ -152,12 +167,86 @@ var Parser = {
*/
],
+ tumblr: function(url, cb){
+ var domain = url.replace(/^https?:\/\//,"").split("/")[0]
+ if (domain.indexOf(".") == -1) {
+ domain += ".tumblr.com"
+ }
+ $.ajax({
+ type: 'GET',
+ url: "http://" + domain + "/api/read",
+ dataType: "jsonp",
+ data: {
+ format: "json",
+ },
+ success: function(data){
+ var media_list = []
+ var blog = data.tumblelog
+
+ data.posts.forEach(parse)
+ cb(media_list)
+
+ function parse(post){
+ var media, caption, url
+ switch (post.type) {
+ case 'photo':
+ caption = stripHTML(post['photo-caption'])
+ if (post.photos.length) {
+ post.photos.forEach(function(photo){
+ var media = {
+ url: photo['photo-url-1280'],
+ type: "image",
+ token: "",
+ thumbnail: photo['photo-url-500'],
+ description: caption,
+ width: parseInt(photo.width),
+ height: parseInt(photo.height),
+ }
+ media_list.push(media)
+ })
+ }
+ else {
+ media = {
+ url: post['photo-url-1280'],
+ type: "image",
+ token: "",
+ thumbnail: post['photo-url-500'],
+ description: caption,
+ width: parseInt(post.width),
+ height: parseInt(post.height),
+ }
+ media_list.push(media)
+ }
+ break
+ case 'video':
+ url = post['video-source']
+ if (url.indexOf("http") !== 0) { break }
+ if (Parser.lookup.youtube.regex.test(url)) {
+ var id = (url.match(/v=([-_a-zA-Z0-9]{11})/i) || url.match(/youtu.be\/([-_a-zA-Z0-9]{11})/i) || url.match(/embed\/([-_a-zA-Z0-9]{11})/i))[1].split('&')[0];
+ var thumb = "http://i.ytimg.com/vi/" + id + "/hqdefault.jpg"
+ media = {
+ url: post['video-source'],
+ type: "youtube",
+ token: id,
+ thumbnail: thumb,
+ title: stripHTML(post['video-caption']),
+ width: 640,
+ height: 360,
+ }
+ media_list.push(media)
+ }
+ break
+ }
+ }
+// console.log(post)
+ }
+ })
+ },
+
parse: function (url, cb) {
var matched = Parser.integrations.some(function(integration){
if (integration.regex.test(url)) {
integration.fetch(url, function(res){
- res.url = url
- res.type = integration.type
cb(res)
})
return true
@@ -176,6 +265,15 @@ var Parser = {
return ""
},
+ loadImage: function(url, cb, error){
+ if (Parser.lookup.image.regex.test(url)) {
+ Parser.lookup.image.fetch(url, function(media){
+ cb(media)
+ })
+ }
+ else error && error()
+ },
+
thumbnail: function (media) {
return '<img src="' + (media.thumbnail || media.url) + '" class="thumb">';
},
diff --git a/public/assets/javascripts/ui/lib/Router.js b/public/assets/javascripts/ui/lib/Router.js
index 0b6385c..28905b2 100644
--- a/public/assets/javascripts/ui/lib/Router.js
+++ b/public/assets/javascripts/ui/lib/Router.js
@@ -16,6 +16,7 @@ var Router = View.extend({
if (pathname in routes) {
this[this.routes[pathname]](null)
+ return
}
if (path[path.length-1] == null) {
diff --git a/public/assets/javascripts/ui/lib/ToggleableView.js b/public/assets/javascripts/ui/lib/ToggleableView.js
new file mode 100644
index 0000000..371629f
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/ToggleableView.js
@@ -0,0 +1,19 @@
+var ToggleableView = View.extend({
+
+ toggle: function(state){
+ this.$el.toggleClass("active", state)
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+
+ hide: function(){
+ this.toggle(false)
+ },
+
+ visible: function(){
+ return this.$el.hasClass("active")
+ }
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/Toolbar.js b/public/assets/javascripts/ui/lib/Toolbar.js
new file mode 100644
index 0000000..a9ce51c
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/Toolbar.js
@@ -0,0 +1,22 @@
+var Toolbar = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(rapper){
+ this.rapper = (typeof rapper == "string") ? $(rapper)[0] : rapper
+ this.tools = {}
+ this.els = {}
+ }
+ exports.add = function(role, fn){
+ var self = this
+ this.tools[role] = fn
+ this.els[role] = $("[data-role=" + role + "]", self.rapper)
+ this.els[role].click(function(){
+ $(".active", self.rapper).removeClass('active')
+ $(this).addClass('active')
+ fn()
+ })
+ }
+ exports.pick = function(role){
+ this.els[role].trigger("click")
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/UploadView.js b/public/assets/javascripts/ui/lib/UploadView.js
index efaa8c9..d1e2b73 100644
--- a/public/assets/javascripts/ui/lib/UploadView.js
+++ b/public/assets/javascripts/ui/lib/UploadView.js
@@ -3,88 +3,94 @@ var UploadView = View.extend({
// define uploadAction
- events: {
- "change .file": "handleFileSelect",
- "submit form": "preventDefault",
- },
-
- initialize: function(){
- this.$file = this.$(".file")
- this.$upload = this.$(".upload-icon")
+ events: {
+ "change [type=file]": "handleFileSelect",
+ "submit form": "preventDefault",
+ },
+
+ initialize: function(){
+ this.$file = this.$("[type=file]")
+ this.$upload = this.$(".upload-icon")
},
beforeUpload: function(){
},
-
+
handleFileSelect: function(e) {
- e.stopPropagation();
- e.preventDefault();
-
- this.beforeUpload()
+ e.stopPropagation();
+ e.preventDefault();
+
+ this.beforeUpload()
- var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
+ var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
- for (var i = 0, f; f = files[i]; i++) {
- if ( ! f.type.match('image.*')) {
- continue;
- }
-
- this.getImageDimensions(f)
- }
- },
-
- getImageDimensions: function(f){
- var base = this
-
- this.$upload.addClass('uploading')
+ for (var i = 0, f; f = files[i]; i++) {
+ if ( ! f.type.match('image.*')) {
+ continue;
+ }
+
+ this.getImageDimensions(f)
+ }
+ },
+
+ getImageDimensions: function(f){
+ var base = this
+
+ this.$upload.addClass('uploading')
- var reader = new FileReader();
+ var reader = new FileReader();
- reader.onload = function(e) {
- var image = new Image()
- image.onload = function(){
- var width = image.naturalWidth,
- height = image.naturalHeight
- base.upload(f, width, height)
- }
- image.src = e.target.result
- }
-
- reader.readAsDataURL(f);
- },
-
- upload: function(f, width, height){
- var fd = new FormData()
- fd.append('image', f)
- fd.append('width', width)
- fd.append('height', height)
- fd.append('_csrf', $("[name=_csrf]").val())
-
- if (this.mediaTag) {
- fd.append('tag', this.mediaTag)
- }
+ reader.onload = function(e) {
+ var image = new Image()
+ image.onload = function(){
+ var width = image.naturalWidth,
+ height = image.naturalHeight
+ base.upload(f, width, height)
+ }
+ image.src = e.target.result
+ }
+
+ reader.readAsDataURL(f);
+ },
+
+ upload: function(f, width, height){
+ var fd = new FormData()
+ fd.append('image', f)
+ fd.append('width', width)
+ fd.append('height', height)
+ fd.append('_csrf', $("[name=_csrf]").val())
+
+ if (this.mediaTag) {
+ fd.append('tag', this.mediaTag)
+ }
- var request = $.ajax({
- url: this.uploadAction,
- type: "post",
- data: fd,
- dataType: "json",
- processData: false,
- contentType: false,
- })
- request.done(this.success.bind(this))
- },
-
- success: function(media){
- if (media.error) {
- return
- }
- this.$upload.removeClass('uploading')
- this.add(media)
- },
-
- add: function(media){
- console.log(media)
- },
+ var request = $.ajax({
+ url: this.uploadAction,
+ type: "post",
+ data: fd,
+ dataType: "json",
+ processData: false,
+ contentType: false,
+ })
+ request.done(this.success.bind(this))
+ },
+
+ success: function(media){
+ if (media.error) {
+ // console.log(media.error)
+ this.$upload.removeClass('uploading')
+ this.error(media.error)
+ return
+ }
+ this.$upload.removeClass('uploading')
+ this.add(media)
+ },
+
+ add: function(media){
+ console.log(media)
+ },
+
+ error: function(error){
+ },
})
diff --git a/public/assets/javascripts/ui/lib/View.js b/public/assets/javascripts/ui/lib/View.js
index d94e6db..9a8ab5b 100644
--- a/public/assets/javascripts/ui/lib/View.js
+++ b/public/assets/javascripts/ui/lib/View.js
@@ -1,139 +1,142 @@
var View = (function($, _){
- var View = function(options) {
- this._id = _.uniqueId('view')
- this.type = "view"
- options || (options = {});
- _.extend(this, _.pick(options, viewOptions))
- this._ensureElement()
- this.initialize.apply(this, arguments)
- this.delegateEvents()
- }
+ var View = function(options) {
+ this._id = _.uniqueId('view')
+ this.type = "view"
+ options || (options = {});
+ _.extend(this, _.pick(options, viewOptions))
+ this._ensureElement()
+ this.initialize.apply(this, arguments)
+ this.delegateEvents()
+ }
- var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+ var delegateEventSplitter = /^(\S+)\s*(.*)$/;
- var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
+ var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
- _.extend(View.prototype, {
+ _.extend(View.prototype, {
- // The default `tagName` of a View's element is `"div"`.
- tagName: 'div',
+ // The default `tagName` of a View's element is `"div"`.
+ tagName: 'div',
- $: function(selector) {
- return this.$el.find(selector);
- },
+ $: function(selector) {
+ return this.$el.find(selector);
+ },
- initialize: function(){},
+ initialize: function(){},
- setElement: function(element, delegate) {
- if (this.$el) this.undelegateEvents();
- this.$el = element instanceof $ ? element : $(element);
- this.el = this.$el[0];
- if (delegate !== false) this.delegateEvents();
- return this;
- },
+ setElement: function(element, delegate) {
+ if (this.$el) this.undelegateEvents();
+ this.$el = element instanceof $ ? element : $(element);
+ this.el = this.$el[0];
+ if (delegate !== false) this.delegateEvents();
+ return this;
+ },
- // Set callbacks, where `this.events` is a hash of
- //
- // *{"event selector": "callback"}*
- //
- // {
- // 'mousedown .title': 'edit',
- // 'click .button': 'save',
- // 'click .open': function(e) { ... }
- // }
- //
- // pairs. Callbacks will be bound to the view, with `this` set properly.
- // Uses event delegation for efficiency.
- // Omitting the selector binds the event to `this.el`.
- // This only works for delegate-able events: not `focus`, `blur`, and
- // not `change`, `submit`, and `reset` in Internet Explorer.
- delegateEvents: function(events) {
- if (!(events || (events = _.result(this, 'events')))) return this;
- this.undelegateEvents();
- for (var key in events) {
- var method = events[key];
- if (!_.isFunction(method)) method = this[events[key]];
- if (!method) continue;
+ // Set callbacks, where `this.events` is a hash of
+ //
+ // *{"event selector": "callback"}*
+ //
+ // {
+ // 'mousedown .title': 'edit',
+ // 'click .button': 'save',
+ // 'click .open': function(e) { ... }
+ // }
+ //
+ // pairs. Callbacks will be bound to the view, with `this` set properly.
+ // Uses event delegation for efficiency.
+ // Omitting the selector binds the event to `this.el`.
+ // This only works for delegate-able events: not `focus`, `blur`, and
+ // not `change`, `submit`, and `reset` in Internet Explorer.
+ delegateEvents: function(events) {
+ if (!(events || (events = _.result(this, 'events')))) return this;
+ this.undelegateEvents();
+ for (var key in events) {
+ var method = events[key];
+ if (!_.isFunction(method)) method = this[events[key]];
+ if (!method) continue;
- var match = key.match(delegateEventSplitter);
- var eventName = match[1], selector = match[2];
- method = _.bind(method, this);
- eventName += '.delegateEvents' + this._id;
- if (selector === '') {
- this.$el.on(eventName, method);
- } else {
- this.$el.on(eventName, selector, method);
- }
- }
- return this;
- },
+ var match = key.match(delegateEventSplitter);
+ var eventName = match[1], selector = match[2];
+ method = _.bind(method, this);
+ eventName += '.delegateEvents' + this._id;
+ if (is_mobile && (selector === 'mouseenter' || selector === 'mouseleave')) {
+ continue
+ }
+ else if (selector === '') {
+ this.$el.on(eventName, method);
+ } else {
+ this.$el.on(eventName, selector, method);
+ }
+ }
+ return this;
+ },
- // Clears all callbacks previously bound to the view with `delegateEvents`.
- undelegateEvents: function() {
- this.$el.off('.delegateEvents' + this._id);
- return this;
- },
+ // Clears all callbacks previously bound to the view with `delegateEvents`.
+ undelegateEvents: function() {
+ this.$el.off('.delegateEvents' + this._id);
+ return this;
+ },
- // Ensure that the View has a DOM element to render into.
- // If `this.el` is a string, pass it through `$()`, take the first
- // matching element, and re-assign it to `el`. Otherwise, create
- // an element from the `id`, `className` and `tagName` properties.
- _ensureElement: function() {
- this.setElement(_.result(this, 'el'), false);
- },
-
- preventDefault: function(e){
- e && e.preventDefault()
- },
-
- stopPropagation: function(e){
- e && e.stopPropagation()
- },
+ // Ensure that the View has a DOM element to render into.
+ // If `this.el` is a string, pass it through `$()`, take the first
+ // matching element, and re-assign it to `el`. Otherwise, create
+ // an element from the `id`, `className` and `tagName` properties.
+ _ensureElement: function() {
+ this.setElement(_.result(this, 'el'), false);
+ },
+
+ preventDefault: function(e){
+ e && e.preventDefault()
+ },
+
+ stopPropagation: function(e){
+ e && e.stopPropagation()
+ },
- });
+ });
- var extend = function(protoProps, staticProps) {
- var staticProps = staticProps || {}
- var parent = this;
- var child;
- var childEvents = {};
+ var extend = function(protoProps, staticProps) {
+ var staticProps = staticProps || {}
+ var parent = this;
+ var child;
+ var childEvents = {};
- // The constructor function for the new subclass is either defined by you
- // (the "constructor" property in your `extend` definition), or defaulted
- // by us to simply call the parent's constructor.
- if (protoProps && _.has(protoProps, 'constructor')) {
- child = protoProps.constructor;
- } else {
- child = function(){ return parent.apply(this, arguments); };
- }
+ // The constructor function for the new subclass is either defined by you
+ // (the "constructor" property in your `extend` definition), or defaulted
+ // by us to simply call the parent's constructor.
+ if (protoProps && _.has(protoProps, 'constructor')) {
+ child = protoProps.constructor;
+ } else {
+ child = function(){ return parent.apply(this, arguments); };
+ }
- // Extend events so we can subclass views
- _.extend(childEvents, parent.prototype.events, protoProps.events)
+ // Extend events so we can subclass views
+ _.extend(childEvents, parent.prototype.events, protoProps.events)
- // Add static properties to the constructor function, if supplied.
- _.extend(child, parent, staticProps);
+ // Add static properties to the constructor function, if supplied.
+ _.extend(child, parent, staticProps);
- // Set the prototype chain to inherit from `parent`, without calling
- // `parent`'s constructor function.
- var Surrogate = function(){ this.constructor = child; };
- Surrogate.prototype = parent.prototype;
- child.prototype = new Surrogate;
+ // Set the prototype chain to inherit from `parent`, without calling
+ // `parent`'s constructor function.
+ var Surrogate = function(){ this.constructor = child; };
+ Surrogate.prototype = parent.prototype;
+ child.prototype = new Surrogate;
- // Add prototype properties (instance properties) to the subclass,
- // if supplied.
- if (protoProps) _.extend(child.prototype, protoProps);
+ // Add prototype properties (instance properties) to the subclass,
+ // if supplied.
+ if (protoProps) _.extend(child.prototype, protoProps);
- // Set a convenience property in case the parent's prototype is needed
- // later.
- child.prototype.__super__ = parent.prototype;
- child.prototype.events = childEvents
+ // Set a convenience property in case the parent's prototype is needed
+ // later.
+ child.prototype.__super__ = parent.prototype;
+ child.prototype.events = childEvents
- return child;
- };
+ return child;
+ };
- View.extend = extend;
-
- return View;
+ View.extend = extend;
+
+ return View;
})(jQuery, _)
diff --git a/public/assets/javascripts/ui/reader/EmbedView.js b/public/assets/javascripts/ui/reader/EmbedView.js
new file mode 100644
index 0000000..7a75e00
--- /dev/null
+++ b/public/assets/javascripts/ui/reader/EmbedView.js
@@ -0,0 +1,76 @@
+var EmbedView = ModalView.extend({
+ el: ".embedView",
+
+ events: {
+ "keydown": "stopPropagation",
+ "input [name=width]": "build",
+ "input [name=height]": "build",
+ "click [name=mute]": "build",
+ "click [name=interactive]": "build",
+ "click textarea": "selectAll",
+ "click #testEmbed": "test",
+ },
+
+ defaultWidth: 600,
+ defaultHeight: 450,
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.$embedCode = this.$("#embedCode")
+ this.$width = this.$("[name=width]")
+ this.$height = this.$("[name=height]")
+ this.$mute = this.$("[name=mute]")
+ this.$interactive = this.$("[name=interactive]")
+
+ this.$width.val(this.defaultWidth)
+ this.$height.val(this.defaultHeight)
+ },
+
+ show: function(){
+ this.build()
+ this.__super__.show.call(this)
+ },
+
+ build: function(){
+ var kode = this.getEmbedCode()
+ this.$embedCode.val( kode )
+ },
+
+ getEmbedCode: function(){
+ var mute = this.$mute.prop('checked') ? 1 : 0
+ var interactive = this.$interactive.prop('checked') ? 1 : 0
+ var width = clamp( this.$width.int(), 0, 2000) || this.defaultWidth
+ var height = clamp( this.$height.int(), 0, 2000) || this.defaultHeight
+ var link = this.parent.getLink()
+ var embed_link = link
+ embed_link += "?mute=" + mute
+ embed_link += "&embed=1"
+ if (interactive) {
+ embed_link += "&interactive=1"
+ }
+
+ var kode = "<iframe src='" + encodeURI(embed_link) + "' width='" + width + "' height='" + height + "'"
+ kode += " seamless scrolling='no' style='border: 0'"
+ kode += " webkitallowfullscreen mozallowfullscreen allowfullscreen"
+ if (! interactive) {
+ kode += " style='pointer-events:none;'"
+ }
+ kode += "></iframe>"
+
+ if (! interactive) {
+ kode = "<div style='position:relative'>" + kode + "<a href='" + encodeURI(link) + "' style='display:block;position:absolute;top:0;left:0;width:" + width + "px;height:" + height + "px;'></a></div>"
+ }
+
+ return kode
+ },
+
+ test: function(){
+ var kode = this.getEmbedCode()
+ window.open("data:text/html," + kode, "_blank")
+ },
+
+ selectAll: function(){
+ this.$embedCode[0].select()
+ },
+
+})
diff --git a/public/assets/javascripts/ui/reader/MediaPlayer.js b/public/assets/javascripts/ui/reader/MediaPlayer.js
index df2d075..8e65976 100644
--- a/public/assets/javascripts/ui/reader/MediaPlayer.js
+++ b/public/assets/javascripts/ui/reader/MediaPlayer.js
@@ -1,5 +1,5 @@
-var MediaPlayer = FormView.extend({
+var MediaPlayer = View.extend({
el: "#mediaPlayer",
events: {
@@ -44,22 +44,26 @@ var MediaPlayer = FormView.extend({
this.unbind()
}
if (media.type == "image") {
- if ((! media.title || ! media.title.length) && (! media.description || ! media.description.length)) {
+ if ( ! media.description && (! media.title || media.title == filenameFromUrl(media.url)) ) {
this.hide()
- return
+ return false
}
}
+ else if (media.type == "text") {
+ return false
+ }
this.bind(scenery)
this.$el.addClass("active")
- this.$name.html(media.title)
- this.$description.html(media.description)
+ this.$name.html( sanitize(media.title) )
+ this.$description.html( marked(media.description) )
switch (media.type) {
case "image":
- this.$(".image").show()
this.$(".video").hide()
+ this.$(".audio").hide()
+ this.$(".image").show()
// this.$widthDimension.html( Number(media.widthDimension) || "" )
// this.$heightDimension.html( Number(media.heightDimension) || "" )
@@ -70,14 +74,24 @@ var MediaPlayer = FormView.extend({
case "youtube":
case "vimeo":
case "video":
- this.$(".video").show()
this.$(".image").hide()
+ this.$(".audio").hide()
+ this.$(".video").show()
this.$playButton.toggleClass("paused", ! this.scenery.paused())
this.$muteButton.toggleClass("muted", this.scenery.muted())
break
+
+ case "soundcloud":
+ this.$(".image").hide()
+ this.$(".video").hide()
+ this.$(".audio").show()
+
+ this.$playButton.toggleClass("paused", ! this.scenery.paused())
+ break
}
+ return true
},
hide: function(scenery){
diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js
index d80f225..43e81d8 100644
--- a/public/assets/javascripts/ui/reader/ReaderView.js
+++ b/public/assets/javascripts/ui/reader/ReaderView.js
@@ -9,36 +9,98 @@ var ReaderView = View.extend({
initialize: function(){
this.mediaPlayer = new MediaPlayer ({ parent: this })
+ this.shareView = new ShareView ({ parent: this })
},
load: function(name){
- if (window.location.search.indexOf("noui") !== -1) {
- $(".logo,.topLinks,#editorView").hide()
+ var opt = this.getQS()
+ var mode = "default"
+ var name = sanitize(name)
+
+ if (opt.noui) {
+ $(".logo, .topLinks, #editorView, #keyhint").hide()
+ mode = "noui"
+ }
+ if (opt.embed) {
+ $(".topLinks, .share, #edit-room-link, #keyhint").hide()
+ mode = "embed"
}
- if (window.location.search.indexOf("mute") !== -1) {
+ if (opt.mute) {
app.muted = true
}
- name = sanitize(name)
- $.get(this.projectAction + name, this.ready.bind(this))
+
+ this.tracker = new Tracker ({ mode: mode })
+
+ if ('vvalls_data' in window) {
+ this.ready(window.vvalls_data)
+ }
+ else {
+ $.get(this.projectAction + name, this.ready.bind(this))
+ }
+ },
+
+ getQS: function(){
+ var qs = {}
+ window.location.search.replace(/^\?/,"").split("&").forEach(function(s){
+ var pair = s.split("=")
+ if (pair.length < 2) {
+ qs[pair[0]] = true
+ }
+ else {
+ qs[pair[0]] = pair[1]
+ }
+ })
+ return qs
},
ready: function(data){
$("#map").hide()
+ this.data = data
+ var is_landscape = window.innerWidth > window.innerHeight
- data.rooms && Rooms.deserialize(data.rooms)
+ if (is_desktop || (is_mobile && is_landscape)) {
+ this.build(data)
+ return
+ }
+
+ // don't build anything until we're in landscape mode, otherwise ios might crash!!
+ var orientationFn = orientationchange.bind(this)
+ window.addEventListener('orientationchange', orientationFn)
+ function orientationchange (e) {
+ var is_landscape = window.innerWidth > window.innerHeight
+ if (is_landscape) {
+ window.removeEventListener('orientationchange', orientationFn)
+ this.build(data)
+ }
+ }
+ },
+
+ build: function(data){
+ if (data.shapes.length) {
+ Rooms.deserializeFromShapes(data)
+ }
+ else {
+ Rooms.deserialize(data.rooms)
+ }
data.walls && Walls.deserialize(data.walls)
data.media && Scenery.deserialize(data.media)
+ data.sculpture && Sculpture.deserialize(data.sculpture)
data.startPosition && scene.camera.move(data.startPosition)
+ cam.y = window.viewHeight = data.viewHeight || app.defaults.viewHeight
+
var colors = data.colors || app.defaults.colors
var modes = [ "wall", "outline", "floor", "ceiling" ]
modes.forEach(function(mode){
Walls.setColor[mode](colors[mode])
})
- editor.permissions.clear()
+ window.editor && editor.permissions.clear()
- this.listen()
+ // disable until we start using spinning again
+ // this.listen()
+
+ app.tube("site-ready")
},
listen: function(){
@@ -71,11 +133,19 @@ var ReaderView = View.extend({
},
pick: function(scenery){
- this.mediaPlayer.pick(scenery)
+ var has_info = this.mediaPlayer.pick(scenery)
+ $("#minimap").toggleClass('active', ! has_info)
+ app.tube("pick-scenery", { scenery: scenery })
+ },
+
+ pickWall: function(wall, pos){
+ this.hideExtras()
},
hideExtras: function(){
+ $("#minimap").addClass('active')
this.mediaPlayer.hide()
+ app.tube("close-scenery")
}
})
diff --git a/public/assets/javascripts/ui/reader/ShareView.js b/public/assets/javascripts/ui/reader/ShareView.js
new file mode 100644
index 0000000..dbe6f64
--- /dev/null
+++ b/public/assets/javascripts/ui/reader/ShareView.js
@@ -0,0 +1,62 @@
+var ShareView = View.extend({
+ el: ".share",
+
+ events: {
+ "keydown": "stopPropagation",
+ "click #share_facebook": "facebook",
+ "click #share_twitter": "twitter",
+ "click #share_embed": "embed",
+ },
+
+ initialize: function(opt){
+ this.parent = opt.parent
+ this.embedView = new EmbedView ({ parent: this })
+ this.$link = this.$("#share_link")
+ },
+
+ toggle: function(state){
+ if (typeof state == "boolean") {
+ this.$el.toggleClass("active", state)
+ }
+ else {
+ this.$el.toggleClass("active")
+ }
+ },
+ show: function(){
+ this.toggle(true)
+ },
+ hide: function(){
+ this.toggle(false)
+ },
+
+ setLink: function(url){
+ this.$link.val( url )
+ },
+ getLink: function(){
+ var link = window.location.origin + window.location.pathname
+ link = link.replace(/\/edit\/?$/, "")
+ return link
+ },
+
+ facebook: function (e) {
+ e.preventDefault()
+ var link = this.getLink()
+ var msg = app.controller.data.name + " on VValls"
+ var url = "https://www.facebook.com/share.php?u=" + encodeURIComponent(link) + "&t=" + encodeURIComponent(msg)
+ window.open(url, "_blank")
+ },
+
+ twitter: function (e) {
+ e.preventDefault()
+ var link = this.getLink()
+ var msg = app.controller.data.name + " on VValls"
+ var url = "https://twitter.com/home?status=" + encodeURIComponent(link + " " + msg)
+ window.open(url, "_blank")
+ },
+
+ embed: function (e) {
+ e.preventDefault()
+ this.embedView.show()
+ },
+
+})
diff --git a/public/assets/javascripts/ui/reader/Tracker.js b/public/assets/javascripts/ui/reader/Tracker.js
new file mode 100644
index 0000000..d2dec39
--- /dev/null
+++ b/public/assets/javascripts/ui/reader/Tracker.js
@@ -0,0 +1,133 @@
+if (window.location.host.indexOf("lvh.me") === -1) {
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+}
+else {
+ ga = function(){}
+}
+ga('create', 'UA-56883705-1', 'auto');
+ga('send', 'pageview');
+
+var Tracker = Fiber.extend(function(base){
+
+ var exports = {
+ init: function(opt){
+ this.wall_id = null
+ this.scenery_id = null
+ this.clicks = 0
+
+ this.wallTimer = new Timer ()
+ this.roomTimer = new Timer ()
+ this.sceneryTimer = new Timer ()
+
+ this.bind()
+ // this.trackPageview(opt)
+ },
+
+ bind: function () {
+ window.addEventListener("click", this.trackClick.bind(this), true)
+ app.on("change-wall", this.changeWall.bind(this))
+ app.on("pick-scenery", this.pickScenery.bind(this))
+ app.on("close-scenery", this.trackScenery.bind(this))
+ app.on("change-room", this.changeRoom.bind(this))
+ },
+
+ pushEvent: function(event){
+ // this.events.push(event)
+ event.unshift("send")
+ ga.apply( ga, event )
+ },
+
+ trackPageview: function(opt){
+ // this.pushEvent([ "view", opt.mode ])
+ },
+
+ //
+ // how long they spend in front of each wall
+
+ changeWall: function(opt){
+ var duration = this.wallTimer.currentTime()
+ if (this.wall_id && duration > 5000) {
+ this.pushEvent([ "wall", this.wall_id, duration ])
+ }
+ this.wall_id = opt.wall.id
+ this.wallTimer.start()
+ },
+
+ //
+ // how long the user spends on each item they click
+
+ pickScenery: function(opt){
+ if (this.scenery_id && opt.scenery.id !== this.scenery_id) {
+ this.trackScenery()
+ }
+ else {
+ this.sceneryTimer.start()
+ }
+ this.scenery_id = opt.scenery.id
+ },
+
+ trackScenery: function(){
+ var duration = this.sceneryTimer.currentTime()
+ if (this.scenery_id && duration > 1000) {
+ this.pushEvent([ "scenery", this.scenery_id, duration ])
+ }
+ this.scenery_id = null
+ this.sceneryTimer.reset()
+ },
+
+ //
+ // how long they spend in the room
+
+ changeRoom: function(opt){
+ var duration = this.roomTimer.currentTime()
+ if (this.room_id !== opt.room.id) {
+ if (this.room_id && duration > 5000) {
+ this.pushEvent([ "room", this.room_id, duration ])
+ }
+ this.roomTimer.start()
+ this.room_id = opt.room.id
+ }
+ },
+
+ //
+ // how many clicks per room
+
+ trackClick: function(opt){
+ this.clicks += 1
+ },
+
+ save: function () {
+ // possibly just push to google analytics
+ },
+
+ }
+
+ return exports
+})
+
+
+var Timer = Fiber.extend(function(base){
+ var exports = {
+
+ init: function(opt){
+ this.time = 0
+ },
+
+ reset: function(){
+ this.time = 0
+ },
+
+ start: function(){
+ this.time = Date.now()
+ },
+
+ currentTime: function(){
+ return this.time ? Date.now() - this.time : 0
+ },
+ }
+
+ return exports
+})
diff --git a/public/assets/javascripts/ui/reader/_router.js b/public/assets/javascripts/ui/reader/_router.js
new file mode 100644
index 0000000..f3b121b
--- /dev/null
+++ b/public/assets/javascripts/ui/reader/_router.js
@@ -0,0 +1,24 @@
+
+var SiteRouter = Router.extend({
+ el: "body",
+
+ initialize: function(){
+ app.launch()
+ if (app.unsupported) return
+
+ this.readerView = app.controller = new ReaderView()
+ this.readerView.load()
+
+ $("body").removeClass("loading")
+ }
+
+})
+
+var editor = {
+ permissions: new Permissions({
+ 'pick': true,
+ 'move': true,
+ 'resize': true,
+ 'destroy': false,
+ })
+}
diff --git a/public/assets/javascripts/ui/site/EditProfileModal.js b/public/assets/javascripts/ui/site/EditProfileModal.js
index b023923..d0e5d05 100644
--- a/public/assets/javascripts/ui/site/EditProfileModal.js
+++ b/public/assets/javascripts/ui/site/EditProfileModal.js
@@ -3,11 +3,14 @@ var EditProfileModal = ModalFormView.extend({
el: ".mediaDrawer.editProfile",
action: "/api/profile",
method: "put",
+
+ events: {
+ "click [data-role='changePasswordToggle']": 'togglePasswordFields'
+ },
load: function(){
this.reset()
$.get("/api/profile", function(data){
- console.log(data)
for (var i in data) {
this.$("[name='" + i + "']").val(data[i])
@@ -25,6 +28,10 @@ var EditProfileModal = ModalFormView.extend({
this.show()
}.bind(this))
},
+
+ togglePasswordFields: function(){
+ this.$("[data-role='changePasswordFields']").toggleClass("hidden")
+ },
validate: function(){
var errors = []
diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js
new file mode 100644
index 0000000..c1dc9f8
--- /dev/null
+++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js
@@ -0,0 +1,290 @@
+
+var EditSubscriptionModal = ModalView.extend({
+ el: ".mediaDrawer.editSubscription",
+ action: "/api/subscription",
+ syncAction: "/api/subscription/sync",
+ updateAction: "/api/subscription",
+ destroyAction: "/api/subscription/destroy",
+
+ fixedClose: true,
+ editing: false,
+ subscriber: null,
+ tempSubscriber: null,
+
+ events: {
+ "click [data-role='addLayouts']": 'addLayouts',
+ "click [data-role='changePlan']": 'changePlan',
+ "click [data-role='cancelSubscription']": 'destroy',
+ "click .gear": 'sync',
+ "click .planList button": 'followLink',
+
+ "click [data-role=showEditMenu]": "editMode",
+
+ "click [data-role=closeMenu]": "resetMode",
+
+ "input [data-role=basicLayoutInput]": "updateQuantity",
+ "input [data-role=proLayoutInput]": "updateQuantity",
+ "click [data-role=saveChanges]": "saveChanges",
+
+ "change [name=planRadio]": "updatePlan",
+ "click [data-role=savePlan]": "savePlan",
+
+ "submit form": "preventDefault",
+ },
+
+ initialize: function(){
+ // this.parent = opt.parent
+ this.__super__.initialize.call(this)
+
+ // two sections
+ this.$freePlan = this.$(".freePlan")
+ this.$paidPlan = this.$(".paidPlan")
+
+ // subscription table
+ this.$planInfo = this.$(".planInfo")
+ this.$planRow = this.$(".planRow")
+ this.$basicLayoutRow = this.$(".basicLayoutRow")
+ this.$proLayoutRow = this.$(".proLayoutRow")
+ this.$totalRow = this.$(".totalRow")
+ this.$planList = this.$(".planList")
+
+ this.$billingInterval = this.$("[data-role=billingInterval]")
+
+ // plan stuff
+ this.$planName = this.$("[data-role=planName]")
+ this.$planCost = this.$("[data-role=planCost]")
+ this.$planTotal = this.$("[data-role=planTotal]")
+
+ this.$basicPlanName = this.$("[data-role=basicPlanName]")
+ this.$basicPlanCost = this.$("[data-role=basicPlanCost]")
+
+ this.$proPlanName = this.$("[data-role=proPlanName]")
+ this.$proPlanCost = this.$("[data-role=proPlanCost]")
+
+ // basic + pro layout stuff
+ this.$basicLayoutCost = this.$("[data-role=basicLayoutCost]")
+ this.$basicLayoutQuantity = this.$("[data-role=basicLayoutQuantity]")
+ this.$basicLayoutTotal = this.$("[data-role=basicLayoutTotal]")
+
+ this.$proLayoutCost = this.$("[data-role=proLayoutCost]")
+ this.$proLayoutQuantity = this.$("[data-role=proLayoutQuantity]")
+ this.$proLayoutTotal = this.$("[data-role=proLayoutTotal]")
+
+ // menus.. main menu
+ this.$showEditMenu = this.$("[data-role=showEditMenu]")
+ this.$cancelSubscription = this.$("[data-role=cancelSubscription]")
+
+ // three submenus
+ this.$editMenu = this.$("[data-role=editMenu]")
+ this.$planMenu = this.$("[data-role=planMenu]")
+
+ this.$buyLayouts = this.$("[data-role=buyLayouts]")
+ this.$closeMenu = this.$("[data-role=closeMenu]")
+ this.$changePlan = this.$("[data-role=changePlan]")
+
+ // input fields
+ this.$basicLayoutInput = this.$("[data-role=basicLayoutInput]")
+ this.$proLayoutInput = this.$("[data-role=proLayoutInput]")
+ this.$planRadio = this.$("[name=planRadio]")
+ this.$basicPlanInput = this.$("[data-role=basicPlanInput]")
+ this.$proPlanInput = this.$("[data-role=proPlanInput]")
+
+ this.$gear = this.$(".gear")
+ },
+
+ plan_levels: {
+ free: 0,
+ basic: 1,
+ pro: 2,
+ custom: 3,
+ artist: 4,
+ },
+
+ loaded: false,
+ load: function(){
+ if (this.loaded) { return this.show() }
+ $.get(this.action, this.didLoad.bind(this))
+ },
+ didLoad: function(data){
+ this.loaded = true
+ this.plans = data.plans
+ if (data.subscription) {
+ this.subscriber = data.subscription
+ }
+ else if (data.error) {
+ // ...no subscription found
+ this.subscriber = null
+ }
+ return this.show()
+ },
+ followLink: function(e){
+ e.preventDefault();
+ window.location.href = $(e.target).closest("a").attr("href")
+ },
+
+ show: function(){
+ this.$gear.removeClass("turning")
+ if (! this.subscriber) {
+ this.$freePlan.show()
+ this.$paidPlan.hide()
+ this.$planList.load("/partials/plans", function(){
+ this.$(".free_plan_info").remove()
+ this.__super__.show.call(this)
+ }.bind(this))
+ return
+ }
+
+ this.$freePlan.hide()
+ this.$paidPlan.show()
+
+ this.resetMode()
+
+ this.__super__.show.call(this)
+ },
+ reset: function(){
+ var subscriber = this.subscriber
+ var plan = this.getPlan(subscriber.plan_type)
+ this.displayTotals(subscriber, plan)
+ },
+ getPlan: function(plan_type){
+ return this.plans[ this.plan_levels[ plan_type ] ]
+ },
+ calculateTotals: function(subscriber, plan){
+ var t = {}
+ t.is_pro = subscriber.plan_type == "pro"
+ t.is_monthly = subscriber.plan_period == "monthly"
+ t.plan_price = t.is_monthly ? plan.monthly_price : plan.yearly_price
+ t.basic_layout_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.basic_layout_yearly_price
+ t.basic_layout_total = subscriber.basic_layouts * t.basic_layout_price
+ t.pro_layout_price = t.is_monthly ? plan.pro_layout_monthly_price : plan.pro_layout_yearly_price
+ t.pro_layout_total = t.is_pro ? subscriber.pro_layouts * t.pro_layout_price : 0
+ t.plan_total = t.plan_price + t.basic_layout_total + t.pro_layout_total
+ return t
+ },
+ displayTotals: function(subscriber, plan){
+ var totals = this.calculateTotals(subscriber, plan)
+
+ this.$basicPlanName.html ( this.plans[1].name )
+ this.$proPlanName.html ( this.plans[2].name )
+ this.$basicPlanCost.toDollars ( totals.is_monthly ? this.plans[1].monthly_price : this.plans[2].yearly_price)
+ this.$proPlanCost.toDollars ( totals.is_monthly ? this.plans[2].monthly_price : this.plans[2].yearly_price)
+
+ this.$planName.html ( plan.name )
+ this.$planCost.toDollars ( totals.plan_price )
+
+ this.$billingInterval.html ( totals.is_monthly ? "mo." : "yr." )
+ this.$basicLayoutRow.toggle ( subscriber.basic_layouts > 0 )
+ this.$proLayoutRow.toggle ( totals.is_pro && subscriber.pro_layouts > 0)
+
+ this.$basicLayoutCost.toDollars ( totals.basic_layout_price )
+ this.$basicLayoutQuantity.html ( subscriber.basic_layouts )
+ this.$basicLayoutTotal.toDollars ( totals.basic_layout_total )
+
+ this.$proLayoutCost.toDollars ( totals.pro_layout_price )
+ this.$proLayoutQuantity.html ( subscriber.pro_layouts )
+ this.$proLayoutTotal.toDollars ( totals.pro_layout_total )
+
+ this.$planTotal.toDollars ( totals.plan_total )
+ },
+
+ editMode: function(e){
+ e && e.preventDefault()
+
+ this.editing = true
+ this.$el.addClass("editing")
+ this.tempSubscriber = defaults({}, this.subscriber)
+ this.$basicLayoutInput.val( this.subscriber.basic_layouts )
+ this.$proLayoutInput.val( this.subscriber.pro_layouts )
+ this.$basicLayoutRow.show()
+ this.$proLayoutRow.toggle(this.subscriber.plan_type == "pro")
+ switch (this.subscriber.plan_type) {
+ case 'basic': this.$basicPlanInput.prop('checked', true); break;
+ case 'pro': this.$proPlanInput.prop('checked', true); break;
+ }
+ },
+ resetMode: function(e){
+ e && e.preventDefault()
+ this.editing = false
+ this.$el.removeClass("editing")
+ this.reset()
+ },
+
+ updateQuantity: function(e){
+ e && e.preventDefault()
+ var plan = this.getPlan( this.tempSubscriber.plan_type )
+ this.tempSubscriber.basic_layouts = clamp( this.$basicLayoutInput.int() || 0, 0, 100)
+ this.tempSubscriber.pro_layouts = clamp( this.$proLayoutInput.int() || 0, 0, 100)
+
+ this.$basicLayoutInput.val(this.tempSubscriber.basic_layouts)
+ this.$proLayoutInput.val(this.tempSubscriber.pro_layouts)
+ this.displayTotals(this.tempSubscriber, plan)
+ this.$basicLayoutRow.show()
+ this.$proLayoutRow.toggle(this.tempSubscriber.plan_type == "pro")
+ },
+ saveChanges: function(e){
+ e && e.preventDefault()
+ var is_changed = false
+ var diff = {}
+ "plan_type basic_layouts pro_layouts".split(" ").forEach(function(field){
+ diff[field] = this.tempSubscriber[field]
+ if (this.tempSubscriber[field] != this.subscriber[field]) {
+ is_changed = true
+ }
+ }.bind(this))
+
+ if (is_changed) {
+ this.update(diff)
+ }
+ this.subscriber = this.tempSubscriber
+ this.resetMode()
+ },
+
+ updatePlan: function(e){
+ e && e.preventDefault()
+ this.tempSubscriber.plan_type = this.$("[name=planRadio]:checked").val()
+ this.updateQuantity()
+ },
+
+ sync: function(){
+ this.$gear.addClass("turning")
+ $.ajax({
+ url: this.syncAction,
+ type: "put",
+ data: { _csrf: $("[name=_csrf]").val() },
+ success: this.didLoad.bind(this)
+ })
+ },
+
+ update: function(data){
+ data['_csrf'] = $("[name=_csrf]").val()
+ this.$gear.addClass("turning")
+ $.ajax({
+ url: this.updateAction,
+ type: "put",
+ data: data,
+ success: function(data){
+ this.$gear.removeClass("turning")
+ }.bind(this)
+ })
+ },
+
+ destroy: function(e){
+ e.preventDefault()
+ var msg = "Are you sure you want to cancel your subscription?"
+ ConfirmModal.confirm(msg, function(){
+ $.ajax({
+ url: this.destroyAction,
+ type: "delete",
+ data: { _csrf: $("[name=_csrf]").val() },
+ success: function(data){
+ this.subscriber = null
+ this.didLoad(data)
+ }.bind(this)
+ })
+ }.bind(this),
+ function(){
+ this.show()
+ }.bind(this))
+ },
+
+})
diff --git a/public/assets/javascripts/ui/site/HomeView.js b/public/assets/javascripts/ui/site/HomeView.js
index 02f9ab9..20452bd 100644
--- a/public/assets/javascripts/ui/site/HomeView.js
+++ b/public/assets/javascripts/ui/site/HomeView.js
@@ -6,6 +6,32 @@ var HomeView = View.extend({
load: function() {
this.projectList = new ProjectList ()
- }
+
+ var iframe = $("#okplayer")[0]
+ var player = $f( iframe )
+ player.addEvent('ready', function(){
+ player.addEvent('play', function(){
+ player.api('setVolume', 1.0)
+ })
+ player.addEvent('finish', function(){
+ hide()
+ })
+ })
+ $('.hero .circle').click( function(){
+ $('.videoModal').css("display","table").addClass('active');
+ player.api('play')
+ })
+
+ $('.videoModal .ion-ios-close-empty').click( function(){
+ player.api('pause')
+ hide()
+ })
+
+ function hide() {
+ $('.videoModal').fadeOut(300, function(){
+ $('.videoModal').removeClass('active')
+ })
+ }
+ },
})
diff --git a/public/assets/javascripts/ui/site/LayoutsIndex.js b/public/assets/javascripts/ui/site/LayoutsIndex.js
new file mode 100644
index 0000000..f7272bb
--- /dev/null
+++ b/public/assets/javascripts/ui/site/LayoutsIndex.js
@@ -0,0 +1,85 @@
+
+var LayoutsIndex = View.extend({
+
+ initialize: function(){
+ this.$templates = this.$(".templates")
+ this.$templatesList = this.$(".templates-list")
+ this.$noTemplates = this.$(".no-templates")
+ this.$form = this.$("form")
+
+ this.$userTemplatesList = this.$(".userTemplatesList")
+ this.$blueprintsList = this.$(".blueprintsList")
+ this.$newBlueprintButton = this.$("[data-role='create-new-blueprint']")
+ },
+
+ load: function(type){
+ this.$templates.children("span").remove()
+
+ $.get(this.action, this.populate.bind(this))
+ },
+
+ populate: function(data){
+ if (! data.layouts.length) {
+ this.$templates.hide()
+ this.$form.hide()
+ this.$noTemplates.show()
+ }
+ this.$templatesList.empty()
+ data.layouts.forEach(function(room){
+ var $span = $("<span>")
+ $span.data("slug", room.slug)
+
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+ this.show()
+ }
+
+})
+
+
+
+var ProjectsModal = ModalView.extend(LayoutsIndex.prototype).extend({
+ el: ".mediaDrawer.projects",
+
+ action: "/api/project",
+
+ events: {
+ "click .templates span": 'toggleActive',
+ "submit form": 'newProject',
+ },
+
+ populate: function(data){
+ if (! data.length) {
+ app.router.newProject()
+ }
+ else {
+ this.__super__.populate.call(this, data)
+ }
+ },
+
+ toggleActive: function(e){
+ e.preventDefault()
+ this.$(".templates .active").removeClass("active")
+ var $layout = $(e.currentTarget)
+ $layout.addClass("active")
+
+ // actually do
+ window.location.pathname = "/project/" + $layout.data("slug") + "/edit"
+ },
+
+ newProject: function(e){
+ e && e.preventDefault()
+ window.location.pathname = "/project/new"
+ }
+
+})
+
diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js
index 2449465..0222077 100644
--- a/public/assets/javascripts/ui/site/LayoutsModal.js
+++ b/public/assets/javascripts/ui/site/LayoutsModal.js
@@ -1,127 +1,106 @@
+var LayoutsModal = ModalView.extend(LayoutsIndex.prototype).extend({
+ el: ".mediaDrawer.layouts",
-var LayoutsIndex = View.extend({
+ action: "/api/layout",
- initialize: function(){
- this.$templates = this.$(".templates")
- this.$noTemplates = this.$(".no-templates")
- this.$form = this.$("form")
+ events: {
+ "click [data-role='create-new-layout']": 'createNewLayout',
+ "click [data-role='create-new-blueprint']": 'createNewBlueprint',
+ "click .templates span": 'pick',
},
+
+ pick: function(e){
+ e.preventDefault()
+ var layout = $(e.currentTarget).data("slug")
+ var isBlueprint = $(e.currentTarget).data("blueprint")
- load: function(type){
- this.$templates.children("span").remove()
+ if (! layout || ! layout.length) return
- $.get(this.action, this.populate.bind(this))
+ if (isBlueprint) {
+ window.location.pathname = "/blueprint/" + layout
+ }
+ else {
+ window.location.pathname = "/layout/" + layout
+ }
+ },
+
+ createNewLayout: function(e){
+ e.preventDefault()
+ window.location.pathname = "/layout/new"
+ },
+
+ createNewBlueprint: function(e){
+ e.preventDefault()
+ window.location.pathname = "/blueprint/new"
},
populate: function(data){
- if (! data.length) {
+/*
+ if (data.user.plan_level < 1 && data.projectCount == 1) {
+ // show lockout message
+ }
+*/
+ if (! data.layouts.length) {
this.$templates.hide()
this.$form.hide()
this.$noTemplates.show()
}
- this.$templates.empty()
- data.forEach(function(room){
+ this.$templatesList.empty()
+ data.layouts.forEach(function(room){
var $span = $("<span>")
- // $span.html(JSON.stringify(room))
$span.data("slug", room.slug)
- $span.css("background-image", "url(" + room.photo + ")")
- $span.attr("data-name", room.name)
- this.$templates.append($span)
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
}.bind(this))
- console.log(this.$templates.html())
- this.show()
- }
-
-})
-
-var ProjectsModal = ModalView.extend(LayoutsIndex.prototype).extend({
- el: ".mediaDrawer.projects",
-
- action: "/api/project",
-
- events: {
- "click .templates span": 'toggleActive',
- "submit form": 'newProject',
- },
-
- populate: function(data){
- if (! data.length) {
- app.router.newProject()
- }
- else {
- this.__super__.populate.call(this, data)
- }
- },
-
- toggleActive: function(e){
- e.preventDefault()
- this.$(".templates .active").removeClass("active")
- var $layout = $(e.currentTarget)
- $layout.addClass("active")
-
- // actually do
- window.location.pathname = "/project/" + $layout.data("slug") + "/edit"
- },
-
- newProject: function(e){
- e && e.preventDefault()
- window.location.pathname = "/project/new"
- }
-
-})
-
-
-var LayoutsModal = ModalView.extend(LayoutsIndex.prototype).extend({
- el: ".mediaDrawer.layouts",
-
- action: "/api/layout",
- events: {
- "click .templates span": 'toggleActive',
- "submit form": 'newLayout',
- },
-
- toggleActive: function(e){
- e.preventDefault()
- this.$(".templates .active").removeClass("active")
- var $layout = $(e.currentTarget)
- $layout.addClass("active")
+ data.user_layouts.forEach(function(room){
+ var $span = $("<span>")
+ $span.data("slug", room.slug)
+
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+
+ data.blueprints.forEach(function(blueprint){
+ var $span = $("<span>")
+ $span.data("slug", blueprint.slug)
+ $span.data("blueprint", true)
+
+ var $label = $("<label>")
+ $label.html( blueprint.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + blueprint.url + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
- // actually do
- window.location.pathname = "/layout/" + $layout.data("slug")
+ this.show()
},
-
+
newLayout: function(e){
e && e.preventDefault()
window.location.pathname = "/layout/new"
}
})
-
-
-var NewProjectModal = ModalView.extend(LayoutsIndex.prototype).extend({
- el: ".mediaDrawer.newProject",
-
- action: "/api/layout",
-
- events: {
- "click .templates span": 'choose',
- "submit form": 'choose',
- },
-
- toggleActive: function(e){
- e.preventDefault()
- this.$(".templates .active").removeClass("active")
- $(e.currentTarget).addClass("active")
- },
-
- choose: function(e){
- e && e.preventDefault()
-// var layout = this.$(".templates .active").data("slug")
- var layout = $(e.currentTarget).data("slug")
- if (! layout || ! layout.length) return
- window.location.pathname = "/project/new/" + layout
- }
-
-})
diff --git a/public/assets/javascripts/ui/site/NewProjectModal.js b/public/assets/javascripts/ui/site/NewProjectModal.js
new file mode 100644
index 0000000..31675ba
--- /dev/null
+++ b/public/assets/javascripts/ui/site/NewProjectModal.js
@@ -0,0 +1,118 @@
+var NewProjectModal = ModalView.extend(LayoutsIndex.prototype).extend({
+ el: ".mediaDrawer.newProject",
+
+ action: "/api/layout",
+
+ events: {
+ "click [data-role='create-new-layout']": 'createNewLayout',
+ "click [data-role='create-new-blueprint']": 'createNewBlueprint',
+ "click .templates span": 'pick',
+ },
+
+ toggleActive: function(e){
+ e.preventDefault()
+ this.$(".templates .active").removeClass("active")
+ $(e.currentTarget).addClass("active")
+ },
+
+ pick: function(e){
+ e && e.preventDefault()
+// var layout = this.$(".templates .active").data("slug")
+ var layout = $(e.currentTarget).data("slug")
+ var isBlueprint = $(e.currentTarget).data("blueprint")
+ if (! layout || ! layout.length) return
+
+ if (isBlueprint) {
+ window.location.pathname = "/project/blueprint/" + layout
+ }
+ else {
+ window.location.pathname = "/project/new/" + layout
+ }
+ },
+
+ createNewLayout: function(e){
+ e.preventDefault()
+ window.location.pathname = "/project/new/empty"
+ },
+
+ createNewBlueprint: function(e){
+ e.preventDefault()
+ window.location.pathname = "/blueprint/new"
+ },
+
+ populate: function(data){
+/*
+ if (data.user.plan_level < 1 && data.projectCount == 1) {
+ // show lockout message
+ this.$newBlueprintButton.hide()
+ }
+*/
+ if (! data.layouts.length) {
+ this.$templates.hide()
+ this.$form.hide()
+ this.$noTemplates.show()
+ }
+ if (! data.blueprints.length) {
+ this.$blueprintsList.parent().hide()
+ }
+ if (! data.user_layouts.length) {
+ this.$userTemplatesList.parent().hide()
+ }
+
+ this.$templatesList.empty()
+ data.layouts.forEach(function(room){
+ var $span = $("<span>")
+ $span.data("slug", room.slug)
+
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+
+ data.user_layouts.forEach(function(room){
+ var $span = $("<span>")
+ $span.data("slug", room.slug)
+
+ var $label = $("<label>")
+ $label.html( room.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + room.photo + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+
+ data.blueprints.forEach(function(blueprint){
+ if (! blueprint.slug) { return }
+
+ var $span = $("<span>")
+ $span.data("blueprint", true)
+ $span.data("slug", blueprint.slug)
+
+ var $label = $("<label>")
+ $label.html( blueprint.name )
+
+ var $image = $("<span>")
+ $image.addClass("image").css("background-image", "url(" + blueprint.url + ")")
+
+ $span.append( $image )
+ $span.append( $label )
+
+ this.$templatesList.append($span)
+ }.bind(this))
+
+ this.show()
+ },
+
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/site/ProfileView.js b/public/assets/javascripts/ui/site/ProfileView.js
index f3b35d9..8471abc 100644
--- a/public/assets/javascripts/ui/site/ProfileView.js
+++ b/public/assets/javascripts/ui/site/ProfileView.js
@@ -1,6 +1,12 @@
var ProfileView = View.extend({
+ el: ".profilepage",
+
+ events: {
+ "change #profile_avatar": "uploadAvatar",
+ },
+
initialize: function() {
},
@@ -12,6 +18,28 @@ var ProfileView = View.extend({
$(".bio").addClass(choice(classes));
this.projectList = new ProjectList ()
+ },
+
+ uploadAvatar: function(){
+ var fd = new FormData(), hasCSRF = false
+ var files = this.$("#profile_avatar")[0].files
+ if (! files.length) return
+
+ fd.append("avatar", files[0]);
+ fd.append("_csrf", $("[name=_csrf]").val())
+
+ var request = $.ajax({
+ url: "/api/profile",
+ type: "put",
+ data: fd,
+ dataType: "json",
+ processData: false,
+ contentType: false,
+ })
+
+ request.done($.proxy(function (response) {
+ window.location.href = "/profile"
+ }, this));
}
})
diff --git a/public/assets/javascripts/ui/site/ProjectList.js b/public/assets/javascripts/ui/site/ProjectList.js
index 993d805..076a674 100644
--- a/public/assets/javascripts/ui/site/ProjectList.js
+++ b/public/assets/javascripts/ui/site/ProjectList.js
@@ -1,16 +1,75 @@
+var projectListTimeout = null
var ProjectList = View.extend({
el: ".projectList",
events: {
- "mouseenter .room": 'spinOn',
- "mouseleave .room": 'spinOff',
+ "click .viewMore": 'viewMore',
+ "mouseenter .room": 'enter',
+ "mouseleave .room": 'leave',
},
initialize: function(){
+ this.$viewMore = this.$(".viewMore")
+ this.$(".images").each(function(){
+ $divs = $(this).children("div")
+ $divs.hide()
+ $divs.first().show()
+ $(this).data("index", 0)
+ })
},
+ timeout: null,
+ enter: function(e){
+ clearTimeout(projectListTimeout)
+ this.advance(e.currentTarget)
+ },
+
+ leave: function(e){
+ clearTimeout(projectListTimeout)
+ var $divs = $(e.currentTarget).find(".images div")
+ $divs.hide()
+ $divs.eq(0).show()
+ },
+
+ advance: function(el){
+ projectListTimeout = setTimeout(function(){
+ this.advance(el)
+ }.bind(this), 500)
+ var $images = $(el).find(".images")
+ var $divs = $images.children("div")
+ var index = $images.data("index")
+ var nextIndex = (index + 1) % $divs.length
+ $divs.eq(index).hide()
+ $divs.eq(nextIndex).show()
+ $images.data("index", nextIndex)
+ },
+
+ viewMore: function(e){
+ e.preventDefault()
+ var criteria = {}
+ criteria.offset = this.$(".projectItem").length
+ if (window.location.pathname == "/" || window.location.pathname.match("/home")) {
+ criteria.home = 1
+ }
+ else {
+ criteria.user_id = this.$(".projectItem").first().data("userid")
+ }
+
+ $.get("/api/project/paginate", criteria, function(data){
+ var offset = this.$viewMore.offset()
+ var $data = $(data)
+ var $els = $data.find(".projectItem")
+ $els.insertBefore( this.$viewMore )
+ if (! $data.find(".viewMore").length) {
+ this.$viewMore.hide()
+ }
+ $("body,html").animate({ scrollTop: offset.top - 80 }, 300)
+ }.bind(this))
+ },
+
+/*
spinOn: function(e){
var iframe = $(e.currentTarget).find("iframe").get('0')
if (! iframe) return
@@ -22,5 +81,6 @@ var ProjectList = View.extend({
if (! iframe) return
iframe.contentWindow.postMessage("spin-off", window.location.origin)
}
+*/
})
diff --git a/public/assets/javascripts/ui/site/StaffView.js b/public/assets/javascripts/ui/site/StaffView.js
index fdf39d2..97f86c2 100644
--- a/public/assets/javascripts/ui/site/StaffView.js
+++ b/public/assets/javascripts/ui/site/StaffView.js
@@ -3,14 +3,29 @@ var StaffView = View.extend({
events: {
"click #toggle-staff": "toggleStaff",
+ "click #toggle-featured": "toggleFeatured",
+ "click #toggle-stock": "toggleStock",
+ "click #toggle-artist": "toggleArtist",
},
initialize: function() {
this.$toggleStaff = $("#toggle-staff")
+ this.$toggleFeatured = $("#toggle-featured")
+ this.$toggleStock = $("#toggle-stock")
+ this.$toggleArtist = $("#toggle-artist")
this.$mediaEmbed = $("#media-embed")
if (this.$toggleStaff.length && this.$toggleStaff.data().isstaff) {
this.$toggleStaff.html("Is Staff")
}
+ if (this.$toggleFeatured.length && this.$toggleFeatured.data().featured) {
+ this.$toggleFeatured.html("Featured Project")
+ }
+ if (this.$toggleStock.length && this.$toggleStock.data().stock) {
+ this.$toggleStock.html("Layout is Stock")
+ }
+ if (this.$toggleArtist.length && this.$toggleArtist.data().isartist) {
+ this.$toggleArtist.html("Is Artist")
+ }
if (this.$mediaEmbed.length) {
var media = this.$mediaEmbed.data()
this.$mediaEmbed.html( Parser.tag( media ) )
@@ -44,6 +59,59 @@ var StaffView = View.extend({
}.bind(this)
})
}.bind(this))
- },
+ },
+ toggleFeatured: function(){
+ var state = ! this.$toggleFeatured.data().featured
+ $.ajax({
+ type: "put",
+ dataType: "json",
+ url: window.location.href + "/feature",
+ data: {
+ state: state,
+ _csrf: $("#_csrf").val(),
+ },
+ success: function(data){
+ this.$toggleFeatured.data("featured", data.state)
+ this.$toggleFeatured.html(data.state ? "Featured Project" : "Feature this project")
+ $("#isFeaturedProject").html(data.state ? "yes" : "no")
+ }.bind(this)
+ })
+ },
+
+ toggleStock: function(){
+ var state = ! this.$toggleStock.data().stock
+ $.ajax({
+ type: "put",
+ dataType: "json",
+ url: window.location.href + "/stock",
+ data: {
+ state: state,
+ _csrf: $("#_csrf").val(),
+ },
+ success: function(data){
+ this.$toggleStock.data("stock", data.state)
+ this.$toggleStock.html(data.state ? "Stock Layout" : "Make this layout Stock")
+ $("#isStockLayout").html(data.state ? "yes" : "no")
+ }.bind(this)
+ })
+ },
+
+ toggleArtist: function(){
+ var state = ! this.$toggleArtist.data().isartist
+ $.ajax({
+ type: "put",
+ dataType: "json",
+ url: window.location.href + "/artist",
+ data: {
+ state: state,
+ _csrf: $("#_csrf").val(),
+ },
+ success: function(data){
+ this.$toggleArtist.data("stock", data.state)
+ this.$toggleArtist.html(data.state ? "Is Artist" : "Make Artist")
+ $("#isArtist").html(data.state ? "yes" : "no")
+ }.bind(this)
+ })
+ },
})
diff --git a/public/assets/javascripts/ui/z_share.js b/public/assets/javascripts/ui/z_share.js
deleted file mode 100644
index d31aa89..0000000
--- a/public/assets/javascripts/ui/z_share.js
+++ /dev/null
@@ -1,25 +0,0 @@
-var share = {
- init: function(){
- share.bind()
- },
- bind: function(){
- $("#facebook").click(share.facebook)
- $("#twitter").click(share.twitter)
- },
- url: "http://vvalls.com/",
- facebook_msg: "",
- twitter_msg: "",
- openLink: function (url) {
- window.open(url, "_blank");
- },
- facebook: function () {
- var url = "https://www.facebook.com/share.php?u=" + encodeURIComponent(share.url) + "&t=" + encodeURIComponent(share.facebook_msg);
- share.openLink(url);
- return false;
- },
- twitter: function () {
- var url = "https://twitter.com/home?status=" + encodeURIComponent(share.url + " " + share.twitter_msg);
- share.openLink(url);
- return false;
- }
-}
diff --git a/public/assets/javascripts/util.js b/public/assets/javascripts/util.js
index 7812a4d..0f5c6ed 100644
--- a/public/assets/javascripts/util.js
+++ b/public/assets/javascripts/util.js
@@ -4,11 +4,14 @@ if (window.$) {
$.fn.string = function() { return trim($(this).val()) }
$.fn.enable = function() { return $(this).attr("disabled",null) }
$.fn.disable = function() { return $(this).attr("disabled","disabled") }
+ $.fn.sanitize = function(s) { return trim(sanitize($(this).val())) }
$.fn.htmlSafe = function(s) { return $(this).html(sanitize(s)) }
+ $.fn.toDollars = function(i) { return $(this).html((i/100).toFixed(2)) }
}
-function trim(s){ return s.replace(/^\s+/,"").replace(/\s+$/,"") }
+function trim (s){ return s.replace(/^\s+/,"").replace(/\s+$/,"") }
function sanitize (s){ return (s || "").replace(new RegExp("[<>&]", 'g'), "") }
+function stripHTML (s){ return (s || "").replace(/<[^>]+>/g, "") }
function capitalize (s){ return s.split(" ").map(capitalizeWord).join(" ") }
function capitalizeWord (s){ return s.charAt(0).toUpperCase() + s.slice(1) }
function slugify (s){ return (s || "").toLowerCase().replace(/\s/g,"-").replace(/[^-_a-zA-Z0-9]/g, '-').replace(/-+/g,"-") }
@@ -92,9 +95,10 @@ function smoothstep(min,max,n){
}
function shuffle(a){
+ var r, swap
for (var i = a.length; i > 0; i--){
- var r = randint(i)
- var swap = a[i-1]
+ r = randint(i)
+ swap = a[i-1]
a[i-1] = a[r]
a[r] = swap
}
@@ -173,9 +177,80 @@ function invert_hash (h) {
for (var i in h) { if (h.hasOwnProperty(i)) k[h[i]] = i }
return k
}
+function filenameFromUrl (url) {
+ var partz = url.split( "/" )
+ return partz[partz.length-1].split(".")[0]
+}
function bitcount(v) {
v = v - ((v >>> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);
return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;
}
+
+// Function.bind polyfill
+if (!Function.prototype.bind) {
+ Function.prototype.bind = function(oThis) {
+ if (typeof this !== 'function') {
+ // closest thing possible to the ECMAScript 5
+ // internal IsCallable function
+ throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
+ }
+
+ var aArgs = Array.prototype.slice.call(arguments, 1),
+ fToBind = this,
+ fNOP = function() {},
+ fBound = function() {
+ return fToBind.apply(this instanceof fNOP && oThis
+ ? this
+ : oThis,
+ aArgs.concat(Array.prototype.slice.call(arguments)));
+ };
+
+ fNOP.prototype = this.prototype;
+ fBound.prototype = new fNOP();
+
+ return fBound;
+ };
+}
+
+// rAF polyfill
+(function() {
+ var lastTime = 0;
+ var vendors = ['ms', 'moz', 'webkit', 'o'];
+ for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
+ window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
+ window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
+ || window[vendors[x]+'CancelRequestAnimationFrame'];
+ }
+
+ if (!window.requestAnimationFrame)
+ window.requestAnimationFrame = function(callback, element) {
+ var currTime = new Date().getTime();
+ var timeToCall = Math.max(0, 16 - (currTime - lastTime));
+ var id = window.setTimeout(function() { callback(currTime + timeToCall); },
+ timeToCall);
+ lastTime = currTime + timeToCall;
+ return id;
+ };
+
+ if (!window.cancelAnimationFrame)
+ window.cancelAnimationFrame = function(id) {
+ clearTimeout(id);
+ };
+}());
+
+
+function selectElementContents(el) {
+ if (window.getSelection && document.createRange) {
+ var sel = window.getSelection();
+ var range = document.createRange();
+ range.selectNodeContents(el);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ } else if (document.selection && document.body.createTextRange) {
+ var textRange = document.body.createTextRange();
+ textRange.moveToElementText(el);
+ textRange.select();
+ }
+}
diff --git a/public/assets/javascripts/vendor/canvasutilities.js b/public/assets/javascripts/vendor/canvasutilities.js
new file mode 100644
index 0000000..011ebb0
--- /dev/null
+++ b/public/assets/javascripts/vendor/canvasutilities.js
@@ -0,0 +1,145 @@
+var drawArrow = function(ctx, x1, y1, x2, y2, style, which, angle, d) {
+ 'use strict';
+ // Ceason pointed to a problem when x1 or y1 were a string, and concatenation
+ // would happen instead of addition
+ if (typeof(x1) == 'string') x1 = parseInt(x1);
+ if (typeof(y1) == 'string') y1 = parseInt(y1);
+ if (typeof(x2) == 'string') x2 = parseInt(x2);
+ if (typeof(y2) == 'string') y2 = parseInt(y2);
+ style = typeof(style) != 'undefined' ? style : 3;
+ which = typeof(which) != 'undefined' ? which : 1; // end point gets arrow
+ angle = typeof(angle) != 'undefined' ? angle : Math.PI / 8;
+ d = typeof(d) != 'undefined' ? d : 10;
+ // default to using drawHead to draw the head, but if the style
+ // argument is a function, use it instead
+ var toDrawHead = typeof(style) != 'function' ? drawHead : style;
+
+ // For ends with arrow we actually want to stop before we get to the arrow
+ // so that wide lines won't put a flat end on the arrow.
+ //
+ var dist = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+ var ratio = (dist - d / 3) / dist;
+ var tox, toy, fromx, fromy;
+ if (which & 1) {
+ tox = Math.round(x1 + (x2 - x1) * ratio);
+ toy = Math.round(y1 + (y2 - y1) * ratio);
+ } else {
+ tox = x2;
+ toy = y2;
+ }
+ if (which & 2) {
+ fromx = x1 + (x2 - x1) * (1 - ratio);
+ fromy = y1 + (y2 - y1) * (1 - ratio);
+ } else {
+ fromx = x1;
+ fromy = y1;
+ }
+
+ // Draw the shaft of the arrow
+ ctx.beginPath();
+ ctx.moveTo(fromx, fromy);
+ ctx.lineTo(tox, toy);
+ ctx.stroke();
+
+ // calculate the angle of the line
+ var lineangle = Math.atan2(y2 - y1, x2 - x1);
+ // h is the line length of a side of the arrow head
+ var h = Math.abs(d / Math.cos(angle));
+
+ if (which & 1) { // handle far end arrow head
+ var angle1 = lineangle + Math.PI + angle;
+ var topx = x2 + Math.cos(angle1) * h;
+ var topy = y2 + Math.sin(angle1) * h;
+ var angle2 = lineangle + Math.PI - angle;
+ var botx = x2 + Math.cos(angle2) * h;
+ var boty = y2 + Math.sin(angle2) * h;
+ toDrawHead(ctx, topx, topy, x2, y2, botx, boty, style);
+ }
+ if (which & 2) { // handle near end arrow head
+ var angle1 = lineangle + angle;
+ var topx = x1 + Math.cos(angle1) * h;
+ var topy = y1 + Math.sin(angle1) * h;
+ var angle2 = lineangle - angle;
+ var botx = x1 + Math.cos(angle2) * h;
+ var boty = y1 + Math.sin(angle2) * h;
+ toDrawHead(ctx, topx, topy, x1, y1, botx, boty, style);
+ }
+}
+
+var drawHead = function(ctx, x0, y0, x1, y1, x2, y2, style) {
+ 'use strict';
+ if (typeof(x0) == 'string') x0 = parseInt(x0);
+ if (typeof(y0) == 'string') y0 = parseInt(y0);
+ if (typeof(x1) == 'string') x1 = parseInt(x1);
+ if (typeof(y1) == 'string') y1 = parseInt(y1);
+ if (typeof(x2) == 'string') x2 = parseInt(x2);
+ if (typeof(y2) == 'string') y2 = parseInt(y2);
+ var radius = 3;
+ var twoPI = 2 * Math.PI;
+
+ // all cases do this.
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(x0, y0);
+ ctx.lineTo(x1, y1);
+ ctx.lineTo(x2, y2);
+ switch (style) {
+ case 0:
+ // curved filled, add the bottom as an arcTo curve and fill
+ var backdist = Math.sqrt(((x2 - x0) * (x2 - x0)) + ((y2 - y0) * (y2 - y0)));
+ ctx.arcTo(x1, y1, x0, y0, .55 * backdist);
+ ctx.fill();
+ break;
+ case 1:
+ // straight filled, add the bottom as a line and fill.
+ ctx.beginPath();
+ ctx.moveTo(x0, y0);
+ ctx.lineTo(x1, y1);
+ ctx.lineTo(x2, y2);
+ ctx.lineTo(x0, y0);
+ ctx.fill();
+ break;
+ case 2:
+ // unfilled head, just stroke.
+ ctx.stroke();
+ break;
+ case 3:
+ //filled head, add the bottom as a quadraticCurveTo curve and fill
+ var cpx = (x0 + x1 + x2) / 3;
+ var cpy = (y0 + y1 + y2) / 3;
+ ctx.quadraticCurveTo(cpx, cpy, x0, y0);
+ ctx.fill();
+ break;
+ case 4:
+ //filled head, add the bottom as a bezierCurveTo curve and fill
+ var cp1x, cp1y, cp2x, cp2y, backdist;
+ var shiftamt = 5;
+ if (x2 == x0) {
+ // Avoid a divide by zero if x2==x0
+ backdist = y2 - y0;
+ cp1x = (x1 + x0) / 2;
+ cp2x = (x1 + x0) / 2;
+ cp1y = y1 + backdist / shiftamt;
+ cp2y = y1 - backdist / shiftamt;
+ } else {
+ backdist = Math.sqrt(((x2 - x0) * (x2 - x0)) + ((y2 - y0) * (y2 - y0)));
+ var xback = (x0 + x2) / 2;
+ var yback = (y0 + y2) / 2;
+ var xmid = (xback + x1) / 2;
+ var ymid = (yback + y1) / 2;
+
+ var m = (y2 - y0) / (x2 - x0);
+ var dx = (backdist / (2 * Math.sqrt(m * m + 1))) / shiftamt;
+ var dy = m * dx;
+ cp1x = xmid - dx;
+ cp1y = ymid - dy;
+ cp2x = xmid + dx;
+ cp2y = ymid + dy;
+ }
+
+ ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x0, y0);
+ ctx.fill();
+ break;
+ }
+ ctx.restore();
+}
diff --git a/public/assets/javascripts/vendor/chardinjs.min.js b/public/assets/javascripts/vendor/chardinjs.min.js
new file mode 100755
index 0000000..56cd7b7
--- /dev/null
+++ b/public/assets/javascripts/vendor/chardinjs.min.js
@@ -0,0 +1,2 @@
+// Generated by CoffeeScript 1.6.2
+(function(){var e=[].slice;(function(t,n){var r;return r=function(){function e(e){var r=this;this.$el=t(e),t(n).resize(function(){return r.refresh()})}return e.prototype.start=function(){var e,t,n,r;if(this._overlay_visible())return!1;this._add_overlay_layer(),r=this.$el.find("*[data-intro]:visible");for(t=0,n=r.length;t<n;t++)e=r[t],this._show_element(e);return this.$el.trigger("chardinJs:start")},e.prototype.toggle=function(){return this._overlay_visible()?this.stop():this.start()},e.prototype.refresh=function(){var e,t,n,r,i;if(this._overlay_visible()){r=this.$el.find("*[data-intro]:visible"),i=[];for(t=0,n=r.length;t<n;t++)e=r[t],i.push(this._position_helper_layer(e));return i}return this},e.prototype.stop=function(){return this.$el.find(".chardinjs-overlay").fadeOut(function(){return t(this).remove()}),this.$el.find(".chardinjs-helper-layer").remove(),this.$el.find(".chardinjs-show-element").removeClass("chardinjs-show-element"),this.$el.find(".chardinjs-relative-position").removeClass("chardinjs-relative-position"),n.removeEventListener?n.removeEventListener("keydown",this._onKeyDown,!0):document.detachEvent&&document.detachEvent("onkeydown",this._onKeyDown),this.$el.trigger("chardinJs:stop")},e.prototype._overlay_visible=function(){return this.$el.find(".chardinjs-overlay").length!==0},e.prototype._add_overlay_layer=function(){var e,t,n,r=this;return this._overlay_visible()?!1:(t=document.createElement("div"),n="",t.className="chardinjs-overlay",this.$el.prop("tagName")==="BODY"?(n+="top: 0;bottom: 0; left: 0;right: 0;position: fixed;",t.setAttribute("style",n)):(e=this._get_offset(this.$el.get()[0]),e&&(n+="width: "+e.width+"px; height:"+e.height+"px; top:"+e.top+"px;left: "+e.left+"px;",t.setAttribute("style",n))),this.$el.get()[0].appendChild(t),t.onclick=function(){return r.stop()},setTimeout(function(){return n+="opacity: .8;opacity: .8;-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';filter: alpha(opacity=80);",t.setAttribute("style",n)},10))},e.prototype._get_position=function(e){return e.getAttribute("data-position")||"bottom"},e.prototype._place_tooltip=function(e){var n,r,i,s,o,u,a;u=t(e).data("tooltip_layer"),a=this._get_offset(u),u.style.top=null,u.style.right=null,u.style.bottom=null,u.style.left=null;switch(this._get_position(e)){case"top":case"bottom":i=this._get_offset(e),o=i.width,r=t(u).width(),u.style.left=""+(o/2-a.width/2)+"px";break;case"left":case"right":i=this._get_offset(e),s=i.height,n=t(u).height(),u.style.top=""+(s/2-a.height/2)+"px"}switch(this._get_position(e)){case"left":return u.style.left="-"+(a.width-34)+"px";case"right":return u.style.right="-"+(a.width-34)+"px";case"bottom":return u.style.bottom="-"+a.height+"px";case"top":return u.style.top="-"+a.height+"px"}},e.prototype._position_helper_layer=function(e){var n,r;return r=t(e).data("helper_layer"),n=this._get_offset(e),r.setAttribute("style","width: "+n.width+"px; height:"+n.height+"px; top:"+n.top+"px; left: "+n.left+"px;")},e.prototype._show_element=function(e){var n,r,i,s;r=this._get_offset(e),i=document.createElement("div"),s=document.createElement("div"),t(e).data("helper_layer",i).data("tooltip_layer",s),e.id&&i.setAttribute("data-id",e.id),i.className="chardinjs-helper-layer chardinjs-"+this._get_position(e),this._position_helper_layer(e),this.$el.get()[0].appendChild(i),s.className="chardinjs-tooltip chardinjs-"+this._get_position(e),s.innerHTML="<div class='chardinjs-tooltiptext'>"+e.getAttribute("data-intro")+"</div>",i.appendChild(s),this._place_tooltip(e),e.className+=" chardinjs-show-element",n="",e.currentStyle?n=e.currentStyle.position:document.defaultView&&document.defaultView.getComputedStyle&&(n=document.defaultView.getComputedStyle(e,null).getPropertyValue("position")),n=n.toLowerCase();if(n!=="absolute"&&n!=="relative")return e.className+=" chardinjs-relative-position"},e.prototype._get_offset=function(e){var t,n,r;t={width:e.offsetWidth,height:e.offsetHeight},n=0,r=0;while(e&&!isNaN(e.offsetLeft)&&!isNaN(e.offsetTop))n+=e.offsetLeft,r+=e.offsetTop,e=e.offsetParent;return t.top=r,t.left=n,t},e}(),t.fn.extend({chardinJs:function(){var n,i,s,o;return o=arguments[0],i=2<=arguments.length?e.call(arguments,1):[],n=t(this[0]),s=n.data("chardinJs"),s||n.data("chardinJs",s=new r(this,o)),typeof o=="string"&&s[o].apply(s,i),s}})})(window.jQuery,window)}).call(this); \ No newline at end of file
diff --git a/public/assets/javascripts/vendor/froogaloop.js b/public/assets/javascripts/vendor/froogaloop.js
new file mode 100644
index 0000000..c9330e6
--- /dev/null
+++ b/public/assets/javascripts/vendor/froogaloop.js
@@ -0,0 +1,287 @@
+// Init style shamelessly stolen from jQuery http://jquery.com
+var Froogaloop = (function(){
+ // Define a local copy of Froogaloop
+ function Froogaloop(iframe) {
+ // The Froogaloop object is actually just the init constructor
+ return new Froogaloop.fn.init(iframe);
+ }
+
+ var eventCallbacks = {},
+ hasWindowEvent = false,
+ isReady = false,
+ slice = Array.prototype.slice,
+ playerDomain = '';
+
+ Froogaloop.fn = Froogaloop.prototype = {
+ element: null,
+
+ init: function(iframe) {
+ if (typeof iframe === "string") {
+ iframe = document.getElementById(iframe);
+ }
+
+ this.element = iframe;
+
+ // Register message event listeners
+ playerDomain = getDomainFromUrl(this.element.getAttribute('src'));
+
+ return this;
+ },
+
+ /*
+ * Calls a function to act upon the player.
+ *
+ * @param {string} method The name of the Javascript API method to call. Eg: 'play'.
+ * @param {Array|Function} valueOrCallback params Array of parameters to pass when calling an API method
+ * or callback function when the method returns a value.
+ */
+ api: function(method, valueOrCallback) {
+ if (!this.element || !method) {
+ return false;
+ }
+
+ var self = this,
+ element = self.element,
+ target_id = element.id !== '' ? element.id : null,
+ params = !isFunction(valueOrCallback) ? valueOrCallback : null,
+ callback = isFunction(valueOrCallback) ? valueOrCallback : null;
+
+ // Store the callback for get functions
+ if (callback) {
+ storeCallback(method, callback, target_id);
+ }
+
+ postMessage(method, params, element);
+ return self;
+ },
+
+ /*
+ * Registers an event listener and a callback function that gets called when the event fires.
+ *
+ * @param eventName (String): Name of the event to listen for.
+ * @param callback (Function): Function that should be called when the event fires.
+ */
+ addEvent: function(eventName, callback) {
+ if (!this.element) {
+ return false;
+ }
+
+ var self = this,
+ element = self.element,
+ target_id = element.id !== '' ? element.id : null;
+
+ storeCallback(eventName, callback, target_id);
+
+ // The ready event is not registered via postMessage. It fires regardless.
+ if (eventName != 'ready') {
+ postMessage('addEventListener', eventName, element);
+ }
+ else if (eventName == 'ready' && isReady) {
+ callback.call(null, target_id);
+ }
+
+ return self;
+ },
+
+ /*
+ * Unregisters an event listener that gets called when the event fires.
+ *
+ * @param eventName (String): Name of the event to stop listening for.
+ */
+ removeEvent: function(eventName) {
+ if (!this.element) {
+ return false;
+ }
+
+ var self = this,
+ element = self.element,
+ target_id = element.id !== '' ? element.id : null,
+ removed = removeCallback(eventName, target_id);
+
+ // The ready event is not registered
+ if (eventName != 'ready' && removed) {
+ postMessage('removeEventListener', eventName, element);
+ }
+ }
+ };
+
+ /**
+ * Handles posting a message to the parent window.
+ *
+ * @param method (String): name of the method to call inside the player. For api calls
+ * this is the name of the api method (api_play or api_pause) while for events this method
+ * is api_addEventListener.
+ * @param params (Object or Array): List of parameters to submit to the method. Can be either
+ * a single param or an array list of parameters.
+ * @param target (HTMLElement): Target iframe to post the message to.
+ */
+ function postMessage(method, params, target) {
+ if (!target.contentWindow.postMessage) {
+ return false;
+ }
+
+ var url = target.getAttribute('src').split('?')[0],
+ data = JSON.stringify({
+ method: method,
+ value: params
+ });
+
+ if (url.substr(0, 2) === '//') {
+ url = window.location.protocol + url;
+ }
+
+ target.contentWindow.postMessage(data, url);
+ }
+
+ /**
+ * Event that fires whenever the window receives a message from its parent
+ * via window.postMessage.
+ */
+ function onMessageReceived(event) {
+ var data, method;
+
+ try {
+ data = JSON.parse(event.data);
+ method = data.event || data.method;
+ }
+ catch(e) {
+ //fail silently... like a ninja!
+ }
+
+ if (method == 'ready' && !isReady) {
+ isReady = true;
+ }
+
+ // Handles messages from moogaloop only
+ if (event.origin != playerDomain) {
+ return false;
+ }
+
+ var value = data.value,
+ eventData = data.data,
+ target_id = target_id === '' ? null : data.player_id,
+
+ callback = getCallback(method, target_id),
+ params = [];
+
+ if (!callback) {
+ return false;
+ }
+
+ if (value !== undefined) {
+ params.push(value);
+ }
+
+ if (eventData) {
+ params.push(eventData);
+ }
+
+ if (target_id) {
+ params.push(target_id);
+ }
+
+ return params.length > 0 ? callback.apply(null, params) : callback.call();
+ }
+
+
+ /**
+ * Stores submitted callbacks for each iframe being tracked and each
+ * event for that iframe.
+ *
+ * @param eventName (String): Name of the event. Eg. api_onPlay
+ * @param callback (Function): Function that should get executed when the
+ * event is fired.
+ * @param target_id (String) [Optional]: If handling more than one iframe then
+ * it stores the different callbacks for different iframes based on the iframe's
+ * id.
+ */
+ function storeCallback(eventName, callback, target_id) {
+ if (target_id) {
+ if (!eventCallbacks[target_id]) {
+ eventCallbacks[target_id] = {};
+ }
+ eventCallbacks[target_id][eventName] = callback;
+ }
+ else {
+ eventCallbacks[eventName] = callback;
+ }
+ }
+
+ /**
+ * Retrieves stored callbacks.
+ */
+ function getCallback(eventName, target_id) {
+ if (target_id) {
+ return eventCallbacks[target_id][eventName];
+ }
+ else {
+ return eventCallbacks[eventName];
+ }
+ }
+
+ function removeCallback(eventName, target_id) {
+ if (target_id && eventCallbacks[target_id]) {
+ if (!eventCallbacks[target_id][eventName]) {
+ return false;
+ }
+ eventCallbacks[target_id][eventName] = null;
+ }
+ else {
+ if (!eventCallbacks[eventName]) {
+ return false;
+ }
+ eventCallbacks[eventName] = null;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a domain's root domain.
+ * Eg. returns http://vimeo.com when http://vimeo.com/channels is sbumitted
+ *
+ * @param url (String): Url to test against.
+ * @return url (String): Root domain of submitted url
+ */
+ function getDomainFromUrl(url) {
+ if (url.substr(0, 2) === '//') {
+ url = window.location.protocol + url;
+ }
+
+ var url_pieces = url.split('/'),
+ domain_str = '';
+
+ for(var i = 0, length = url_pieces.length; i < length; i++) {
+ if(i<3) {domain_str += url_pieces[i];}
+ else {break;}
+ if(i<2) {domain_str += '/';}
+ }
+
+ return domain_str;
+ }
+
+ function isFunction(obj) {
+ return !!(obj && obj.constructor && obj.call && obj.apply);
+ }
+
+ function isArray(obj) {
+ return toString.call(obj) === '[object Array]';
+ }
+
+ // Give the init function the Froogaloop prototype for later instantiation
+ Froogaloop.fn.init.prototype = Froogaloop.fn;
+
+ // Listens for the message event.
+ // W3C
+ if (window.addEventListener) {
+ window.addEventListener('message', onMessageReceived, false);
+ }
+ // IE
+ else {
+ window.attachEvent('onmessage', onMessageReceived);
+ }
+
+ // Expose froogaloop to the global object
+ return (window.Froogaloop = window.$f = Froogaloop);
+
+})(); \ No newline at end of file
diff --git a/public/assets/javascripts/vendor/polyfill.js b/public/assets/javascripts/vendor/polyfill.js
index f97e438..2139618 100644
--- a/public/assets/javascripts/vendor/polyfill.js
+++ b/public/assets/javascripts/vendor/polyfill.js
@@ -48,10 +48,18 @@ function has3d(){
} else if ( browser.webkit ) {
browser.safari = true;
}
- $.browser = browser;
+ if (window.$) $.browser = browser;
return browser;
})( navigator.userAgent );
+// Naive useragent detection pattern
+var is_iphone = (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))
+var is_ipad = (navigator.userAgent.match(/iPad/i))
+var is_android = (navigator.userAgent.match(/Android/i))
+var is_mobile = is_iphone || is_ipad || is_android
+var is_desktop = ! is_mobile;
+var app_devicePixelRatio = is_mobile ? devicePixelRatio : 1;
+
// rAF shim
(function() {
diff --git a/public/assets/javascripts/vendor/wow.js b/public/assets/javascripts/vendor/wow.js
new file mode 100644
index 0000000..83ca71b
--- /dev/null
+++ b/public/assets/javascripts/vendor/wow.js
@@ -0,0 +1,452 @@
+(function() {
+ var MutationObserver, Util, WeakMap, getComputedStyle, getComputedStyleRX,
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+ Util = (function() {
+ function Util() {}
+
+ Util.prototype.extend = function(custom, defaults) {
+ var key, value;
+ for (key in defaults) {
+ value = defaults[key];
+ if (custom[key] == null) {
+ custom[key] = value;
+ }
+ }
+ return custom;
+ };
+
+ Util.prototype.isMobile = function(agent) {
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent);
+ };
+
+ Util.prototype.addEvent = function(elem, event, fn) {
+ if (elem.addEventListener != null) {
+ return elem.addEventListener(event, fn, false);
+ } else if (elem.attachEvent != null) {
+ return elem.attachEvent("on" + event, fn);
+ } else {
+ return elem[event] = fn;
+ }
+ };
+
+ Util.prototype.removeEvent = function(elem, event, fn) {
+ if (elem.removeEventListener != null) {
+ return elem.removeEventListener(event, fn, false);
+ } else if (elem.detachEvent != null) {
+ return elem.detachEvent("on" + event, fn);
+ } else {
+ return delete elem[event];
+ }
+ };
+
+ Util.prototype.innerHeight = function() {
+ if ('innerHeight' in window) {
+ return window.innerHeight;
+ } else {
+ return document.documentElement.clientHeight;
+ }
+ };
+
+ return Util;
+
+ })();
+
+ WeakMap = this.WeakMap || this.MozWeakMap || (WeakMap = (function() {
+ function WeakMap() {
+ this.keys = [];
+ this.values = [];
+ }
+
+ WeakMap.prototype.get = function(key) {
+ var i, item, _i, _len, _ref;
+ _ref = this.keys;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+ item = _ref[i];
+ if (item === key) {
+ return this.values[i];
+ }
+ }
+ };
+
+ WeakMap.prototype.set = function(key, value) {
+ var i, item, _i, _len, _ref;
+ _ref = this.keys;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+ item = _ref[i];
+ if (item === key) {
+ this.values[i] = value;
+ return;
+ }
+ }
+ this.keys.push(key);
+ return this.values.push(value);
+ };
+
+ return WeakMap;
+
+ })());
+
+ MutationObserver = this.MutationObserver || this.WebkitMutationObserver || this.MozMutationObserver || (MutationObserver = (function() {
+ function MutationObserver() {
+ if (typeof console !== "undefined" && console !== null) {
+ console.warn('MutationObserver is not supported by your browser.');
+ }
+ if (typeof console !== "undefined" && console !== null) {
+ console.warn('WOW.js cannot detect dom mutations, please call .sync() after loading new content.');
+ }
+ }
+
+ MutationObserver.notSupported = true;
+
+ MutationObserver.prototype.observe = function() {};
+
+ return MutationObserver;
+
+ })());
+
+ getComputedStyle = this.getComputedStyle || function(el, pseudo) {
+ this.getPropertyValue = function(prop) {
+ var _ref;
+ if (prop === 'float') {
+ prop = 'styleFloat';
+ }
+ if (getComputedStyleRX.test(prop)) {
+ prop.replace(getComputedStyleRX, function(_, char) {
+ return char.toUpperCase();
+ });
+ }
+ return ((_ref = el.currentStyle) != null ? _ref[prop] : void 0) || null;
+ };
+ return this;
+ };
+
+ getComputedStyleRX = /(\-([a-z]){1})/g;
+
+ this.WOW = (function() {
+ WOW.prototype.defaults = {
+ boxClass: 'wow',
+ animateClass: 'animated',
+ offset: 0,
+ mobile: true,
+ live: true
+ };
+
+ function WOW(options) {
+ if (options == null) {
+ options = {};
+ }
+ this.scrollCallback = __bind(this.scrollCallback, this);
+ this.scrollHandler = __bind(this.scrollHandler, this);
+ this.start = __bind(this.start, this);
+ this.scrolled = true;
+ this.config = this.util().extend(options, this.defaults);
+ this.animationNameCache = new WeakMap();
+ }
+
+ WOW.prototype.init = function() {
+ var _ref;
+ this.element = window.document.documentElement;
+ if ((_ref = document.readyState) === "interactive" || _ref === "complete") {
+ this.start();
+ } else {
+ this.util().addEvent(document, 'DOMContentLoaded', this.start);
+ }
+ return this.finished = [];
+ };
+
+ WOW.prototype.start = function() {
+ var box, _i, _len, _ref;
+ this.stopped = false;
+ this.boxes = (function() {
+ var _i, _len, _ref, _results;
+ _ref = this.element.querySelectorAll("." + this.config.boxClass);
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ box = _ref[_i];
+ _results.push(box);
+ }
+ return _results;
+ }).call(this);
+ this.all = (function() {
+ var _i, _len, _ref, _results;
+ _ref = this.boxes;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ box = _ref[_i];
+ _results.push(box);
+ }
+ return _results;
+ }).call(this);
+ if (this.boxes.length) {
+ if (this.disabled()) {
+ this.resetStyle();
+ } else {
+ _ref = this.boxes;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ box = _ref[_i];
+ this.applyStyle(box, true);
+ }
+ this.util().addEvent(window, 'scroll', this.scrollHandler);
+ this.util().addEvent(window, 'resize', this.scrollHandler);
+ this.interval = setInterval(this.scrollCallback, 50);
+ }
+ }
+ if (this.config.live) {
+ return new MutationObserver((function(_this) {
+ return function(records) {
+ var node, record, _j, _len1, _results;
+ _results = [];
+ for (_j = 0, _len1 = records.length; _j < _len1; _j++) {
+ record = records[_j];
+ _results.push((function() {
+ var _k, _len2, _ref1, _results1;
+ _ref1 = record.addedNodes || [];
+ _results1 = [];
+ for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
+ node = _ref1[_k];
+ _results1.push(this.doSync(node));
+ }
+ return _results1;
+ }).call(_this));
+ }
+ return _results;
+ };
+ })(this)).observe(document.body, {
+ childList: true,
+ subtree: true
+ });
+ }
+ };
+
+ WOW.prototype.stop = function() {
+ this.stopped = true;
+ this.util().removeEvent(window, 'scroll', this.scrollHandler);
+ this.util().removeEvent(window, 'resize', this.scrollHandler);
+ if (this.interval != null) {
+ return clearInterval(this.interval);
+ }
+ };
+
+ WOW.prototype.sync = function(element) {
+ if (MutationObserver.notSupported) {
+ return this.doSync(this.element);
+ }
+ };
+
+ WOW.prototype.doSync = function(element) {
+ var box, _i, _len, _ref, _results;
+ if (!this.stopped) {
+ if (element == null) {
+ element = this.element;
+ }
+ if (element.nodeType !== 1) {
+ return;
+ }
+ element = element.parentNode || element;
+ _ref = element.querySelectorAll("." + this.config.boxClass);
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ box = _ref[_i];
+ if (__indexOf.call(this.all, box) < 0) {
+ this.applyStyle(box, true);
+ this.boxes.push(box);
+ this.all.push(box);
+ _results.push(this.scrolled = true);
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ }
+ };
+
+ WOW.prototype.show = function(box) {
+ this.applyStyle(box);
+ return box.className = "" + box.className + " " + this.config.animateClass;
+ };
+
+ WOW.prototype.applyStyle = function(box, hidden) {
+ var delay, duration, iteration;
+ duration = box.getAttribute('data-wow-duration');
+ delay = box.getAttribute('data-wow-delay');
+ iteration = box.getAttribute('data-wow-iteration');
+ return this.animate((function(_this) {
+ return function() {
+ return _this.customStyle(box, hidden, duration, delay, iteration);
+ };
+ })(this));
+ };
+
+ WOW.prototype.animate = (function() {
+ if ('requestAnimationFrame' in window) {
+ return function(callback) {
+ return window.requestAnimationFrame(callback);
+ };
+ } else {
+ return function(callback) {
+ return callback();
+ };
+ }
+ })();
+
+ WOW.prototype.resetStyle = function() {
+ var box, _i, _len, _ref, _results;
+ _ref = this.boxes;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ box = _ref[_i];
+ _results.push(box.setAttribute('style', 'visibility: visible;'));
+ }
+ return _results;
+ };
+
+ WOW.prototype.customStyle = function(box, hidden, duration, delay, iteration) {
+ if (hidden) {
+ this.cacheAnimationName(box);
+ }
+ box.style.visibility = hidden ? 'hidden' : 'visible';
+ if (duration) {
+ this.vendorSet(box.style, {
+ animationDuration: duration
+ });
+ }
+ if (delay) {
+ this.vendorSet(box.style, {
+ animationDelay: delay
+ });
+ }
+ if (iteration) {
+ this.vendorSet(box.style, {
+ animationIterationCount: iteration
+ });
+ }
+ this.vendorSet(box.style, {
+ animationName: hidden ? 'none' : this.cachedAnimationName(box)
+ });
+ return box;
+ };
+
+ WOW.prototype.vendors = ["moz", "webkit"];
+
+ WOW.prototype.vendorSet = function(elem, properties) {
+ var name, value, vendor, _results;
+ _results = [];
+ for (name in properties) {
+ value = properties[name];
+ elem["" + name] = value;
+ _results.push((function() {
+ var _i, _len, _ref, _results1;
+ _ref = this.vendors;
+ _results1 = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ vendor = _ref[_i];
+ _results1.push(elem["" + vendor + (name.charAt(0).toUpperCase()) + (name.substr(1))] = value);
+ }
+ return _results1;
+ }).call(this));
+ }
+ return _results;
+ };
+
+ WOW.prototype.vendorCSS = function(elem, property) {
+ var result, style, vendor, _i, _len, _ref;
+ style = getComputedStyle(elem);
+ result = style.getPropertyCSSValue(property);
+ _ref = this.vendors;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ vendor = _ref[_i];
+ result = result || style.getPropertyCSSValue("-" + vendor + "-" + property);
+ }
+ return result;
+ };
+
+ WOW.prototype.animationName = function(box) {
+ var animationName;
+ try {
+ animationName = this.vendorCSS(box, 'animation-name').cssText;
+ } catch (_error) {
+ animationName = getComputedStyle(box).getPropertyValue('animation-name');
+ }
+ if (animationName === 'none') {
+ return '';
+ } else {
+ return animationName;
+ }
+ };
+
+ WOW.prototype.cacheAnimationName = function(box) {
+ return this.animationNameCache.set(box, this.animationName(box));
+ };
+
+ WOW.prototype.cachedAnimationName = function(box) {
+ return this.animationNameCache.get(box);
+ };
+
+ WOW.prototype.scrollHandler = function() {
+ return this.scrolled = true;
+ };
+
+ WOW.prototype.scrollCallback = function() {
+ var box;
+ if (this.scrolled) {
+ this.scrolled = false;
+ this.boxes = (function() {
+ var _i, _len, _ref, _results;
+ _ref = this.boxes;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ box = _ref[_i];
+ if (!(box)) {
+ continue;
+ }
+ if (this.isVisible(box)) {
+ this.show(box);
+ continue;
+ }
+ _results.push(box);
+ }
+ return _results;
+ }).call(this);
+ if (!(this.boxes.length || this.config.live)) {
+ return this.stop();
+ }
+ }
+ };
+
+ WOW.prototype.offsetTop = function(element) {
+ var top;
+ while (element.offsetTop === void 0) {
+ element = element.parentNode;
+ }
+ top = element.offsetTop;
+ while (element = element.offsetParent) {
+ top += element.offsetTop;
+ }
+ return top;
+ };
+
+ WOW.prototype.isVisible = function(box) {
+ var bottom, offset, top, viewBottom, viewTop;
+ offset = box.getAttribute('data-wow-offset') || this.config.offset;
+ viewTop = window.pageYOffset;
+ viewBottom = viewTop + Math.min(this.element.clientHeight, this.util().innerHeight()) - offset;
+ top = this.offsetTop(box);
+ bottom = top + box.clientHeight;
+ return top <= viewBottom && bottom >= viewTop;
+ };
+
+ WOW.prototype.util = function() {
+ return this._util != null ? this._util : this._util = new Util();
+ };
+
+ WOW.prototype.disabled = function() {
+ return !this.config.mobile && this.util().isMobile(navigator.userAgent);
+ };
+
+ return WOW;
+
+ })();
+
+}).call(this);
diff --git a/public/assets/stylesheets/animate.css b/public/assets/stylesheets/animate.css
new file mode 100644
index 0000000..f784ce8
--- /dev/null
+++ b/public/assets/stylesheets/animate.css
@@ -0,0 +1,3158 @@
+@charset "UTF-8";
+/*!
+Animate.css - http://daneden.me/animate
+Licensed under the MIT license - http://opensource.org/licenses/MIT
+
+Copyright (c) 2014 Daniel Eden
+*/
+
+.animated {
+ -webkit-animation-duration: 1s;
+ animation-duration: 1s;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+}
+
+.animated.infinite {
+ -webkit-animation-iteration-count: infinite;
+ animation-iteration-count: infinite;
+}
+
+.animated.hinge {
+ -webkit-animation-duration: 2s;
+ animation-duration: 2s;
+}
+
+@-webkit-keyframes bounce {
+ 0%, 20%, 53%, 80%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ -webkit-transform: translate3d(0,0,0);
+ transform: translate3d(0,0,0);
+ }
+
+ 40%, 43% {
+ -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
+ transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
+ -webkit-transform: translate3d(0, -30px, 0);
+ transform: translate3d(0, -30px, 0);
+ }
+
+ 70% {
+ -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
+ transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
+ -webkit-transform: translate3d(0, -15px, 0);
+ transform: translate3d(0, -15px, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(0,-4px,0);
+ transform: translate3d(0,-4px,0);
+ }
+}
+
+@keyframes bounce {
+ 0%, 20%, 53%, 80%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ -webkit-transform: translate3d(0,0,0);
+ transform: translate3d(0,0,0);
+ }
+
+ 40%, 43% {
+ -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
+ transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
+ -webkit-transform: translate3d(0, -30px, 0);
+ transform: translate3d(0, -30px, 0);
+ }
+
+ 70% {
+ -webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
+ transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
+ -webkit-transform: translate3d(0, -15px, 0);
+ transform: translate3d(0, -15px, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(0,-4px,0);
+ transform: translate3d(0,-4px,0);
+ }
+}
+
+.bounce {
+ -webkit-animation-name: bounce;
+ animation-name: bounce;
+ -webkit-transform-origin: center bottom;
+ -ms-transform-origin: center bottom;
+ transform-origin: center bottom;
+}
+
+@-webkit-keyframes flash {
+ 0%, 50%, 100% {
+ opacity: 1;
+ }
+
+ 25%, 75% {
+ opacity: 0;
+ }
+}
+
+@keyframes flash {
+ 0%, 50%, 100% {
+ opacity: 1;
+ }
+
+ 25%, 75% {
+ opacity: 0;
+ }
+}
+
+.flash {
+ -webkit-animation-name: flash;
+ animation-name: flash;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+@-webkit-keyframes pulse {
+ 0% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+
+ 50% {
+ -webkit-transform: scale3d(1.05, 1.05, 1.05);
+ transform: scale3d(1.05, 1.05, 1.05);
+ }
+
+ 100% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+}
+
+@keyframes pulse {
+ 0% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+
+ 50% {
+ -webkit-transform: scale3d(1.05, 1.05, 1.05);
+ transform: scale3d(1.05, 1.05, 1.05);
+ }
+
+ 100% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+}
+
+.pulse {
+ -webkit-animation-name: pulse;
+ animation-name: pulse;
+}
+
+@-webkit-keyframes rubberBand {
+ 0% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+
+ 30% {
+ -webkit-transform: scale3d(1.25, 0.75, 1);
+ transform: scale3d(1.25, 0.75, 1);
+ }
+
+ 40% {
+ -webkit-transform: scale3d(0.75, 1.25, 1);
+ transform: scale3d(0.75, 1.25, 1);
+ }
+
+ 50% {
+ -webkit-transform: scale3d(1.15, 0.85, 1);
+ transform: scale3d(1.15, 0.85, 1);
+ }
+
+ 65% {
+ -webkit-transform: scale3d(.95, 1.05, 1);
+ transform: scale3d(.95, 1.05, 1);
+ }
+
+ 75% {
+ -webkit-transform: scale3d(1.05, .95, 1);
+ transform: scale3d(1.05, .95, 1);
+ }
+
+ 100% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+}
+
+@keyframes rubberBand {
+ 0% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+
+ 30% {
+ -webkit-transform: scale3d(1.25, 0.75, 1);
+ transform: scale3d(1.25, 0.75, 1);
+ }
+
+ 40% {
+ -webkit-transform: scale3d(0.75, 1.25, 1);
+ transform: scale3d(0.75, 1.25, 1);
+ }
+
+ 50% {
+ -webkit-transform: scale3d(1.15, 0.85, 1);
+ transform: scale3d(1.15, 0.85, 1);
+ }
+
+ 65% {
+ -webkit-transform: scale3d(.95, 1.05, 1);
+ transform: scale3d(.95, 1.05, 1);
+ }
+
+ 75% {
+ -webkit-transform: scale3d(1.05, .95, 1);
+ transform: scale3d(1.05, .95, 1);
+ }
+
+ 100% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+}
+
+.rubberBand {
+ -webkit-animation-name: rubberBand;
+ animation-name: rubberBand;
+}
+
+@-webkit-keyframes shake {
+ 0%, 100% {
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+
+ 10%, 30%, 50%, 70%, 90% {
+ -webkit-transform: translate3d(-10px, 0, 0);
+ transform: translate3d(-10px, 0, 0);
+ }
+
+ 20%, 40%, 60%, 80% {
+ -webkit-transform: translate3d(10px, 0, 0);
+ transform: translate3d(10px, 0, 0);
+ }
+}
+
+@keyframes shake {
+ 0%, 100% {
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+
+ 10%, 30%, 50%, 70%, 90% {
+ -webkit-transform: translate3d(-10px, 0, 0);
+ transform: translate3d(-10px, 0, 0);
+ }
+
+ 20%, 40%, 60%, 80% {
+ -webkit-transform: translate3d(10px, 0, 0);
+ transform: translate3d(10px, 0, 0);
+ }
+}
+
+.shake {
+ -webkit-animation-name: shake;
+ animation-name: shake;
+}
+
+@-webkit-keyframes swing {
+ 20% {
+ -webkit-transform: rotate3d(0, 0, 1, 15deg);
+ transform: rotate3d(0, 0, 1, 15deg);
+ }
+
+ 40% {
+ -webkit-transform: rotate3d(0, 0, 1, -10deg);
+ transform: rotate3d(0, 0, 1, -10deg);
+ }
+
+ 60% {
+ -webkit-transform: rotate3d(0, 0, 1, 5deg);
+ transform: rotate3d(0, 0, 1, 5deg);
+ }
+
+ 80% {
+ -webkit-transform: rotate3d(0, 0, 1, -5deg);
+ transform: rotate3d(0, 0, 1, -5deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate3d(0, 0, 1, 0deg);
+ transform: rotate3d(0, 0, 1, 0deg);
+ }
+}
+
+@keyframes swing {
+ 20% {
+ -webkit-transform: rotate3d(0, 0, 1, 15deg);
+ transform: rotate3d(0, 0, 1, 15deg);
+ }
+
+ 40% {
+ -webkit-transform: rotate3d(0, 0, 1, -10deg);
+ transform: rotate3d(0, 0, 1, -10deg);
+ }
+
+ 60% {
+ -webkit-transform: rotate3d(0, 0, 1, 5deg);
+ transform: rotate3d(0, 0, 1, 5deg);
+ }
+
+ 80% {
+ -webkit-transform: rotate3d(0, 0, 1, -5deg);
+ transform: rotate3d(0, 0, 1, -5deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate3d(0, 0, 1, 0deg);
+ transform: rotate3d(0, 0, 1, 0deg);
+ }
+}
+
+.swing {
+ -webkit-transform-origin: top center;
+ -ms-transform-origin: top center;
+ transform-origin: top center;
+ -webkit-animation-name: swing;
+ animation-name: swing;
+}
+
+@-webkit-keyframes tada {
+ 0% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+
+ 10%, 20% {
+ -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
+ transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
+ }
+
+ 30%, 50%, 70%, 90% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
+ transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
+ }
+
+ 40%, 60%, 80% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
+ transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
+ }
+
+ 100% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+}
+
+@keyframes tada {
+ 0% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+
+ 10%, 20% {
+ -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
+ transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg);
+ }
+
+ 30%, 50%, 70%, 90% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
+ transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
+ }
+
+ 40%, 60%, 80% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
+ transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
+ }
+
+ 100% {
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+}
+
+.tada {
+ -webkit-animation-name: tada;
+ animation-name: tada;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+@-webkit-keyframes wobble {
+ 0% {
+ -webkit-transform: none;
+ transform: none;
+ }
+
+ 15% {
+ -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+ transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+ }
+
+ 30% {
+ -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+ transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+ }
+
+ 45% {
+ -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+ transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+ }
+
+ 60% {
+ -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+ transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+ transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes wobble {
+ 0% {
+ -webkit-transform: none;
+ transform: none;
+ }
+
+ 15% {
+ -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+ transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
+ }
+
+ 30% {
+ -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+ transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
+ }
+
+ 45% {
+ -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+ transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
+ }
+
+ 60% {
+ -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+ transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+ transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.wobble {
+ -webkit-animation-name: wobble;
+ animation-name: wobble;
+}
+
+@-webkit-keyframes bounceIn {
+ 0%, 20%, 40%, 60%, 80%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.3, .3, .3);
+ transform: scale3d(.3, .3, .3);
+ }
+
+ 20% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
+ transform: scale3d(1.1, 1.1, 1.1);
+ }
+
+ 40% {
+ -webkit-transform: scale3d(.9, .9, .9);
+ transform: scale3d(.9, .9, .9);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(1.03, 1.03, 1.03);
+ transform: scale3d(1.03, 1.03, 1.03);
+ }
+
+ 80% {
+ -webkit-transform: scale3d(.97, .97, .97);
+ transform: scale3d(.97, .97, .97);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+}
+
+@keyframes bounceIn {
+ 0%, 20%, 40%, 60%, 80%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.3, .3, .3);
+ transform: scale3d(.3, .3, .3);
+ }
+
+ 20% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
+ transform: scale3d(1.1, 1.1, 1.1);
+ }
+
+ 40% {
+ -webkit-transform: scale3d(.9, .9, .9);
+ transform: scale3d(.9, .9, .9);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(1.03, 1.03, 1.03);
+ transform: scale3d(1.03, 1.03, 1.03);
+ }
+
+ 80% {
+ -webkit-transform: scale3d(.97, .97, .97);
+ transform: scale3d(.97, .97, .97);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: scale3d(1, 1, 1);
+ transform: scale3d(1, 1, 1);
+ }
+}
+
+.bounceIn {
+ -webkit-animation-name: bounceIn;
+ animation-name: bounceIn;
+ -webkit-animation-duration: .75s;
+ animation-duration: .75s;
+}
+
+@-webkit-keyframes bounceInDown {
+ 0%, 60%, 75%, 90%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -3000px, 0);
+ transform: translate3d(0, -3000px, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 25px, 0);
+ transform: translate3d(0, 25px, 0);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(0, -10px, 0);
+ transform: translate3d(0, -10px, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(0, 5px, 0);
+ transform: translate3d(0, 5px, 0);
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes bounceInDown {
+ 0%, 60%, 75%, 90%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -3000px, 0);
+ transform: translate3d(0, -3000px, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 25px, 0);
+ transform: translate3d(0, 25px, 0);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(0, -10px, 0);
+ transform: translate3d(0, -10px, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(0, 5px, 0);
+ transform: translate3d(0, 5px, 0);
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.bounceInDown {
+ -webkit-animation-name: bounceInDown;
+ animation-name: bounceInDown;
+}
+
+@-webkit-keyframes bounceInLeft {
+ 0%, 60%, 75%, 90%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-3000px, 0, 0);
+ transform: translate3d(-3000px, 0, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(25px, 0, 0);
+ transform: translate3d(25px, 0, 0);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(-10px, 0, 0);
+ transform: translate3d(-10px, 0, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(5px, 0, 0);
+ transform: translate3d(5px, 0, 0);
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes bounceInLeft {
+ 0%, 60%, 75%, 90%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-3000px, 0, 0);
+ transform: translate3d(-3000px, 0, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(25px, 0, 0);
+ transform: translate3d(25px, 0, 0);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(-10px, 0, 0);
+ transform: translate3d(-10px, 0, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(5px, 0, 0);
+ transform: translate3d(5px, 0, 0);
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.bounceInLeft {
+ -webkit-animation-name: bounceInLeft;
+ animation-name: bounceInLeft;
+}
+
+@-webkit-keyframes bounceInRight {
+ 0%, 60%, 75%, 90%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(3000px, 0, 0);
+ transform: translate3d(3000px, 0, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(-25px, 0, 0);
+ transform: translate3d(-25px, 0, 0);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(10px, 0, 0);
+ transform: translate3d(10px, 0, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(-5px, 0, 0);
+ transform: translate3d(-5px, 0, 0);
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes bounceInRight {
+ 0%, 60%, 75%, 90%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(3000px, 0, 0);
+ transform: translate3d(3000px, 0, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(-25px, 0, 0);
+ transform: translate3d(-25px, 0, 0);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(10px, 0, 0);
+ transform: translate3d(10px, 0, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(-5px, 0, 0);
+ transform: translate3d(-5px, 0, 0);
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.bounceInRight {
+ -webkit-animation-name: bounceInRight;
+ animation-name: bounceInRight;
+}
+
+@-webkit-keyframes bounceInUp {
+ 0%, 60%, 75%, 90%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 3000px, 0);
+ transform: translate3d(0, 3000px, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, -20px, 0);
+ transform: translate3d(0, -20px, 0);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(0, 10px, 0);
+ transform: translate3d(0, 10px, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(0, -5px, 0);
+ transform: translate3d(0, -5px, 0);
+ }
+
+ 100% {
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+
+@keyframes bounceInUp {
+ 0%, 60%, 75%, 90%, 100% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
+ }
+
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 3000px, 0);
+ transform: translate3d(0, 3000px, 0);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, -20px, 0);
+ transform: translate3d(0, -20px, 0);
+ }
+
+ 75% {
+ -webkit-transform: translate3d(0, 10px, 0);
+ transform: translate3d(0, 10px, 0);
+ }
+
+ 90% {
+ -webkit-transform: translate3d(0, -5px, 0);
+ transform: translate3d(0, -5px, 0);
+ }
+
+ 100% {
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+
+.bounceInUp {
+ -webkit-animation-name: bounceInUp;
+ animation-name: bounceInUp;
+}
+
+@-webkit-keyframes bounceOut {
+ 20% {
+ -webkit-transform: scale3d(.9, .9, .9);
+ transform: scale3d(.9, .9, .9);
+ }
+
+ 50%, 55% {
+ opacity: 1;
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
+ transform: scale3d(1.1, 1.1, 1.1);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale3d(.3, .3, .3);
+ transform: scale3d(.3, .3, .3);
+ }
+}
+
+@keyframes bounceOut {
+ 20% {
+ -webkit-transform: scale3d(.9, .9, .9);
+ transform: scale3d(.9, .9, .9);
+ }
+
+ 50%, 55% {
+ opacity: 1;
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
+ transform: scale3d(1.1, 1.1, 1.1);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale3d(.3, .3, .3);
+ transform: scale3d(.3, .3, .3);
+ }
+}
+
+.bounceOut {
+ -webkit-animation-name: bounceOut;
+ animation-name: bounceOut;
+ -webkit-animation-duration: .75s;
+ animation-duration: .75s;
+}
+
+@-webkit-keyframes bounceOutDown {
+ 20% {
+ -webkit-transform: translate3d(0, 10px, 0);
+ transform: translate3d(0, 10px, 0);
+ }
+
+ 40%, 45% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, -20px, 0);
+ transform: translate3d(0, -20px, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+}
+
+@keyframes bounceOutDown {
+ 20% {
+ -webkit-transform: translate3d(0, 10px, 0);
+ transform: translate3d(0, 10px, 0);
+ }
+
+ 40%, 45% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, -20px, 0);
+ transform: translate3d(0, -20px, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+}
+
+.bounceOutDown {
+ -webkit-animation-name: bounceOutDown;
+ animation-name: bounceOutDown;
+}
+
+@-webkit-keyframes bounceOutLeft {
+ 20% {
+ opacity: 1;
+ -webkit-transform: translate3d(20px, 0, 0);
+ transform: translate3d(20px, 0, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+}
+
+@keyframes bounceOutLeft {
+ 20% {
+ opacity: 1;
+ -webkit-transform: translate3d(20px, 0, 0);
+ transform: translate3d(20px, 0, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+}
+
+.bounceOutLeft {
+ -webkit-animation-name: bounceOutLeft;
+ animation-name: bounceOutLeft;
+}
+
+@-webkit-keyframes bounceOutRight {
+ 20% {
+ opacity: 1;
+ -webkit-transform: translate3d(-20px, 0, 0);
+ transform: translate3d(-20px, 0, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+}
+
+@keyframes bounceOutRight {
+ 20% {
+ opacity: 1;
+ -webkit-transform: translate3d(-20px, 0, 0);
+ transform: translate3d(-20px, 0, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+}
+
+.bounceOutRight {
+ -webkit-animation-name: bounceOutRight;
+ animation-name: bounceOutRight;
+}
+
+@-webkit-keyframes bounceOutUp {
+ 20% {
+ -webkit-transform: translate3d(0, -10px, 0);
+ transform: translate3d(0, -10px, 0);
+ }
+
+ 40%, 45% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 20px, 0);
+ transform: translate3d(0, 20px, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+}
+
+@keyframes bounceOutUp {
+ 20% {
+ -webkit-transform: translate3d(0, -10px, 0);
+ transform: translate3d(0, -10px, 0);
+ }
+
+ 40%, 45% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 20px, 0);
+ transform: translate3d(0, 20px, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+}
+
+.bounceOutUp {
+ -webkit-animation-name: bounceOutUp;
+ animation-name: bounceOutUp;
+}
+
+@-webkit-keyframes fadeIn {
+ 0% {opacity: 0;}
+ 100% {opacity: 1;}
+}
+
+@keyframes fadeIn {
+ 0% {opacity: 0;}
+ 100% {opacity: 1;}
+}
+
+.fadeIn {
+ -webkit-animation-name: fadeIn;
+ animation-name: fadeIn;
+}
+
+@-webkit-keyframes fadeInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes fadeInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.fadeInDown {
+ -webkit-animation-name: fadeInDown;
+ animation-name: fadeInDown;
+}
+
+@-webkit-keyframes fadeInDownBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes fadeInDownBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.fadeInDownBig {
+ -webkit-animation-name: fadeInDownBig;
+ animation-name: fadeInDownBig;
+}
+
+@-webkit-keyframes fadeInLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes fadeInLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.fadeInLeft {
+ -webkit-animation-name: fadeInLeft;
+ animation-name: fadeInLeft;
+}
+
+@-webkit-keyframes fadeInLeftBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes fadeInLeftBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.fadeInLeftBig {
+ -webkit-animation-name: fadeInLeftBig;
+ animation-name: fadeInLeftBig;
+}
+
+@-webkit-keyframes fadeInRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes fadeInRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.fadeInRight {
+ -webkit-animation-name: fadeInRight;
+ animation-name: fadeInRight;
+}
+
+@-webkit-keyframes fadeInRightBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes fadeInRightBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.fadeInRightBig {
+ -webkit-animation-name: fadeInRightBig;
+ animation-name: fadeInRightBig;
+}
+
+@-webkit-keyframes fadeInUp {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes fadeInUp {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.fadeInUp {
+ -webkit-animation-name: fadeInUp;
+ animation-name: fadeInUp;
+}
+
+@-webkit-keyframes fadeInUpBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes fadeInUpBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.fadeInUpBig {
+ -webkit-animation-name: fadeInUpBig;
+ animation-name: fadeInUpBig;
+}
+
+@-webkit-keyframes fadeOut {
+ 0% {opacity: 1;}
+ 100% {opacity: 0;}
+}
+
+@keyframes fadeOut {
+ 0% {opacity: 1;}
+ 100% {opacity: 0;}
+}
+
+.fadeOut {
+ -webkit-animation-name: fadeOut;
+ animation-name: fadeOut;
+}
+
+@-webkit-keyframes fadeOutDown {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+}
+
+@keyframes fadeOutDown {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+}
+
+.fadeOutDown {
+ -webkit-animation-name: fadeOutDown;
+ animation-name: fadeOutDown;
+}
+
+@-webkit-keyframes fadeOutDownBig {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+}
+
+@keyframes fadeOutDownBig {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+}
+
+.fadeOutDownBig {
+ -webkit-animation-name: fadeOutDownBig;
+ animation-name: fadeOutDownBig;
+}
+
+@-webkit-keyframes fadeOutLeft {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+
+@keyframes fadeOutLeft {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+
+.fadeOutLeft {
+ -webkit-animation-name: fadeOutLeft;
+ animation-name: fadeOutLeft;
+}
+
+@-webkit-keyframes fadeOutLeftBig {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+}
+
+@keyframes fadeOutLeftBig {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+}
+
+.fadeOutLeftBig {
+ -webkit-animation-name: fadeOutLeftBig;
+ animation-name: fadeOutLeftBig;
+}
+
+@-webkit-keyframes fadeOutRight {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+}
+
+@keyframes fadeOutRight {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+}
+
+.fadeOutRight {
+ -webkit-animation-name: fadeOutRight;
+ animation-name: fadeOutRight;
+}
+
+@-webkit-keyframes fadeOutRightBig {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+}
+
+@keyframes fadeOutRightBig {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+}
+
+.fadeOutRightBig {
+ -webkit-animation-name: fadeOutRightBig;
+ animation-name: fadeOutRightBig;
+}
+
+@-webkit-keyframes fadeOutUp {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+}
+
+@keyframes fadeOutUp {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+}
+
+.fadeOutUp {
+ -webkit-animation-name: fadeOutUp;
+ animation-name: fadeOutUp;
+}
+
+@-webkit-keyframes fadeOutUpBig {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+}
+
+@keyframes fadeOutUpBig {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+}
+
+.fadeOutUpBig {
+ -webkit-animation-name: fadeOutUpBig;
+ animation-name: fadeOutUpBig;
+}
+
+@-webkit-keyframes flip {
+ 0% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 40% {
+ -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
+ transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 50% {
+ -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
+ transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 80% {
+ -webkit-transform: perspective(400px) scale3d(.95, .95, .95);
+ transform: perspective(400px) scale3d(.95, .95, .95);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+}
+
+@keyframes flip {
+ 0% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, -360deg);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 40% {
+ -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
+ transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+
+ 50% {
+ -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
+ transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 80% {
+ -webkit-transform: perspective(400px) scale3d(.95, .95, .95);
+ transform: perspective(400px) scale3d(.95, .95, .95);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+}
+
+.animated.flip {
+ -webkit-backface-visibility: visible;
+ backface-visibility: visible;
+ -webkit-animation-name: flip;
+ animation-name: flip;
+}
+
+@-webkit-keyframes flipInX {
+ 0% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+ -webkit-transition-timing-function: ease-in;
+ transition-timing-function: ease-in;
+ opacity: 0;
+ }
+
+ 40% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+ -webkit-transition-timing-function: ease-in;
+ transition-timing-function: ease-in;
+ }
+
+ 60% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+ opacity: 1;
+ }
+
+ 80% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+}
+
+@keyframes flipInX {
+ 0% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+ -webkit-transition-timing-function: ease-in;
+ transition-timing-function: ease-in;
+ opacity: 0;
+ }
+
+ 40% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+ -webkit-transition-timing-function: ease-in;
+ transition-timing-function: ease-in;
+ }
+
+ 60% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
+ opacity: 1;
+ }
+
+ 80% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+}
+
+.flipInX {
+ -webkit-backface-visibility: visible !important;
+ backface-visibility: visible !important;
+ -webkit-animation-name: flipInX;
+ animation-name: flipInX;
+}
+
+@-webkit-keyframes flipInY {
+ 0% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+ -webkit-transition-timing-function: ease-in;
+ transition-timing-function: ease-in;
+ opacity: 0;
+ }
+
+ 40% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
+ -webkit-transition-timing-function: ease-in;
+ transition-timing-function: ease-in;
+ }
+
+ 60% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
+ opacity: 1;
+ }
+
+ 80% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+}
+
+@keyframes flipInY {
+ 0% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+ -webkit-transition-timing-function: ease-in;
+ transition-timing-function: ease-in;
+ opacity: 0;
+ }
+
+ 40% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
+ -webkit-transition-timing-function: ease-in;
+ transition-timing-function: ease-in;
+ }
+
+ 60% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
+ opacity: 1;
+ }
+
+ 80% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+}
+
+.flipInY {
+ -webkit-backface-visibility: visible !important;
+ backface-visibility: visible !important;
+ -webkit-animation-name: flipInY;
+ animation-name: flipInY;
+}
+
+@-webkit-keyframes flipOutX {
+ 0% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+
+ 30% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+ opacity: 0;
+ }
+}
+
+@keyframes flipOutX {
+ 0% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+
+ 30% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+ transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
+ opacity: 0;
+ }
+}
+
+.flipOutX {
+ -webkit-animation-name: flipOutX;
+ animation-name: flipOutX;
+ -webkit-animation-duration: .75s;
+ animation-duration: .75s;
+ -webkit-backface-visibility: visible !important;
+ backface-visibility: visible !important;
+}
+
+@-webkit-keyframes flipOutY {
+ 0% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+
+ 30% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+ opacity: 0;
+ }
+}
+
+@keyframes flipOutY {
+ 0% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+
+ 30% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, -15deg);
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+ transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
+ opacity: 0;
+ }
+}
+
+.flipOutY {
+ -webkit-backface-visibility: visible !important;
+ backface-visibility: visible !important;
+ -webkit-animation-name: flipOutY;
+ animation-name: flipOutY;
+ -webkit-animation-duration: .75s;
+ animation-duration: .75s;
+}
+
+@-webkit-keyframes lightSpeedIn {
+ 0% {
+ -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
+ transform: translate3d(100%, 0, 0) skewX(-30deg);
+ opacity: 0;
+ }
+
+ 60% {
+ -webkit-transform: skewX(20deg);
+ transform: skewX(20deg);
+ opacity: 1;
+ }
+
+ 80% {
+ -webkit-transform: skewX(-5deg);
+ transform: skewX(-5deg);
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+@keyframes lightSpeedIn {
+ 0% {
+ -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
+ transform: translate3d(100%, 0, 0) skewX(-30deg);
+ opacity: 0;
+ }
+
+ 60% {
+ -webkit-transform: skewX(20deg);
+ transform: skewX(20deg);
+ opacity: 1;
+ }
+
+ 80% {
+ -webkit-transform: skewX(-5deg);
+ transform: skewX(-5deg);
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+.lightSpeedIn {
+ -webkit-animation-name: lightSpeedIn;
+ animation-name: lightSpeedIn;
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+}
+
+@-webkit-keyframes lightSpeedOut {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);
+ transform: translate3d(100%, 0, 0) skewX(30deg);
+ opacity: 0;
+ }
+}
+
+@keyframes lightSpeedOut {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);
+ transform: translate3d(100%, 0, 0) skewX(30deg);
+ opacity: 0;
+ }
+}
+
+.lightSpeedOut {
+ -webkit-animation-name: lightSpeedOut;
+ animation-name: lightSpeedOut;
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+}
+
+@-webkit-keyframes rotateIn {
+ 0% {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ -webkit-transform: rotate3d(0, 0, 1, -200deg);
+ transform: rotate3d(0, 0, 1, -200deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+@keyframes rotateIn {
+ 0% {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ -webkit-transform: rotate3d(0, 0, 1, -200deg);
+ transform: rotate3d(0, 0, 1, -200deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+.rotateIn {
+ -webkit-animation-name: rotateIn;
+ animation-name: rotateIn;
+}
+
+@-webkit-keyframes rotateInDownLeft {
+ 0% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
+ transform: rotate3d(0, 0, 1, -45deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+@keyframes rotateInDownLeft {
+ 0% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
+ transform: rotate3d(0, 0, 1, -45deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+.rotateInDownLeft {
+ -webkit-animation-name: rotateInDownLeft;
+ animation-name: rotateInDownLeft;
+}
+
+@-webkit-keyframes rotateInDownRight {
+ 0% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
+ transform: rotate3d(0, 0, 1, 45deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+@keyframes rotateInDownRight {
+ 0% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
+ transform: rotate3d(0, 0, 1, 45deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+.rotateInDownRight {
+ -webkit-animation-name: rotateInDownRight;
+ animation-name: rotateInDownRight;
+}
+
+@-webkit-keyframes rotateInUpLeft {
+ 0% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
+ transform: rotate3d(0, 0, 1, 45deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+@keyframes rotateInUpLeft {
+ 0% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
+ transform: rotate3d(0, 0, 1, 45deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+.rotateInUpLeft {
+ -webkit-animation-name: rotateInUpLeft;
+ animation-name: rotateInUpLeft;
+}
+
+@-webkit-keyframes rotateInUpRight {
+ 0% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: rotate3d(0, 0, 1, -90deg);
+ transform: rotate3d(0, 0, 1, -90deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+@keyframes rotateInUpRight {
+ 0% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: rotate3d(0, 0, 1, -90deg);
+ transform: rotate3d(0, 0, 1, -90deg);
+ opacity: 0;
+ }
+
+ 100% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: none;
+ transform: none;
+ opacity: 1;
+ }
+}
+
+.rotateInUpRight {
+ -webkit-animation-name: rotateInUpRight;
+ animation-name: rotateInUpRight;
+}
+
+@-webkit-keyframes rotateOut {
+ 0% {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ -webkit-transform: rotate3d(0, 0, 1, 200deg);
+ transform: rotate3d(0, 0, 1, 200deg);
+ opacity: 0;
+ }
+}
+
+@keyframes rotateOut {
+ 0% {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ -webkit-transform: rotate3d(0, 0, 1, 200deg);
+ transform: rotate3d(0, 0, 1, 200deg);
+ opacity: 0;
+ }
+}
+
+.rotateOut {
+ -webkit-animation-name: rotateOut;
+ animation-name: rotateOut;
+}
+
+@-webkit-keyframes rotateOutDownLeft {
+ 0% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
+ transform: rotate3d(0, 0, 1, 45deg);
+ opacity: 0;
+ }
+}
+
+@keyframes rotateOutDownLeft {
+ 0% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: rotate3d(0, 0, 1, 45deg);
+ transform: rotate3d(0, 0, 1, 45deg);
+ opacity: 0;
+ }
+}
+
+.rotateOutDownLeft {
+ -webkit-animation-name: rotateOutDownLeft;
+ animation-name: rotateOutDownLeft;
+}
+
+@-webkit-keyframes rotateOutDownRight {
+ 0% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
+ transform: rotate3d(0, 0, 1, -45deg);
+ opacity: 0;
+ }
+}
+
+@keyframes rotateOutDownRight {
+ 0% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
+ transform: rotate3d(0, 0, 1, -45deg);
+ opacity: 0;
+ }
+}
+
+.rotateOutDownRight {
+ -webkit-animation-name: rotateOutDownRight;
+ animation-name: rotateOutDownRight;
+}
+
+@-webkit-keyframes rotateOutUpLeft {
+ 0% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
+ transform: rotate3d(0, 0, 1, -45deg);
+ opacity: 0;
+ }
+}
+
+@keyframes rotateOutUpLeft {
+ 0% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+ -webkit-transform: rotate3d(0, 0, 1, -45deg);
+ transform: rotate3d(0, 0, 1, -45deg);
+ opacity: 0;
+ }
+}
+
+.rotateOutUpLeft {
+ -webkit-animation-name: rotateOutUpLeft;
+ animation-name: rotateOutUpLeft;
+}
+
+@-webkit-keyframes rotateOutUpRight {
+ 0% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: rotate3d(0, 0, 1, 90deg);
+ transform: rotate3d(0, 0, 1, 90deg);
+ opacity: 0;
+ }
+}
+
+@keyframes rotateOutUpRight {
+ 0% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+ -webkit-transform: rotate3d(0, 0, 1, 90deg);
+ transform: rotate3d(0, 0, 1, 90deg);
+ opacity: 0;
+ }
+}
+
+.rotateOutUpRight {
+ -webkit-animation-name: rotateOutUpRight;
+ animation-name: rotateOutUpRight;
+}
+
+@-webkit-keyframes hinge {
+ 0% {
+ -webkit-transform-origin: top left;
+ transform-origin: top left;
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+
+ 20%, 60% {
+ -webkit-transform: rotate3d(0, 0, 1, 80deg);
+ transform: rotate3d(0, 0, 1, 80deg);
+ -webkit-transform-origin: top left;
+ transform-origin: top left;
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+
+ 40%, 80% {
+ -webkit-transform: rotate3d(0, 0, 1, 60deg);
+ transform: rotate3d(0, 0, 1, 60deg);
+ -webkit-transform-origin: top left;
+ transform-origin: top left;
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: translate3d(0, 700px, 0);
+ transform: translate3d(0, 700px, 0);
+ opacity: 0;
+ }
+}
+
+@keyframes hinge {
+ 0% {
+ -webkit-transform-origin: top left;
+ transform-origin: top left;
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+
+ 20%, 60% {
+ -webkit-transform: rotate3d(0, 0, 1, 80deg);
+ transform: rotate3d(0, 0, 1, 80deg);
+ -webkit-transform-origin: top left;
+ transform-origin: top left;
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+
+ 40%, 80% {
+ -webkit-transform: rotate3d(0, 0, 1, 60deg);
+ transform: rotate3d(0, 0, 1, 60deg);
+ -webkit-transform-origin: top left;
+ transform-origin: top left;
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ opacity: 1;
+ }
+
+ 100% {
+ -webkit-transform: translate3d(0, 700px, 0);
+ transform: translate3d(0, 700px, 0);
+ opacity: 0;
+ }
+}
+
+.hinge {
+ -webkit-animation-name: hinge;
+ animation-name: hinge;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+@-webkit-keyframes rollIn {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
+ transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes rollIn {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
+ transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
+ }
+
+ 100% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.rollIn {
+ -webkit-animation-name: rollIn;
+ animation-name: rollIn;
+}
+
+/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */
+
+@-webkit-keyframes rollOut {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
+ transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
+ }
+}
+
+@keyframes rollOut {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
+ transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
+ }
+}
+
+.rollOut {
+ -webkit-animation-name: rollOut;
+ animation-name: rollOut;
+}
+
+@-webkit-keyframes zoomIn {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.3, .3, .3);
+ transform: scale3d(.3, .3, .3);
+ }
+
+ 50% {
+ opacity: 1;
+ }
+}
+
+@keyframes zoomIn {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.3, .3, .3);
+ transform: scale3d(.3, .3, .3);
+ }
+
+ 50% {
+ opacity: 1;
+ }
+}
+
+.zoomIn {
+ -webkit-animation-name: zoomIn;
+ animation-name: zoomIn;
+}
+
+@-webkit-keyframes zoomInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
+ transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
+ transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+@keyframes zoomInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
+ transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
+ transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+.zoomInDown {
+ -webkit-animation-name: zoomInDown;
+ animation-name: zoomInDown;
+}
+
+@-webkit-keyframes zoomInLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);
+ transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);
+ transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+@keyframes zoomInLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);
+ transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);
+ transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+.zoomInLeft {
+ -webkit-animation-name: zoomInLeft;
+ animation-name: zoomInLeft;
+}
+
+@-webkit-keyframes zoomInRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);
+ transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);
+ transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+@keyframes zoomInRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);
+ transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);
+ transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+.zoomInRight {
+ -webkit-animation-name: zoomInRight;
+ animation-name: zoomInRight;
+}
+
+@-webkit-keyframes zoomInUp {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);
+ transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
+ transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+@keyframes zoomInUp {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);
+ transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
+ transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+.zoomInUp {
+ -webkit-animation-name: zoomInUp;
+ animation-name: zoomInUp;
+}
+
+@-webkit-keyframes zoomOut {
+ 0% {
+ opacity: 1;
+ }
+
+ 50% {
+ opacity: 0;
+ -webkit-transform: scale3d(.3, .3, .3);
+ transform: scale3d(.3, .3, .3);
+ }
+
+ 100% {
+ opacity: 0;
+ }
+}
+
+@keyframes zoomOut {
+ 0% {
+ opacity: 1;
+ }
+
+ 50% {
+ opacity: 0;
+ -webkit-transform: scale3d(.3, .3, .3);
+ transform: scale3d(.3, .3, .3);
+ }
+
+ 100% {
+ opacity: 0;
+ }
+}
+
+.zoomOut {
+ -webkit-animation-name: zoomOut;
+ animation-name: zoomOut;
+}
+
+@-webkit-keyframes zoomOutDown {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
+ transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);
+ transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+@keyframes zoomOutDown {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
+ transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);
+ transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0);
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+.zoomOutDown {
+ -webkit-animation-name: zoomOutDown;
+ animation-name: zoomOutDown;
+}
+
+@-webkit-keyframes zoomOutLeft {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
+ transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale(.1) translate3d(-2000px, 0, 0);
+ transform: scale(.1) translate3d(-2000px, 0, 0);
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+ }
+}
+
+@keyframes zoomOutLeft {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
+ transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale(.1) translate3d(-2000px, 0, 0);
+ transform: scale(.1) translate3d(-2000px, 0, 0);
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+ }
+}
+
+.zoomOutLeft {
+ -webkit-animation-name: zoomOutLeft;
+ animation-name: zoomOutLeft;
+}
+
+@-webkit-keyframes zoomOutRight {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);
+ transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale(.1) translate3d(2000px, 0, 0);
+ transform: scale(.1) translate3d(2000px, 0, 0);
+ -webkit-transform-origin: right center;
+ transform-origin: right center;
+ }
+}
+
+@keyframes zoomOutRight {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);
+ transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale(.1) translate3d(2000px, 0, 0);
+ transform: scale(.1) translate3d(2000px, 0, 0);
+ -webkit-transform-origin: right center;
+ transform-origin: right center;
+ }
+}
+
+.zoomOutRight {
+ -webkit-animation-name: zoomOutRight;
+ animation-name: zoomOutRight;
+}
+
+@-webkit-keyframes zoomOutUp {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
+ transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);
+ transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+@keyframes zoomOutUp {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
+ transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190);
+ }
+
+ 100% {
+ opacity: 0;
+ -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);
+ transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0);
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1);
+ }
+}
+
+.zoomOutUp {
+ -webkit-animation-name: zoomOutUp;
+ animation-name: zoomOutUp;
+}
+
+@-webkit-keyframes slideInDown {
+ 0% {
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ visibility: visible;
+ }
+
+ 100% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+@keyframes slideInDown {
+ 0% {
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ visibility: visible;
+ }
+
+ 100% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+.slideInDown {
+ -webkit-animation-name: slideInDown;
+ animation-name: slideInDown;
+}
+
+@-webkit-keyframes slideInLeft {
+ 0% {
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ visibility: visible;
+ }
+
+ 100% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+}
+
+@keyframes slideInLeft {
+ 0% {
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ visibility: visible;
+ }
+
+ 100% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+}
+
+.slideInLeft {
+ -webkit-animation-name: slideInLeft;
+ animation-name: slideInLeft;
+}
+
+@-webkit-keyframes slideInRight {
+ 0% {
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ visibility: visible;
+ }
+
+ 100% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+}
+
+@keyframes slideInRight {
+ 0% {
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ visibility: visible;
+ }
+
+ 100% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+}
+
+.slideInRight {
+ -webkit-animation-name: slideInRight;
+ animation-name: slideInRight;
+}
+
+@-webkit-keyframes slideInUp {
+ 0% {
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ visibility: visible;
+ }
+
+ 100% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+@keyframes slideInUp {
+ 0% {
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ visibility: visible;
+ }
+
+ 100% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+.slideInUp {
+ -webkit-animation-name: slideInUp;
+ animation-name: slideInUp;
+}
+
+@-webkit-keyframes slideOutDown {
+ 0% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ 100% {
+ visibility: hidden;
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
+
+@keyframes slideOutDown {
+ 0% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ 100% {
+ visibility: hidden;
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
+
+.slideOutDown {
+ -webkit-animation-name: slideOutDown;
+ animation-name: slideOutDown;
+}
+
+@-webkit-keyframes slideOutLeft {
+ 0% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+
+ 100% {
+ visibility: hidden;
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+}
+
+@keyframes slideOutLeft {
+ 0% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+
+ 100% {
+ visibility: hidden;
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+}
+
+.slideOutLeft {
+ -webkit-animation-name: slideOutLeft;
+ animation-name: slideOutLeft;
+}
+
+@-webkit-keyframes slideOutRight {
+ 0% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+
+ 100% {
+ visibility: hidden;
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+}
+
+@keyframes slideOutRight {
+ 0% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+
+ 100% {
+ visibility: hidden;
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+}
+
+.slideOutRight {
+ -webkit-animation-name: slideOutRight;
+ animation-name: slideOutRight;
+}
+
+@-webkit-keyframes slideOutUp {
+ 0% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ 100% {
+ visibility: hidden;
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+}
+
+@keyframes slideOutUp {
+ 0% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ 100% {
+ visibility: hidden;
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+}
+
+.slideOutUp {
+ -webkit-animation-name: slideOutUp;
+ animation-name: slideOutUp;
+}
diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css
index ebc21a8..7dda058 100755
--- a/public/assets/stylesheets/app.css
+++ b/public/assets/stylesheets/app.css
@@ -1,15 +1,23 @@
-@import url(http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic);
*{
margin:0;
padding:0;
outline:0;
- font-family: 'Lato', sans-serif;
-webkit-font-smoothing: subpixel-antialiased;
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none;
}
+body,textarea,input {
+ font-family: 'Lato', sans-serif;
+}
+input:-webkit-autofill {
+ -webkit-box-shadow: 0 0 0px 1000px white inset;
+}
+.mobile input {
+ -webkit-appearance: none;
+ border-radius:0;
+}
+
+
+
*, *:before, *:after {
moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
@@ -17,13 +25,39 @@ body{
overflow-x:hidden;
}
+body.editing{
+ overflow:hidden;
+}
+
+::-moz-selection {
+ color: white;
+ background: black;
+}
+
+::selection {
+ color: white;
+ background: black;
+}
+
+body.editing *{
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+
+body.editing input {
+ -webkit-user-select: auto;
+}
+
body.noOverflow{
overflow:hidden;
}
-body.loading * {
- -webkit-transition: all 0 ease 0 !important;
- transition: all 0 ease 0 !important;
+body.loading *,
+body.loading .animate {
+ opacity: 0.2;
+ -webkit-transition: none !important;
+ transition: none !important;
}
html, body {
@@ -40,8 +74,130 @@ body.pastePaper .wallpaper.active span:hover{
cursor:url(../img/paintbucket.png), auto;
}
-a{
+a {
color:black;
+ text-decoration: none;
+}
+
+#header {
+ position: fixed;
+ width: 100%;
+ top: 0;
+ left: 0;
+ z-index: 6;
+}
+.desktop #header.black .logo:hover {
+ background: white;
+}
+.desktop #header.black .logo:hover path {
+ fill: black;
+}
+#header.black path {
+ fill: white;
+}
+#header.black .topLinks a {
+ color: white;
+}
+.desktop #header.black .topLinks a:hover {
+ color: black;
+ background-color: white;
+}
+.desktop #header.black a#help-button:hover {
+ background-color: transparent;
+ text-shadow: 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff;
+}
+
+.videoModal {
+ position: relative;
+ width: 0;
+ height: 0;
+ background: rgba(255,255,255,0);
+ display: table;
+ opacity:0;
+ z-index: -1;
+ top:-100%;
+ left:-100%;
+ overflow:hidden;
+ -webkit-transition:0.4s background;
+ -moz-transition:0.4s background;
+ transition:0.4s background;
+ display:none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -o-user-select: none;
+ user-select: none;
+}
+
+.videoModal.active {
+ position: fixed;
+ display:table;
+ opacity:1;
+ z-index: 6;
+ width: 100%;
+ height: 100%;
+ top:0;
+ left:0;
+ background: rgba(255,255,255,0.9);
+}
+
+.videoModal .ion-ios-close-empty {
+ position: absolute;
+ right: 50px;
+ top: 10px;
+ font-size: 80px;
+ cursor:pointer;
+ color:#444;
+}
+
+.desktop .videoModal .ion-ios-close-empty:hover {
+ color:black;
+}
+
+#help-button {
+ display: none;
+ border-right:0px!important;
+}
+.profileLink {
+ border-right:0px!important;
+}
+.editing #help-button {
+ display: inline;
+}
+.topLinks a.ion-help-circled {
+ font-size: 24px;
+ padding: 18px 27px 0 8px;
+}
+@-moz-keyframes redpulse {
+ 50%{
+ color:#f24444;
+ }
+}
+@keyframes redpulse {
+ 50%{
+ color:#f24444;
+ }
+}
+@-webkit-keyframes redpulse {
+ 50%{
+ color:#f24444;
+ }
+}
+
+.topLinks a.ion-help-circled.active {
+ -webkit-animation:1s redpulse infinite linear;
+ -moz-animation:1s redpulse infinite linear;
+ animation:1s redpulse infinite linear;
+}
+.topLinks a.ion-help-circled.active,
+.desktop .topLinks a.ion-help-circled:hover {
+ background:transparent;
+ color:red;
+}
+
+.page #header {
+ background: white;
+ border-bottom: 1px solid;
}
/*page*/
@@ -57,9 +213,6 @@ a{
cursor: -moz-grabbing;
}
-.floatimgImg.edit {
-
-}
.floatingSwatch {
width: 50px;
@@ -70,10 +223,12 @@ a{
display: none;
z-index: 10;
pointer-events: none;
+ background-size: cover;
}
.floatingSwatch.scissors {
background-image: url(/assets/img/scissors.png) !important;
background-repeat: no-repeat;
+ background-size: auto;
border: 0;
box-shadow: 0 0 transparent;
}
@@ -162,18 +317,112 @@ h5 {
.page {
text-align:center;
+ background:#f9f9f9;
}
.page.profile {
color:white;
}
-
+.profilepage {
+ margin-top:63px;
+}
.page .profilepage,
.page .projectList {
- width: 100%;
- margin: 40px 0 0 0;
- border-spacing: 0;
- clear: both;
+ width: 100%;
+ clear: both;
+ float:left;
+ display: inline-block;
+}
+
+.projectList {
+ border-top: 1px solid;
+}
+
+
+.projectList.about {
+ text-align: left;
+ border-top: 1px solid;
+ padding:10% 0;
+ margin-bottom:20px;
+}
+
+.projectList.about .item{
+ float: left;
+ width: 100%;
+ clear: both;
+}
+
+.projectList.about .item .rap {
+ max-width: 1500px;
+ margin: 0 auto;
+ padding: 0 10%;
+}
+
+.projectList.about .item span{
+ display: inline-block;
+ float: left;
+}
+
+.projectList.about .item span words {
+ max-width: 90%;
+ display: inline-block;
+ line-height: 28px;
+ font-size: 17px;
+ font-weight: 300;
+}
+
+.projectList.about.howto .item span words {
+ line-height: 43px;
+ font-size: 24px;
+}
+
+.projectList.about .item span:nth-child(1){
+ width: 300px;
+ height: 300px;
+ display: inline-block;
+ float: left;
+ border-radius: 300px;
+ background-size:cover;
+ background-position:center;
+}
+
+.projectList.about.howto .item span:nth-child(1){
+ width: 300px;
+ height: 300px;
+ display: inline-block;
+ float: left;
+ border-radius: 0;
+ background-size:cover;
+ background-position:center;
+ border: 1px solid;
+ box-shadow: 2px 2px black;
+}
+
+.projectList.about .item span h3{
+ font-weight: 500;
+ font-size: 25px;
+ margin-bottom: 8px;
+}
+
+.projectList.about .item span:nth-child(2){
+ width: calc(100% - 300px);
+ padding: 70px 50px;
+}
+
+
+.projectList.about .item:nth-child(2n+2) span:nth-child(2) {
+ padding: 70px 0 70px 100px;
+}
+.projectList.about .item:nth-child(2n+2) {
+ padding: 5% 0;
+}
+
+.projectList.about .item:nth-child(2n+2) span:nth-child(1){
+ float: right;
+}
+
+.projectList.about.makeAccountSingleton a {
+ margin: 0 20%;
}
.page .showcase {
@@ -190,37 +439,105 @@ iframe.embed {
z-index: -1;
pointer-events: none;
}
-.projectList {
+
+
+.projectList .projectItem {
+ margin: 4%;
+ width: 22vw;
display: inline-block;
- float: left;
- width: 100%;
}
.projectList .room {
- width: 33.3333%;
- height:40vh;
- display:table;
+ width: 100%;
+ height: 16vw;
+ margin: 1vw 1vw 10px 1vw;
+ display: table;
position: relative;
- float:left;
- border-top:1px solid black;
+ z-index: 1;
}
-.projectList .room:nth-child(4n+1){
- width:100%;
+.projectList .holder {
+ position: absolute;
+ top: 50%;
+ z-index: 2;
}
+
+.room .mask {
+ position: absolute;
+ top: 0; left: 0;
+ z-index: 1;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ overflow: hidden;
+ background-color: rgba(128,128,128,0.1);
+ background-size: contain;
+ background-position: center;
+}
+.desktop .projectList a:hover .room .mask {
+ background-color: rgba(128,128,128,0.1);
+}
+.room .images {
+ position: absolute;
+ top: 0; left: 0;
+ z-index: -1;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ overflow: hidden;
+}
+.room .images div {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center center;
+}
+
+/*
+.room .images[data-mediacount='1'] img:nth-child(1) { left: 20%; top: 20%; }
+
+.room .images[data-mediacount='2'] img:nth-child(1) { left: 51%; bottom: 0%; width: auto; height: 40%; }
+.room .images[data-mediacount='2'] img:nth-child(2) { right: 51%; bottom: 50%; width: auto; height: 40%; }
+
+.room .images[data-mediacount='3'] img:nth-child(1) { right: 51%; bottom: 41%; }
+.room .images[data-mediacount='3'] img:nth-child(2) { right: 51%; top: 61%; }
+.room .images[data-mediacount='3'] img:nth-child(3) { left: 51%; bottom: 0%; width:auto; height:30%;}
+
+.room .images[data-mediacount='4'] img:nth-child(1) { right: 51%; bottom: 41%; }
+.room .images[data-mediacount='4'] img:nth-child(2) { left: 51%; bottom: 61%; }
+.room .images[data-mediacount='4'] img:nth-child(3) { right: 51%; top: 61%; }
+.room .images[data-mediacount='4'] img:nth-child(4) { left: 51%; top: 41%; }
+*/
+
.page .btn {
clear: both;
padding: 30px 0;
border: 0;
-
}
.page .viewMore {
- text-decoration: none;
- font-size: 22px;
- display: block;
+ clear: both;
+ float: none;
+ text-decoration: none;
+ font-size: 22px;
+ display: block;
border-top: 1px solid black;
- border-bottom: 1px solid black;
}
+.mediaDrawer .viewMore {
+ clear: both;
+ float: none;
+ text-decoration: none;
+ font-size: 22px;
+ display: block;
+ text-align: center;
+ padding: 40px;
+ border: 0;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+ margin-top: 150px;
+}
.holder {
display: table-cell;
@@ -229,80 +546,29 @@ iframe.embed {
vertical-align: middle;
}
-.page .roomName {
- font-weight: 300;
- font-size: 20px;
- letter-spacing: 1px;
- color: black;
- background: white;
- border: 1px solid;
- padding: 5px;
- box-shadow: -3px 3px black;
- text-decoration:none;
- max-width: 180px;
- display: inline-block;
+.page .projectList label {
+ font-weight: 500;
+ font-size: 11px;
+ color: black;
+ text-decoration: none;
+ display: inline-block;
+ cursor: pointer;
+ border: 1px solid #000;
+ line-height: 18px;
+ padding: 5px;
+ letter-spacing: 0.3px;
}
-.page .roomName:hover {
+.desktop .page .room .holder a:hover {
background:black;
color:white;
}
-.projectList .editBtn {
- position: absolute;
- right: 10px;
- top: 10px;
-}
-
-/*
-.room1 {
- position: relative;
- overflow: hidden;
- background-image:url(https://s3.amazonaws.com/luckyplop/7eb159e99924e6e371046d6fa12e566fd77901c9.jpg);
-}
-.room2 {
- background-image:url(https://s3.amazonaws.com/luckyplop/fd4ebe8a7a4246c8273fc999fb1ef0d6a8260b8c.png);
-}
-
-.room1 form textarea {
- width: 226px;
-}
-
-.room1 .radio-group {
- width: 226px;
-}
-
-.room1 .radio-group__label {
- width: 106px;
- font-size: 13px;
-}
-
-.room1 .formHolder {
- top: 0;
- padding-top: 10px;
- display: table;
- width: 100%;
- height: 100%;
- background: rgba(255,255,255,0.9);
- -webkit-transform:translateY(-100%);
- transform:translateY(-100%);
-}
-
-.room1 form {
- padding: 0 10px;
- max-width: 440px;
-}
-
-.room1 .formInner {
- display: table-cell;
- vertical-align: middle;
+.desktop .projectList a:hover label {
+ background:black;
+ color:white;
}
-.room1.editing .formHolder {
- -webkit-transform:translateY(0);
- transform:translateY(0);
-}
-*/
.page .questions {
background: #55efcb;
@@ -334,25 +600,46 @@ iframe.embed {
}
.page h1 {
- font-size: 80px;
- font-weight: 100;
- padding-top: 25px;
+ font-size: 80px;
+ font-weight: 100;
+ padding: 20px 0 25px 0;
float: left;
width: 100%;
+ border-top: 1px solid;
+}
+.page h1:nth-child(2) {
+ margin-top: 40px;
+}
+.page h1.leader {
+ margin-top: 60px;
+}
+.page p {
+ margin: 20px;
}
/* DOCUMENTATION / ABOUT SECTION / FAQ PAGES */
.docs .content {
- width: 600px;
+ width: 80%;
margin: 0 auto;
text-align: left;
}
+.page.docs h1 {
+ border-top: 0px solid;
+ font-weight: 500;
+ font-size: 40px;
+}
.docs .content img {
max-width: 90%;
margin: 0 auto;
display: block;
}
+.docs a {
+ border-bottom: 1px dashed;
+}
+.docs #header a, .docs .footer a {
+ border-bottom: 0;
+}
.docs .options {
margin: 50px auto 0 auto;
@@ -364,36 +651,76 @@ iframe.embed {
.docs .content p {
margin: 1em 0;
+ font-size: 30px;
+ font-weight: 300;
+ line-height: 60px;
}
-
.footer {
width: 100%;
- padding: 80px 0;
+ padding: 100px 0 120px 0;
background: #f9f9f9;
+ float: left;
+ clear: both;
+ border-top:1px solid black;
}
-.footer a, .footer span{
+.footer a, .footer span {
margin: 15px;
font-weight: 300;
font-size: 13px;
}
+.desktop .footer a:hover{
+ text-decoration:underline;
+}
+
+.docs .content.doc-privacy,
+.docs .content.doc-terms {
+ font-size: 15px;
+ line-height: 25px;
+ font-weight: 300;
+}
+
+.aboutintro {
+ text-align: center;
+ line-height: 43px;
+ font-size: 24px;
+ padding: 5% 0;
+ font-weight: 300;
+}
+.aboutintro .inner {
+ max-width: 800px;
+ margin: 0 auto;
+ text-align: center;
+}
/* PROFILE PAGE */
-.profilepage .profilePic {
- font-size: 148px;
- background-size: cover;
- background-position: center;
+
+.profilePic {
+ background-size: cover;
+ background-position: center;
+ width: 40%;
+ height: 50vh;
+ float: left;
+ display:table;
}
-.editProfile {
- margin-right: 10px;
- color: black;
- font-weight: 100;
- text-decoration: none;
- padding: 50px 0 100px 0;
+
+.noPic {
+ border-right: 1px solid;
}
-.editProfile span {
- vertical-align: middle;
+
+.profilePic .ion-ios-person-outline {
+ font-size: 100px;
+}
+
+
+.noPic input {
+ position: absolute;
+ width: 40%;
+ height: 48vh;
+ margin-top: -33vh;
+ margin-left: -20%;
+ opacity: 0;
}
.topLinks {
float: right;
@@ -408,22 +735,35 @@ iframe.embed {
padding: 20px 8px;
color: black;
font-weight: 300;
- float:right;
+ float:left;
text-decoration: none;
- border-bottom:1px solid transparent;
}
-.topLinks a:hover {
+.page .topLinks a {
+ border-right:1px solid;
+}
+
+.page .topLinks a:last-child {
+ border-right:0px solid;
+}
+.desktop .topLinks a:hover {
background: black;
color: white;
}
.profilepage .bio {
- text-align: left;
- padding: 0 5%;
- width: 66.5%;
- background-image:url(../img/pattern.png);
- background-size:100%;
- background-color: lightyellow;
- box-shadow: -4px 6px 7px rgba(0,0,0,0.1) inset;
+ text-align: left;
+ padding: 0 5%;
+ width: 60%;
+ background-image: url(../img/pattern.png);
+ background-size: 100%;
+ background-color: lightyellow;
+ display: table;
+ height: 50vh;
+ float: left;
+ background:white!important;
+}
+
+.desktop .profilepage .bio a:hover {
+ text-decoration:underline;
}
.profilepage .bio.one {
@@ -468,53 +808,415 @@ iframe.embed {
.profilepage .bio h2 {
- text-align: left;
- font-weight: 100;
- font-size: 70px;
+ text-align: left;
+ font-weight: 500;
+ font-size: 18px;
}
.profilepage .bio span {
font-size: 16px;
font-weight: 300;
+ float: left;
+ clear: both;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ display: inline-block;
}
-.profilepage .bio span:after { content: ' \00b7 ' }
+
.profilepage .bio span:last-of-type:after { display: none; }
+.profilepage .about h2 {
+ text-align: center;
+ font-weight: 300;
+ font-size: 32px;
+}
+.profilepage .about h2:nth-child(2){
+ margin:34px 0;
+}
+.profilepage .about h2 a.homeLink {
+ background: white;
+ border: 1px solid black;
+ padding: 10px;
+}
+.profilepage .about h2 a.homeLink:hover {
+ background: black;
+ border: 1px solid black;
+ color: white;
+}
+.profilepage .about h3 {
+ font-size: 13px;
+ font-weight: 300;
+ text-align: center;
+}
+.about {
+ background-color: #ffffff;background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyODkuNScgaGVpZ2h0PScyODkuNScgdmlld0JveD0nMCAwIDI4OS41IDI4OS41Jz4KCTxkZWZzPgoJCTxwYXR0ZXJuIGlkPSdibHVlc3RyaXBlJyBwYXR0ZXJuVW5pdHM9J3VzZXJTcGFjZU9uVXNlJyB4PScwJyB5PScwJyB3aWR0aD0nNTcuOScgaGVpZ2h0PSc1Ny45JyB2aWV3Qm94PScwIDAgMTE1LjggMTE1LjgnID4KCQk8cmVjdCB3aWR0aD0nMTEwJScgaGVpZ2h0PScxMTAlJyBmaWxsPScjZmZmZmZmJy8+CgkJCTxwYXRoIGQ9J00xLDFoMTE1Ljh2MTE1LjhoLTExNS44di0xMTUuOCcgZmlsbC1vcGFjaXR5PScwJyBzdHJva2Utd2lkdGg9JzAuOCcgc3Ryb2tlLWRhc2hhcnJheT0nMCwxLDEnIHN0cm9rZT0nI2NjY2NjYycvPgoJCTwvcGF0dGVybj4gCgkJPGZpbHRlciBpZD0nZnV6eicgeD0nMCcgeT0nMCc+CgkJCTxmZVR1cmJ1bGVuY2UgdHlwZT0ndHVyYnVsZW5jZScgcmVzdWx0PSd0JyBiYXNlRnJlcXVlbmN5PScuMiAuMycgbnVtT2N0YXZlcz0nNScgc3RpdGNoVGlsZXM9J3N0aXRjaCcvPgoJCQk8ZmVDb2xvck1hdHJpeCB0eXBlPSdzYXR1cmF0ZScgaW49J3QnIHZhbHVlcz0nMCcvPgoJCTwvZmlsdGVyPgoJPC9kZWZzPgoJPHJlY3Qgd2lkdGg9JzEwMCUnIGhlaWdodD0nMTAwJScgZmlsbD0ndXJsKCNibHVlc3RyaXBlKScvPgo8cmVjdCB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJyBmaWx0ZXI9J3VybCgjZnV6eiknIG9wYWNpdHk9JzAnLz4KPC9zdmc+Cg==');
+ background-attachment: fixed;
+
+}
+
+
+.projectList.about.gopro {
+ padding:6% 0;
+}
+.about.gopro h3 {
+ font-weight:500;
+ text-align:center;
+ margin-bottom:20px;
+}
+.gopro span{
+ font-size: 24px;
+ font-weight: 300;
+ width: 710px;
+ display: block;
+ margin: 0 auto;
+ line-height: 50px;
+}
+.greenbtn{
+ width: 100%;
+ display: inline-block;
+ text-align: center;
+ margin-top: 40px;
+ background: limegreen;
+ color: white;
+ padding: 10px 0;
+ -webkit-transition:0.2s background;
+ -moz-transition:0.2s background;
+ transition:0.2s background;
+}
+.greenbtn.learn {
+ width: 60%;
+ clear: both;
+ font-size: 26px;
+ font-weight: 300;
+ margin: 140px 0% 0 20%;
+ background: #68B4FF;
+ padding: 20px 0;
+}
+.greenbtn:hover{
+ background:black;
+}
+.profilepage .about h2 .btn {
+ float: none;
+ border: 1px solid;
+ font-weight: 500;
+ padding: 10px;
+ font-size: 18px;
+}
+.desktop .profilepage .about h2 .btn:hover {
+ background:black;
+ color:white;
+}
+
+/* PLANS BROCHURE */
+.about_custom {
+ clear: both;
+ max-width: 600px;
+ margin: 0 auto;
+ font-size: 14px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.about_custom h3 {
+ text-transform: uppercase;
+ letter-spacing: 3px;
+ font-size: 1.25em;
+ font-weight: 500;
+ background: #3A3A3A;
+ color: white;
+ text-align: center;
+}
+.about_custom li {
+ list-style-type: none;
+ line-height: 2em;
+ padding: 10px 20px;
+ background: white;
+ text-align: center;
+ border-left: 1px solid #e5e5e5;
+ border-right: 1px solid #e5e5e5;
+}
+.about_custom a {
+ border-bottom: 1px solid black;
+}
+
+ul#plans {
+ margin: 0 auto;
+ text-align: center;
+ font-size: 14px;
+}
+
+ul#plans>li {
+ display: inline-block;
+ width: 300px;
+ vertical-align: top;
+ margin: 0 25px 25px 0;
+ position: relative;
+}
+
+ul#plans>li.most-popular:before {
+ content: 'Most Popular';
+ display: block;
+ background: #F17E6F;
+ color: white;
+ font-size: 1em;
+ font-weight: 500;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ width: 100%;
+ position: absolute;
+ top: -31px;
+}
+
+ul#plans .top {
+ background: #3A3A3A;
+ color: white;
+ padding: 30px 0;
+ height: 266px;
+}
+
+ul#plans h2 {
+ padding: 0;
+ font-size: 1.25em;
+ margin-bottom: 1.75em;
+ text-transform: uppercase;
+ letter-spacing: 3px;
+ font-weight: 500;
+}
+
+ul#plans h3 {
+ margin: 0 0 20px;
+ font-weight: 200;
+}
+
+ul#plans h3 span.dollar {
+ font-size: 1.25em;
+ vertical-align: top;
+ position: relative;
+ top: -14px;
+}
+
+ul#plans h3 span.price {
+ font-size: 5em;
+ font-weight: 100;
+}
+
+ul#plans h4 {
+ font-size: 0.85em;
+ color: #e6e6e6;
+ margin: 0 auto;
+ width: 50%;
+ font-weight: 500;
+ line-height: 30px;
+}
+
+ul#plans ul {
+ border-left: 1px solid #e5e5e5;
+ border-right: 1px solid #e5e5e5;
+}
+
+ul#plans ul li {
+ text-align: left;
+ border-bottom: 1px solid #e5e5e5;
+ padding: 5px 20px;
+ font-weight: 700;
+ list-style: none;
+ background: white;
+ color:#333;
+}
+
+ul#plans .signup {
+ background: #3A3A3A;
+ padding: 25px 0;
+}
+
+.signup .current {
+ display: inline-block;
+ color: white;
+ font-weight: bold;
+ font-size: 1em;
+ padding: 4px 30px 3px;
+}
+
+.signup .button {
+ font-weight: bold;
+ padding: 16px 30px 14px;
+ -o-transition: background 0.2s ease-in-out;
+ -webkit-transition: background 0.2s ease-in-out;
+ transition: background 0.2s ease-in-out;
+ display: inline-block;
+ background: #F17E6F;
+ color: white;
+ text-decoration: none;
+ font-size: 1em;
+ padding: 4px 30px 3px;
+ border: none;
+ cursor: pointer;
+}
+
+
+.signup .button:hover {
+ color: white;
+ background: #ef6958;
+}
+
+
+/* debug sync button */
+.editSubscription .gear {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ opacity: 0.1;
+ cursor: pointer;
+ -webkit-transition: all 0.3s;
+ -webkit-transform-origin: 49% 53%;
+ transition: all 0.3s;
+ transform-origin: 49% 53%;
+}
+.editSubscription .gear.turning {
+ opacity: 0.3;
+ -webkit-animation: gear 1s infinite linear;
+ animation: gear 1s infinite linear;
+}
+@-webkit-keyframes gear {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(720deg); }
+}
+@keyframes gear {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(720deg); }
+}
+.paidPlan {
+ text-align: left;
+ font-size: 14px;
+}
+.planInfo {
+ margin: 10px 0;
+ width: 100%;
+ padding: 0;
+}
+.planInfo td, .planInfo th {
+ text-align: left;
+ padding: 10px 3px;
+ margin: 0;
+}
+.planInfo td {
+ height: 60px;
+ vertical-align: middle;
+}
+.planInfo td:nth-child(2),
+.planInfo th:nth-child(2),
+.planInfo td:nth-child(3),
+.planInfo td:nth-child(4),
+.planInfo th:nth-child(3) {
+ text-align: right;
+}
+.planInfo td:nth-child(4) {
+ width: 90px;
+}
+
+.planInfo [data-role="billingInterval"] {
+ font-size: 10px;
+}
+.totalRow td:nth-child(4) {
+ border-top: 1px solid;
+}
+.paidPlan button {
+ width: 200px;
+ float: none;
+ margin: 5px 7px;
+}
+.paidPlan [data-role="cancelSubscription"] {
+ color: #800;
+ border-color: black;
+ width: 200px;
+ float: none;
+}
+.paidPlan [data-role="cancelSubscription"]:hover {
+ color: white;
+ background: red;
+ border-color: red;
+}
+/* purchase mode */
+.paidPlan input[type=number] { display: none; float: right; }
+form .paidPlan div { float: none; }
+form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; }
+.paidPlan .upgradeMenu div { padding: 5px 10px; }
+.paidPlan .editMenu { display: none }
+.paidPlan .planMenu { display: none }
+
+.editing .section_break { display: none }
+.editing .paidPlan .currentPlanLevel { display: none }
+.editing .paidPlan .billingMenu { display: none }
+.editing .paidPlan .editMenu { display: block }
+.editing .paidPlan .planMenu { display: block }
+.editing .paidPlan input[type=number] { display: inline-block }
+.editing .paidPlan input[type=number]+span { display: none }
+
+.editMenu .fineprint { font-size: 12px; width: auto; text-align: justify; }
+/* LAYOUTS MODAL */
+
.templates {
overflow: auto;
- max-height: 80%;
+ max-height: 100%;
+ width: 100%;
+ height: 100%;
+ padding: 20px 0 40px 0;
+ text-align: center;
+}
+.templates-list,
+.userTemplatesList,
+.blueprintsList {
+ display: inline-block;
width: 100%;
+ margin-bottom: 40px;
+}
+.templates::-webkit-scrollbar {
+ width: 5px;
+ height: 5px;
}
+
+.templates::-webkit-scrollbar-thumb {
+ background-color: white;
+ border-left: 1px solid black;
+}
+
+.templates::-webkit-scrollbar-track {
+ background-color: transparent;
+}
+
.no-templates {
display: none;
}
+.no-templates a {
+ border-bottom: 1px solid;
+}
-.templates span{
+.templates span {
+ display: inline-block;
+ margin: 1vw 0;
+ width:20%;
+ padding: 2vw;
+ cursor: pointer;
+}
+.templates span .image {
background-position: center;
- background-size: contain;
- background-repeat: no-repeat;
+ background-size: cover;
background-color: #fff;
- background-image: url(http://upload.wikimedia.org/wikipedia/commons/d/d9/Graceland_Memphis_TN_Floorplan_Basement.jpg);
- width: 20vw;
- height: 20vh;
- display: inline-block;
- margin: 4vw;
- border:1px solid white;
- position: relative;
+ width: 100%;
+ height: 15vw;
+ display: block;
+ background-color: #ddd;
}
-.templates span:after {
- content: attr(data-name);
- position: absolute;
- top: 100%;
- width: 100%;
- left: 0;
- background: #fff;
- padding: 5px;
- border-top: 1px solid black;
+.templates span label {
+ width: 100%;
+ left: 0;
+ display: block;
+ font-weight: 300;
}
-.templates span:hover {
- border:1px dashed black;
+
+.desktop .templates span:hover .image {
+ background-color: #f00;
cursor:pointer;
}
@@ -524,9 +1226,6 @@ iframe.embed {
margin: 0;
}
-.templates span.active {
- border:1px solid #017cfe;
-}
.clear:after {
visibility: hidden;
@@ -547,6 +1246,8 @@ iframe.embed {
float:right;
}
+/* MX SCENE STUFF */
+
.mx-scene {
position:fixed;
top:0;
@@ -569,11 +1270,25 @@ iframe.embed {
}
.editing .mx-scenery:hover,
.editing .mx-scenery.picked {
- border: 1px dashed #000;
+ border: 1px dashed black;
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+}
+.mx-outline {
+ border-width: 2px;
+ border-style: dashed;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
+.destroyActive .mx-scene, .destroyActive .mx-object3d.image {
+ cursor:url(/assets/img/delete-cursor.png), auto;
+}
+.addText .mx-scene, .menu span.inuse[data-role="toggle-text-editor"] {
+ cursor:url(/assets/img/text-cursor.png), auto;
+}
+
.mx-scenery:active {
cursor: pointer;
}
@@ -598,10 +1313,30 @@ iframe.embed {
.mx-object3d video {
pointer-events: none;
}
-
+.mx-text {
+/*
+ overflow: hidden;
+ */
+}
+.mx-text .inner {
+ width: 100%;
+ pointer-events: none;
+}
+.mx-text p {
+ margin-bottom: 1em;
+}
+#keyhint {
+ position: fixed;
+ bottom:0;
+ right:0;
+ pointer-events:none;
+ z-index: 2;
+}
#hud {
position: fixed;
top:0;left:0;
+ width: 100%;
+ height: 100%;
z-index: 2;
}
#palette {
@@ -634,7 +1369,7 @@ iframe.embed {
.face {
background-color: #fff;
- transition: 0.1s background-color ease;
+ transition: 0.1s background-color ease, 0.05s background-color ease;
}
.front { background-color: #fff; }
.back { background-color: #fff; }
@@ -651,8 +1386,8 @@ iframe.embed {
.dot {
background:white;
- border-radius:20px;
- border: 1px solid black;
+ border-radius: 50%;
+ border: 2px solid black;
}
.image {
@@ -663,10 +1398,10 @@ iframe.embed {
/* AUTOSAVE MONITOR */
#minotaur {
- position: absolute;
- top: 25px;
- right: 260px;
- opacity: 0;
+ position: absolute;
+ top: 0px;
+ left: 150px;
+ opacity: 0;
}
#minotaur .label:after {
padding: 6px;
@@ -674,11 +1409,13 @@ iframe.embed {
font-weight: 300;
}
#minotaur.saving {
- background: white;
+ padding: 20px 8px;
+ color: white;
+ background: red;
+ font-weight: 300;
+ text-decoration: none;
+ z-index: 33;
opacity: 1;
- z-index: 20;
- font-size: 13px;
- border: 1px solid;
}
#minotaur.saving .label:after {
content: 'SAVING';
@@ -690,16 +1427,26 @@ iframe.embed {
}
.logo {
float:left;
- padding:7px 0 0 10px;
- z-index:4;
- position:relative;
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none;
+ padding:6px 8px 9px 8px;
}
-.logo:hover {
- -webkit-filter:invert(30%);
+
+.desktop .logo:hover {
+ background:black;
+}
+.desktop .logo:hover svg {
+ fill:white;
+}
+
+#fallback {
+ width: 400px;
+ margin: 10% auto;
+ border: 2px solid black;
+ padding: 30px 20px 30px 20px;
}
+#fallback a {
+ border-bottom: 1px solid;
+}
+
.profile{
padding:8px;
float:right;
@@ -734,8 +1481,8 @@ iframe.embed {
}
.menu {
- right: 10px;
- top: 70px;
+ right: 9px;
+ top: 63px;
z-index:3;
-webkit-user-select: none;
-moz-user-select: none;
@@ -753,7 +1500,7 @@ iframe.embed {
width: 55px;
}
-.menu span:hover{
+.desktop .menu span:hover{
color:white;
background:black;
cursor:pointer;
@@ -765,17 +1512,18 @@ iframe.embed {
cursor:pointer;
}
-.menu span.inuse {
+.menu span.inuse,
+.menu span.active {
color:white;
background:black;
cursor:pointer;
}
.menu span.inuse:before {
- content: "\e736" !important;
+ content: "\f12a" !important;
}
-.menu span:hover:after{
+.desktop .menu span:hover:after{
content: attr(data-info);
position: absolute;
color: black;
@@ -787,13 +1535,20 @@ iframe.embed {
padding: 17px 13px;
margin-top: -16px;
font-size: 13px;
+ font-family:'Lato', sans-serif;
+ font-weight:600;
+}
+
+.menu span.ion-ios-sunny-outline:hover:after {
+ width: 130px;
}
+
.menu span.inuse:hover:after{
content:"";
opacity:0;
}
-.menu span.icon-map.hidden:hover:after{
+.menu span.ion-map.hidden:hover:after{
content:"show map";
}
.fixed {
@@ -802,12 +1557,12 @@ iframe.embed {
left: 0;
width: 100%;
height: 100%;
- z-index: 3;
+ z-index: 6;
overflow-y: scroll;
}
.fixed::-webkit-scrollbar {
- width: 3px;
+ width: 3px;
}
.fixed::-webkit-scrollbar-track {
@@ -830,25 +1585,31 @@ iframe.embed {
background: black;
}
.animate {
- -webkit-transition:all 0.2s ease-in-out;
- transform:translateY(-100%);
+ -webkit-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
}
.mediaDrawer {
- -webkit-transform:translateY(-100%);
- transform:translateY(-100%);
- background:rgba(255,255,255,0.9);
- text-align:center;
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ background: white;
+ text-align: center;
overflow-x: hidden;
}
+.editing .mediaDrawer {
+ background:rgba(255,255,255,0.95);
+}
.mediaDrawer.active {
- -webkit-transform:translateY(0%);
- transform:translateY(0%);
+ -webkit-transform: translateY(0%);
+ transform: translateY(0%);
}
.mediaDrawer.table, .mediaDrawer.error,
.mediaDrawer.signin, .mediaDrawer.signup,
.mediaDrawer.alert, .mediaDrawer.confirm,
.mediaDrawer.passwordForgot, .mediaDrawer.passwordReset, .mediaDrawer.usernameTaken,
-.mediaDrawer.layouts, .mediaDrawer.projects, .mediaDrawer.newProject {
+.mediaDrawer.layouts, .mediaDrawer.projects, .mediaDrawer.newProject,
+.mediaDrawer.blueprintEditor {
display:table;
}
.confirm button {
@@ -873,8 +1634,27 @@ iframe.embed {
background-image:url(https://s3.amazonaws.com/luckyplop/735c46b0268cd511a22c37bc0c11e9f60c4459b2.png)!important;
cursor:move;
}
-.deleteActive .mx-object3d.image {
- cursor:pointer;
+#deleteMedia {
+ font-size: 13px;
+ padding: 3px;
+ cursor:pointer;
+}
+#deleteMedia:after {
+ content:"delete media?";
+}
+.deleteArmed #deleteMedia:after {
+ content:"click media you want to delete";
+}
+.deleteArmed #deleteMedia:before {
+ content: "X";
+ background: black;
+ width: 23px;
+ height: 23px;
+ position: absolute;
+ margin-left: -25px;
+ margin-top: -4px;
+ font-size: 19px;
+
}
.deleteActive .mx-object3d.image:after {
content: "\e68f";
@@ -904,7 +1684,7 @@ iframe.embed {
cursor:text;
}
-.fileUpload{
+.fileUpload {
position: fixed;
width: 400px;
text-align: center;
@@ -913,22 +1693,22 @@ iframe.embed {
left: 50%;
padding: 26px 20px;
margin-left: -200px;
- background: white;
- z-index: 4;
+ background: rgba(255,255,255,0.99);
+ z-index: 7;
-webkit-transform: translateY(-1000%);
-webkit-transition: -webkit-transform 0.6s ease-in-out;
transform: translateY(-1000%);
- transition: -webkit-transform 0.6s ease-in-out;
+ transition: transform 0.6s ease-in-out;
border: 1px solid;
box-shadow: -3px 3px black;
}
.fileUpload.active {
- -webkit-transform:translateY(0%);
- transform:translateY(0%);
+ -webkit-transform: translateY(0%);
+ transform: translateY(0%);
}
-.fileUpload .icon-ios7-upload-outline {
+.fileUpload .ion-ios-upload-outline {
font-size:40px;
}
.fileUpload .upload-icon.uploading {
@@ -937,7 +1717,7 @@ iframe.embed {
content: ' ' !important;
background-image: url("/assets/img/loader.gif");
background-repeat: no-repeat;
- width: 40px;
+ width: 21px;
height: 40px;
}
@@ -945,7 +1725,7 @@ iframe.embed {
border: 1px solid #ccc;
font-size: 15px;
padding: 5px;
- width: 220px;
+ width: 290px;
text-align: center;
border-radius: 20px;
}
@@ -977,8 +1757,10 @@ iframe.embed {
.myMedia.inactive {
opacity:0;
}
-
-.foundMedia {
+.noMedia {
+ margin: 40px;
+}
+.foundMedia, .wallpaperMedia {
position:absolute;
top:0;
left:0;
@@ -989,38 +1771,36 @@ iframe.embed {
padding-top:40px;
width: 100%;
}
-
-.foundMedia.active {
+.foundMedia.active, .wallpaperMedia.active {
-webkit-transform: translateX(0%);
transform: translateX(0%);
}
.mediaDrawer h2{
- font-size: 18px;
+ font-size: 24px;
display: inline-block;
- margin-top: 20px;
position:relative;
z-index:4;
+ font-weight: 300;
}
-.mediaDrawer h3{
- margin-top: 28px;
- position: relative;
- z-index: 4;
+.mediaDrawer form h2{
+ font-size: 22px;
+ display: inline-block;
+ position: relative;
+ z-index: 4;
+ margin-bottom: 20px;
}
-.editBtn{
- color: #FF3B30;
- padding: 3px;
- font-size: 12px;
- display: inline-block;
- cursor:pointer;
- font-weight:600;
- text-decoration:none;
+.mediaDrawer.mediaViewer h2 {
+ margin-top:28px;
+ font-size:18px;
}
-.editBtn:hover {
- background:black;
+.mediaDrawer h3{
+ margin-top: 18px;
+ position: relative;
+ z-index: 4;
}
.deleteArmed .mediaDrawer h3 {
@@ -1028,8 +1808,6 @@ iframe.embed {
color:white;
}
-.deleteArmed .mediaContainer {
-}
.deleteArmed .mediaContainer:hover {
background:#FF3B30;
@@ -1037,22 +1815,24 @@ iframe.embed {
}
.deleteArmed .mediaContainer:before {
- content: "\e68f";
- font-family: 'ionicons';
- speak: none;
- font-style: normal;
- font-weight: normal;
- font-variant: normal;
- text-transform: none;
- line-height: 1;
- -webkit-font-smoothing: antialiased;
- font-size: 60px;
- margin-top: -62px;
- position: absolute;
- background: #FF3B30;
- border-radius: 1000px;
- margin-left: -59px;
- color: white;
+ content: "\f1eb";
+ font-family: 'ionicons';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ -webkit-font-smoothing: antialiased;
+ font-size: 40px;
+ margin-top: -50px;
+ position: absolute;
+ background: #FF3B30;
+ border-radius: 1000px;
+ margin-left: -50px;
+ color: white;
+ width: 50px;
+ height: 50px;
+ line-height: 50px;
}
.deleteArmed .mediaContainer.deleted {
@@ -1062,31 +1842,32 @@ iframe.embed {
color: #555;
text-decoration:none;
padding:5px;
- border:3px solid white;
+ border:2px solid white;
+ font-weight: 400;
+ font-size: 15px;
}
.mediaDrawer h2 a.active{
cursor:default;
- border:3px solid black;
+ border:2px solid black;
color:black;
}
.mediaDrawer h2 a:hover {
- border:3px solid #ccc;
+ border:2px solid #ccc;
}
.mediaDrawer h2 a.active{
- border:3px solid black;
+ border:2px solid black;
}
.mediaContainer {
- border: 1px solid white;
display: inline-block;
width: 25%;
margin: 4%;
vertical-align: top;
- border:1px solid white;
+ border:1px solid transparent;
padding:2%;
}
.mediaContainer:hover {
@@ -1096,7 +1877,19 @@ iframe.embed {
.mediaContainer img, .mediaContainer video {
max-width:100%;
}
-
+#reset {
+ position: fixed;
+ bottom: 160px;
+ left: 20px;
+ border-bottom: 1px solid black;
+ padding-bottom: 3px;
+ z-index:3;
+}
+#reset:hover {
+ cursor:pointer;
+ background:black;
+ color:white;
+}
#minimap {
position: fixed;
bottom: 20px;
@@ -1110,12 +1903,12 @@ iframe.embed {
-moz-user-select: none;
user-select: none;
}
-#minimap.hide{
+#minimap.hide {
-webkit-transform: translateY(155px);
transform: translateY(155px);
}
-#minimap.hide canvas{
- opacity:0;
+#minimap.hide canvas {
+ opacity: 0;
}
#minimap canvas {
display: block;
@@ -1124,21 +1917,46 @@ iframe.embed {
-webkit-transition:opacity 0.3s ease-in-out;
transition:opacity 0.3s ease-in-out;
}
+.reader #minimap {
+ right: 10px;
+ bottom: 10px;
+ left: auto;
+ -webkit-transform:translateX(180px);
+ -moz-transform:translateX(180px);
+ transform:translateX(180px);
+ -webkit-transition:0.6s -webkit-transform;
+ -moz-transition:0.6s -moz-transform;
+ transition:0.6s transform;
+}
+
+.reader #minimap.active {
+ -webkit-transform: translateX(0px);
+ -moz-transform: translateX(0px);
+ transform: translateX(0px);
+ left: auto;
+}
+.mobile .reader #minimap{
+ display:none;
+}
/* WALLPAPER PICKER */
-.wallpaper {
+.wallpaper, #presets {
right: 80px;
margin-top: 77px;
- width: 162px;
- z-index: 1;
+ width: 202px;
-webkit-transition: -webkit-transform 0.1s ease-in-out;
-webkit-transform: translateX(400px);
transition: transform 0.1s ease-in-out;
transform: translateX(400px);
+ padding: 10px 12px 12px 12px;
+}
+
+#presets {
+ margin-top: 110px;
}
-.wallpaper.active {
+.wallpaper.active, #presets.active {
display:inline-block;
-webkit-transform: translateX(0px);
transform: translateX(0px);
@@ -1148,11 +1966,15 @@ iframe.embed {
height: 40px;
display: inline-block;
border: 1px solid;
- background-size: contain;
+ background-size: 100%;
+ margin: 0 2px 4px 2px;
-webkit-transition: -webkit-transform 0.1s ease-in-out;
line-height: 0;
vertical-align: text-bottom;
+ background-color:white;
-webkit-user-drag: element;
+ background-size: auto 100%;
+ background-position: center;
}
.wallpaper.active .swatches .swatch:hover {
cursor: pointer;
@@ -1160,42 +1982,134 @@ iframe.embed {
transform: translateX(3px) translateY(-3px);
}
.wallpaper .swatches {
- width: 100%;
- border-bottom: 1px solid black;
- min-height: 30px;
+ width: 100%;
+ min-height: 30px;
+ border-bottom: 1px solid #ddd;
+ display: inline-block;
+ padding-bottom: 6px;
}
-.wallpaper {
- font-size: 14px;
+
+.wallpaper.deleteArmed.active .swatches .swatch {
+ border: 1px solid #FF3B30;
+}
+.desktop .wallpaper.deleteArmed .swatch:hover {
+ background-color: #FF3B30;
+}
+
+.wallpaper.deleteArmed .swatch:before {
+ content: "\f1eb";
+ font-family: 'ionicons';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ -webkit-font-smoothing: antialiased;
+ font-size: 16px;
+ position: absolute;
+ background: #FF3B30;
+ border-radius: 50%;
+ margin-top: -8px;
+ margin-left: -8px;
+ color: white;
+ width: 20px;
+ height: 20px;
+ line-height: 16px;
+ text-align: center;
+ padding-top: 2px;
+}
+
+.exampleTumblrs {
+ display: block;
+ margin-top: 10px;
font-weight: 300;
+ font-size: 0.8em;
+}
+.exampleTumblrs a {
+ border-bottom: 1px dotted;
+ margin-left: 5px;
+}
+
+.vvbox .colors {
+ max-width: 155px;
+ margin-bottom: 5px;
+}
+.vvbox .colors span {
+ display: inline-block;
+ font-size: 0;
+ width: 20px;
+ height: 20px;
+ border: 1px solid #ddd;
+ margin: 0px 2px 0 0;
+ cursor: pointer;
+ transition: transform 0.2s;
+}
+.vvbox .colors span:hover {
+ transform: translateX(2px) translateY(-2px);
+}
+
+.toolButton {
+ border: 1px solid;
+ position: relative;
+ float: left;
+ width: 86px;
+ height: 35px;
+ font-size: 12px;
+ font-weight: 300;
+ cursor: pointer;
}
-.wallpaper label {
+
+.toolButton label {
position: relative;
- top: -6px;
+ vertical-align: middle;
float: none;
}
+.wallpaperRemove {
+ margin-right: 4px;
+}
+.wallpaperUpload:hover {
+ cursor:pointer;
+}
.wallpaper form {
- padding: 2px 0 0 0;
+ position: relative;
+ font-weight: 300;
+ overflow: hidden;
}
-.wallpaper .icon-ios7-upload-outline {
- font-size: 26px;
+.toolButton:hover {
+ background:black;
+ color:white;
+ cursor:pointer;
+}
+.toolButton > span, .toolButton form > span{
+ font-size: 26px;
+ margin: 0 7px;
+ vertical-align: middle;
}
.wallpaper .wallpaperRemove {
cursor: pointer;
border-top: 1px solid black;
- padding: 4px 0 0 0;
+ padding: 0;
}
.wallpaper .wallpaperRemove img {
width: 18px;
margin: 0 4px;
}
+.wallpaper .wallpaperRemove:hover img {
+ -webkit-filter:invert(100%);
+}
+.wallpaperUpload .upload-icon {
+ margin: 0 8px;
+}
.wallpaperUpload .upload-icon.uploading {
}
.wallpaperUpload .upload-icon.uploading:before {
content: ' ' !important;
background-image: url("/assets/img/loader.gif");
background-repeat: no-repeat;
- width: 40px;
- height: 40px;
+ background-position: center;
+ width: 100%;
+ height: 100%;
+ position:absolute;top:0;left:0;
}
.wallpaperUpload input[type="text"]{
border: 1px solid #ccc;
@@ -1209,39 +2123,34 @@ iframe.embed {
border: 1px solid #000;
}
.wallpaperUpload input[type="file"]{
- position: absolute;
- margin-left: -134px;
- background: blue;
- height: 28px;
- width: 100%;
- margin-top: 0px;
- opacity: 0;
- cursor:pointer;
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: blue;
+ height: 100%;
+ width: 100%;
+ opacity: 0;
+ cursor: pointer;
}
/* COLOR PICKER */
-.lightcontrol {
- margin-top: 13%;
+.colorcontrol {
+ margin-top: 8%;
right: 80px;
- padding: 20px;
+ padding: 10px 12px 12px 12px;
-webkit-transform: translateX(400px);
-webkit-transition: -webkit-transform 0.2s ease-in-out;
transform: translateX(400px);
transition: -webkit-transform 0.2s ease-in-out;
}
-.lightcontrol h4 {
- font-weight: 600;
- font-size: 12px;
- line-height: 0;
- margin-top: 15px;
-}
-.lightcontrol.active {
+
+.colorcontrol.active {
-webkit-transform: translateX(0px);
transform: translateX(0px);
}
-.lightcontrol .slider {
+.colorcontrol .slider {
}
h4 {
font-weight:300;
@@ -1250,19 +2159,70 @@ h4 {
input[type=range] {
-webkit-appearance: none;
-moz-appearance: none;
+ cursor: pointer;
background-color: black;
- width: 180px;
- height:3px;
+ width: 155px;
+ height: 3px;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
- background-color: #000;
- width: 10px;
- height: 10px;
+ background-color: white;
+ width: 15px;
+ height: 15px;
border-radius:10px;
cursor:pointer;
+ border:3px solid #000;
+}
+.wallpaperResizeControls {
+ transition: all 0.2s;
+ float: left;
+ height: 28px;
+ overflow: hidden;
+}
+.wallpaperResizeControls.disabled {
+ height: 0;
+ opacity: 0.3;
}
-#color-picker {
+.wallpaperResizeControls input[type=range] {
+ width: 150px;
+ position: relative;
+ top: -10px;
+}
+.wallpaperResizeControls {
+ font-size: 30px;
+}
+.wallpaperResizeControls span {
+ cursor: pointer;
+}
+.floodMessage {
+ display: none;
+ animation: flicker 0.2s infinite;
+ -webkit-animation: flicker 0.2s infinite;
+ -moz-animation: flicker 0.2s infinite;
+ color: black;
+ float: left;
+ margin: 10px 5px 5px 5px;
+ font-size: 10px;
+ text-align: center;
+ font-weight:600;
+ color:red;
+ text-transform:uppercase;
+ text-align:left;
+}
+.floodMessage:before {
+ content:"CLICK ON WALL OR ";
+}
+@keyframes flicker {
+ 50% { opacity:0.7; }
+}
+@-webkit-keyframes flicker {
+ 50% { opacity:0.7; }
+}
+@-moz-keyframes flicker {
+ 50% { opacity:0.7; }
+}
+
+.color-picker {
position: relative;
}
.colorPicker {
@@ -1286,27 +2246,61 @@ input[type="range"]::-webkit-slider-thumb {
cursor: pointer;
float:left;
}
-span:hover .swatch {
- border: 1px solid red;
-}
-.active .swatch {
+
+.color-swatches .active .swatch {
border: 1px solid #000;
}
.color-swatches {
margin-top: 10px;
}
+
+.presets {
+ margin-top: 10px;
+}
+.presets span {
+ font-size:12px;
+ font-weight:500;
+ display: inline-block;
+ width: 50%;
+ float:left;
+ cursor:pointer;
+ border-bottom: 1px transparent solid;
+ padding: 5px;
+}
+.presets span:hover,
+.presets span.active {
+ text-decoration: underline;
+}
.color-swatches span {
display: inline-block;
width: 50%;
float:left;
cursor:pointer;
+ font-size: 14px;
+ font-weight: 300;
+}
+.vvbox .color-swatches ~ h4 {
+ margin-bottom: -4px;
+ border-bottom: 1px solid #ddd;
+ padding-bottom: 4px;
+ padding-top: 11px;
+ display: inline-block;
+ width: 100%;
+ color: #555;
}
+.wallpaper .url {
+ margin: 4px 0;
+ padding: 2px;
+ font-size: 12px;
+ border: 1px black solid;
+ width: 100%;
+}
+
.color-swatches span:nth-child(1),.color-swatches span:nth-child(2){
margin-bottom:5px;
}
-.color-swatches span.active{
- background:red;
- color:white;
+.color-swatches span.active, .color-swatches span.active:hover{
+ background: #fff;
}
.color-swatches span:nth-child(3){
clear:left;
@@ -1314,38 +2308,87 @@ span:hover .swatch {
.color-swatches span:hover {
background:#eee;
}
-
-.color-swatches span.active:hover {
- background:red;
+.color-swatches span.active label,
+.color-swatches span:hover label {
+ border-bottom: 1px solid;
}
+
.color-swatches label {
- font-size: 14px;
- font-weight: 300;
position: relative;
- padding-left: 5px;
+ font-size: 13px;
+ margin-left: 5px;
display: inline-block;
cursor: pointer;
- top: -2px;
}
-.color-swatches span.active label {
+
+#helpCursor {
+ position: fixed;
+ max-width: 200px;
+ font-size: 15px;
+ color: white;
+ background: rgba(255,0,0,0.8);
+ margin: 8px 0 0 8px;
+ padding: 10px;
font-weight: 600;
+ z-index: 22;
+ display: none;
+ margin-left:-220px;
+ margin-bottom:20px;
}
-
.settings.info {
right: auto;
left: 10px;
+ width: 230px;
+}
+
+.vvbox h4 {
+ font-weight: 600;
+ margin-bottom: 10px;
+ border-bottom: 1px solid #999;
+ padding-bottom: 6px;
}
.settings {
- padding: 20px;
- bottom: 20px;
+ padding: 10px 12px 12px 12px;
+ bottom: 10px;
right: 10px;
font-size: 12px;
- -webkit-transform: translateY(400px);
+ -webkit-transform: translateY(500px);
-webkit-transition: -webkit-transform 0.2s ease-in-out;
- transform: translateY(400px);
+ transform: translateY(500px);
transition: -webkit-transform 0.2s ease-in-out;
+ width: 210px;
+}
+#blueprintNotice.settings {
+ width: 230px;
+}
+#blueprintNotice a {
+ border-bottom: 1px solid;
+}
+#blueprintNotice .next {
+ display: inline-block;
+ background: black; color: white;
+ padding: 4px;
+ margin: 4px 0 0 0;
+ float: right;
+ cursor: pointer;
+}
+#textEditor.settings {
+ width: 320px;
+}
+#textEditor .swatch {
+ position: relative;
+ top: 6px;
+ margin-left: 6px;
+ cursor: pointer;
+ float: none;
+}
+#textEditor.color-mode {
+ width: 180px;
+}
+#textEditor.color-mode h4:after {
+ content: ' Colors';
}
.settings.active {
@@ -1356,10 +2399,13 @@ span:hover .swatch {
.modalLink {
text-decoration: none;
}
-.modalLink:hover {
+.modalLink:hover span {
text-decoration: underline;
}
-
+.settings .name {
+ display: block;
+ margin-top: 10px;
+}
@-webkit-keyframes fade {
50% {
opacity:0.6;
@@ -1370,33 +2416,45 @@ span:hover .swatch {
opacity:0.6;
}
}
-#startpoint.active #moveText{
+
+#moveText,
+#confirmText {
+ display: none;
+}
+#startpoint.active #moveText {
+ display:inline-block;
-webkit-animation:fade 0.5s infinite;
animation:fade 0.5s infinite;
}
-#moveText{
- display:none;
+#startpoint #goText,
+#startpoint.active #startText,
+#startpoint.active #goText,
+#startpoint.confirmed #startText {
+ display: none;
}
-#moveText.show {
- display:inline-block;
+#startpoint.confirmed #confirmText {
+ display: inline-block;
}
-#startText.hide {
- display:none;
+#startpoint.confirmed #goText {
+ display: inline-block;
}
-#startpoint.active:after {
+#moveText .done {
content: "done";
background: black;
color: white;
padding: 2px;
font-weight: 900;
margin-left: 5px;
+ text-decoration: none !important;
}
#startpoint.active:hover {
text-decoration:none;
}
+
.settings input[type="text"] {
border: 1px solid #000;
font-size: 15px;
+ max-width: 100%;
padding: 5px;
}
@@ -1406,7 +2464,11 @@ span:hover .swatch {
font-size: 12px;
width: 100%;
max-height: 200px;
- max-width: 180px;
+ max-width: 100%;
+}
+#textEditor.settings textarea {
+ max-height: none;
+ height: 290px;
}
.settings input[type="text"]:focus{
@@ -1449,6 +2511,9 @@ span:hover .swatch {
top: 5px;
font-weight:600;
}
+.setting.number.scale label {
+ top: 0;
+}
.setting.number label:after {
content:":";
}
@@ -1471,24 +2536,42 @@ span:hover .swatch {
top: 0px;
}
+.setting.number #room-height {
+ width: 60px;
+}
+.setting.number #room-height-global-label {
+ float: none;
+ margin-left: 6px;
+}
+.setting.number #room-height-global-label:after {
+ content: '';
+}
+
#mediaEditor .setting.number label {
width: 40px;
}
#mediaEditor .setting.number [type=text] {
width: 140px;
}
+#sculptureEditor .setting.number input[type=text] {
+ width: 130px;
+}
.playButton,.muteButton {
- color: white;
- background: black;
- border-radius: 50px;
- font-size: 22px;
- padding: 4px 2px 3px 6px;
+ border-radius: 50%;
+ font-size: 23px;
+ padding: 5px 0;
cursor: pointer;
margin-right: 5px;
+ width: 40px;
+ display: inline-block;
+ text-align: center;
+ border: 1px solid;
}
.playButton .on {
display: inline;
+ position: relative;
+ left: 1px;
}
.playButton.paused .on {
display: none;
@@ -1503,6 +2586,8 @@ span:hover .swatch {
.muteButton .on {
display: inline;
padding-right: 3px;
+ position: relative;
+ left: 2px;
}
.muteButton.muted .on {
display: none;
@@ -1513,6 +2598,9 @@ span:hover .swatch {
.muteButton.muted .off {
display: inline;
padding-right: 3px;
+ position: relative;
+ left: 2px;
+ top: -1px;
}
.btn, button {
@@ -1529,7 +2617,38 @@ span:hover .swatch {
color:white;
}
.btn.marg {
- margin-top:10px;
+ margin-top:5px;
+ width: 100%;
+}
+#randomize {
+ background: transparent;
+ display: inline-block;
+ color: #999;
+ text-decoration: none;
+ text-align: left;
+ font-size: 12px;
+ padding: 5px;
+ cursor: pointer;
+ position: absolute;
+ left: 10px;
+ font-weight: 500;
+ top: 0px;
+ border: 1px solid #999;
+ -webkit-transition:0.2s background;
+ -moz-transition:0.2s background;
+ transition:0.2s background;
+}
+#randomize:hover {
+ color: white;
+ background: black;
+}
+#tumblr-url {
+ border: 1px solid #999;
+ padding: 10px 5px;
+ position: absolute;
+ top: 18px;
+ left: 145px;
+ width: 216px;
}
.warn {
background:red;
@@ -1546,13 +2665,15 @@ button {
font-weight: 500;
width: 100%;
font-size:14px;
+ font-family:'Lato', sans-serif;
}
#builder-units {
- width:100%;
+ width:75%;
}
#mediaEditor .warn {
width:100%;
+ padding:5px 0;
}
.radio-group {
@@ -1627,6 +2748,8 @@ form div.hidden {
}
form h3.link {
content:"?";
+ margin-top: 0;
+ padding: 0 0 10px 0;
}
form h3.link:after {
content:"?";
@@ -1650,7 +2773,7 @@ form li {
form label {
float:left;
}
-form input[type="text"],form input[type="password"] {
+form input[type="text"],form input[type="password"],form input[type="number"] {
border: 1px solid;
font-size: 20px;
padding: 5px;
@@ -1670,7 +2793,7 @@ form input[type="submit"]:hover {
border:1px solid black;
cursor:pointer;
}
-form p{
+form p {
display: block;
float: left;
font-size: 15px;
@@ -1678,6 +2801,11 @@ form p{
margin-top: 10px;
color: #999;
}
+form p.guidelines {
+ width: 200px;
+ text-align: left;
+ margin: 20px 0;
+}
form h3 {
text-align: left;
font-weight: 600;
@@ -1688,6 +2816,7 @@ form h3 {
}
#form_container {
clear:both;
+ padding-bottom: 50px;
}
.errors {
display: none;
@@ -1695,7 +2824,7 @@ form h3 {
text-align: center;
background: #f8f8f8;
padding: 10px;
- margin-top: 10px;
+ margin:5px 0 10px 0;
border-radius: 3px;
}
.errorList {
@@ -1711,6 +2840,7 @@ form li div div {
}
form li img#load_avatar {
max-width: 200px;
+ float: right;
}
form li textarea {
width: 100%;
@@ -1719,13 +2849,17 @@ form li textarea {
}
.hero {
- float:left;
- width:100%;
- clear:both;
- height:70vh;
- display:table;
- background-size:cover;
+ float: left;
+ width: 100%;
+ clear: both;
+ height: 80vh;
+ display: table;
+ background-size: cover;
+ background-position: center;
+ margin-top: 63px;
}
+
+
.hero .circle {
font-size: 20px;
font-weight: 300;
@@ -1733,14 +2867,25 @@ form li textarea {
display: inline-block;
padding: 60px 20px;
border-radius: 230px;
+ opacity:1;
+ -webkit-transition:0.2s background;
+ -moz-transition:0.2s background;
+ transition:0.2s background;
+ position: relative;
+ z-index: 6;
}
-.hero .circle:hover {
+
+.desktop .hero .circle:hover {
background:black;
color:white;
cursor:pointer;
}
-
+.chardinjs-tooltiptext {
+ font-weight: 300;
+ line-height: 20px;
+ font-size: 16px;
+}
.box {
display: table-cell;
@@ -1763,15 +2908,31 @@ form li textarea {
right: 20px;
top: 20px;
z-index: 20;
- background: #f9f9f9;
+ background: white;
width: 75px;
color: black;
border: 1px solid black;
box-shadow: -3px 4px black;
line-height: 75px;
+ text-align: center;
+}
+#fixed_close {
+ display: none;
+ -webkit-transform: translateY(-200px) translateZ(0);
+ transform: translateY(-200px) translateZ(0);
+}
+#fixed_close.active {
+ -webkit-transition: 0.2s -webkit-transform linear 1s;
+ transition: 0.2s transform linear 1s;
+ display: block;
+ -webkit-transform: translateY(0px) translateZ(0);
+ transform: translateY(0px) translateZ(0);
}
-.close:hover {
+
+
+
+.desktop .close:hover {
background:black;
color:white;
}
@@ -1806,8 +2967,9 @@ form li textarea {
letter-spacing: 2px;
}
.facebook b {
- float: left;
- font-size: 50px;
+ float: left;
+ font-size: 50px;
+ margin: 0 0 0 20px;
}
a[data-role="forgot-password"] {
@@ -1819,13 +2981,13 @@ a[data-role="forgot-password"] {
vertical-align: bottom;
padding-right: 14px;
font-size: 19px;
- line-height: 16px;
+ line-height: 7px;
}
.aboutRoom {
- width: 250px;
+ width: 190px;
background: rgba(255,255,255,0.95);
- padding: 20px;
+ padding: 2px 8px 8px 8px;
position: fixed;
bottom: 10px;
left: 10px;
@@ -1833,19 +2995,58 @@ a[data-role="forgot-password"] {
}
.aboutRoom h1 {
- font-size:28px;
+ font-size:26px;
+}
+.txt.description {
+ max-height: 200px;
+ overflow: auto;
+}
+.txt.description::-webkit-scrollbar {
+ width: 4px;
+}
+.txt.description::-webkit-scrollbar-track {
+}
+.txt.description::-webkit-scrollbar-thumb {
+ background: #000;
+}
+::-webkit-scrollbar-thumb:window-inactive {
+ background: #888;
}
+
.txt {
font-size:12px;
padding:5px 0;
display: inline-block;
}
-.aboutRoom h1 a{
+
+.vvbox .txt {
+ padding:5px;
+}
+
+.vvbox.wallpaper .txt{
+ padding:0;
+}
+
+.aboutRoom.vvbox .txt {
+ padding: 5px 0 3px 0;
+}
+.aboutRoom h1 a {
text-decoration: none;
font-style: italic;
+ font-weight:500;
+}
+.aboutRoom .profilePic {
+ width: 34px;
+ height: 34px;
+ float: none;
+ display: inline-block;
+ vertical-align: middle;
+}
+.aboutRoom .authorName {
+ vertical-align: middle;
}
-.aboutRoom h1 a:hover {
+.desktop .aboutRoom h1 a:hover {
text-decoration:underline;
}
@@ -1857,7 +3058,9 @@ a[data-role="forgot-password"] {
width: 100%;
text-align: center;
}
-
+.mobile .aboutRoom .editlink {
+ display:none;
+}
.aboutRoom .editlink:hover {
background:black;
color:white;
@@ -1868,43 +3071,61 @@ a[data-role="forgot-password"] {
margin: 5px 0 0 0;
}
+
.share {
- position: fixed;
- right: 0px;
- bottom: 10px;
- padding-right:10px;
- background:rgba(255,255,255,0.95);
- z-index: 2;
+ display:inline-block;
+ width:100%;
+ margin-bottom:5px;
}
-
.share h2 {
- font-weight: 300;
- font-size: 18px;
- text-align: right;
+ font-weight: 400;
+ font-size: 13px;
+ margin:0;
}
.share a{
color: #017cfe;
text-decoration: none;
- margin-left: 6px;
- font-size: 13px;
+ font-size: 12px;
font-weight: 600;
+ cursor: pointer;
}
-
-.share a:hover{
+.share a:nth-child(3), .share a:nth-child(4) {
+ margin-left:4px;
+}
+.desktop .share a:hover{
text-decoration:underline;
}
+.vvbox.share {
+ width: 230px
+}
+.vvbox.share #share_link {
+ width: 100%;
+ margin-top: 4px;
+ padding: 3px;
+ font-weight: 300;
+ font-size: 11px;
+}
+
/* COLLABORATORS */
-.collaborators > div {
- width: 600px;
+.mediaDrawer .rap {
+ display: table;
+ width: 100%;
+ height: 100%;
+}
+
+.mediaDrawer .rap .holder .inner {
+ width: 480px;
margin: 0 auto;
text-align: left;
background: white;
padding: 10px;
margin: 20px auto;
+ position: relative;
}
+
.collaborators button {
width: auto;
position: relative;
@@ -1930,15 +3151,16 @@ a[data-role="forgot-password"] {
background-color: black;
border-color: black;
}
-.collaborators p {
- margin: 20px 0;
+.mediaDrawer .rap p {
+ margin: 10px 0 20px;
+ font-weight: 300;
}
.collaborators form input[type=text] {
font-size: 16px;
width: 300px;
}
-.collaborators h2 {
- margin: 20px auto 10px;
+.mediaDrawer .rap h2 {
+ margin: 20px auto 0;
}
#collaborator-list {
margin-top: 20px;
@@ -1954,6 +3176,7 @@ a[data-role="forgot-password"] {
background-size: cover;
display: inline-block;
margin-right: 10px;
+ background-color: #ccc;
}
#collaborator-list .username {
position: relative;
@@ -1972,6 +3195,62 @@ a[data-role="forgot-password"] {
font-weight: 300;
font-style: italic;
}
+#collaborator-url-rapper {
+ display: none;
+ background: #fff;
+ border: 1px solid;
+ box-shadow: -3px 3px 0;
+ padding: 10px;
+ font-weight: 300;
+ font-size: 14px;
+ margin: 10px 0;
+}
+#collaborator-url {
+ font-size: 16px;
+ width: 500px;
+ border: 1px solid;
+ font-size: 14px;
+ padding: 5px;
+ font-weight: 300;
+ margin-top: 5px;
+ display: block;
+}
+
+/* EMBED CODE GENERATOR */
+
+.embedView {
+ font-weight: 300;
+}
+.embedView textarea {
+ border: 1px solid black;
+ width: 100%;
+ height: 100px;
+ font-family: 'Menlo', 'Monaco', 'Lucida Sans Console', monospace;
+ padding: 5px;
+ line-height: 15px;
+}
+.embedView input[type=text] {
+ border: 1px solid black;
+ width: 40px;
+ padding: 2px;
+ font-size: 14px;
+ margin: 5px;
+}
+.embedView label {
+ font-size: 14px;
+ padding: 0 3px;
+}
+#testEmbed {
+ cursor: pointer;
+ float: right;
+ font-size: 11px;
+ margin-top: 11px;
+ font-weight: 100;
+ color: #888;
+}
+#testEmbed:hover {
+ text-decoration: underline;
+}
/* MARCHING ANTS ANIMATION */
@@ -1991,3 +3270,401 @@ a[data-role="forgot-password"] {
0%{height:250px;}
100%{height:500px;top:2px;}
}
+
+
+#threesixty {
+ display:none;
+ width:80px;
+ z-index: 3;
+ position: fixed;
+ bottom: 0;
+ right: 0;
+ pointer-events:none;
+}
+
+
+/* blueprint upload box */
+
+.blueprintUploader {
+ -webkit-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ width: 340px;
+ position: absolute;
+ top: 50%; left: 50%;
+ background: white;
+ padding: 10px;
+ border: 1px solid black;
+ box-shadow: -3px 3px #000;
+ -webkit-transform: translate3D(0%,-200%,0);
+ transform: translate3D(0%,-200%,0);
+ margin-left: -175px;
+ margin-top: -200px;
+ opacity: 0;
+}
+.blueprintUploader.active {
+ -webkit-transform: translate3D(0,0,0);
+ transform: translate3D(0,0,0);
+ opacity: 1;
+}
+.blueprintUploader .toolButton {
+ float: none;
+ width: 108px;
+ display: inline-block;
+}
+.blueprintUploader .url {
+ font-size: 15px;
+ border: 1px solid #888;
+ padding: 2px;
+ font-weight: 300;
+ position: relative;
+ top: 3px;
+ margin-right: 10px;
+ width: 190px;
+}
+.blueprintUploader p {
+ font-weight: 300;
+ font-size: 13px;
+}
+.blueprintUploader .blueprints {
+ display: none;
+}
+.blueprintUploader .blueprints h5 {
+ width: 250px;
+ margin: 10px auto;
+ padding-top: 9px;
+}
+.blueprints .blueprint {
+ border: 2px solid black;
+ background: white;
+ padding: 0px;
+ position: relative;
+ display: inline-block;
+ margin: 0 2px;
+}
+.blueprints .blueprint img {
+ height: 100px;
+ max-width: 200px;
+ display: block;
+ cursor: pointer;
+}
+.blueprints .blueprint .remove {
+ box-shadow: -2px 2px #000;
+ cursor: pointer;
+ position: absolute;
+ color: red;
+ top: 7px;
+ right: 7px;
+ width: 20px; height: 20px;
+ text-align: center;
+ background: #fff;
+ border: 1px solid black;
+}
+.blueprints .blueprint .remove span {
+ position: relative;
+ top: -2px;
+}
+.blueprintUploader .wallpaperUpload .upload-icon {
+ margin: 0 4px;
+}
+.uploadNewBlueprint {
+ color: #333;
+ border-bottom: 1px solid;
+ cursor: pointer;
+}
+
+
+[data-role="create-new-blueprint"] {
+ margin-bottom: 10px;
+}
+.openScaler {
+ margin-left: 10px;
+ border-bottom: 1px solid;
+ cursor: pointer;
+}
+
+/* KEYBOARD SHORTCUTS */
+
+.keyboard { float: left; width: 50%; margin-top: 50px; }
+.keyboard tr { margin: 0; padding: 0; }
+.keyboard td { padding: 2px 10px; margin: 0; }
+.keyboard.first-keyboard td:nth-child(1) { text-align: center; width: 50px; padding-left: 100px; }
+.keyboard td:nth-child(1) { text-align: right; width: 150px; }
+.keyboard td:nth-child(2) { font-weight: 300; }
+
+/* MOBILE */
+
+
+@media (max-width: 680px) {
+ .logo {
+ padding: 0px 4px 0px 8px;
+ }
+ .logo svg {
+ width: 70px;
+ height: 37px;
+ }
+ .video {
+ width: 100%!important;
+ height: auto!important;
+ }
+ .video iframe {
+ width: 100%!important;
+ height: auto!important;
+ margin-top: 0!important;
+ }
+ .topLinks a {
+ padding: 12px 8px;
+ color: black;
+ font-weight: 400;
+ float: left;
+ text-decoration: none;
+ font-size: 14px;
+ }
+
+ .topLinks a[data-role="new-project-modal"], .topLinks a[data-role="show-layouts-modal"] {
+ display:none;
+ }
+ .close {
+ font-size: 40px;
+ right: 10px;
+ top: 10px;
+ width: 55px;
+ line-height: 55px;
+ }
+ .facebook b {
+ font-size: 40px;
+ }
+ .facebook span {
+ line-height: 20px;
+ }
+ form {
+ max-width: 90%;
+
+ }
+
+ form li {
+ font-size: 16px;
+ }
+ form input[type="text"],form input[type="password"],form input[type="number"] {
+ font-size: 15px;
+ }
+ .page h1 {
+ font-size: 26px;
+ padding: 10px 0 15px 0;
+ font-weight: 300;
+ border-top: 1px solid;
+ }
+ .hero {
+ height: 450px;
+ margin-top: 41px;
+ }
+ .page .profilepage {
+ margin-top: 41px;
+ }
+ .profilepage .bio {
+ height: 180px;
+ width: 50%;
+ display: inline-block;
+ padding-top: 40px;
+ }
+
+ .profilePic {
+ width: 50%;
+ height: 180px;
+ }
+ .profilepage .about h2 {
+ display:none;
+ }
+ .profilepage .projectList.about:after {
+ content:"In order to create a room in VValls you need to use a desktop or laptop computer.. Its totally worth though!";
+ margin:20px 0 10px 0;
+ font-size:22px;
+ display:inline-block;
+ width:100%;
+ padding:10px;
+ line-height: 34px;
+ }
+ .bio .holder {
+ display: inline-block;
+ }
+ .page .projectList label {
+ font-weight:600;
+ border:0;
+ }
+ .projectList.about {
+ text-align: center;
+ padding: 0px 0;
+ }
+ .projectList.about .item .rap {
+ padding: 0;
+ }
+ .projectList.about .item span h3 {
+ font-weight: 500;
+ font-size: 18px;
+ margin-bottom: 6px;
+ }
+ .projectList.about .item:nth-child(2) span:nth-child(2) {
+ padding: 10px 0;
+ }
+ .projectList.about .item span:nth-child(1) {
+ width: 100%;
+ border-radius: 0;
+ height: 160px;
+ }
+ .projectList.about .item span:nth-child(2) {
+ width: 100%;
+ padding: 10px 0;
+ }
+ .projectList.about .item:nth-child(2) {
+ padding: 50px 0;
+ }
+ .page .viewMore.btn {
+ text-decoration: none;
+ font-size: 18px;
+ padding: 18px 0;
+ }
+ .footer a, .footer span {
+ margin: 4px;
+ }
+ #keyhint {
+ display:none;
+ }
+ .projectList .projectItem {
+ width:100%;
+ margin: 20px 0;
+ }
+ .projectList .room {
+ width: 100%;
+ height:230px;
+ height: 69vw;
+ margin: 0;
+ }
+ .mediaDrawer form h2 {
+ margin-bottom: 26px;
+ width: 100%;
+ text-align: left;
+ }
+ .aboutRoom.vvbox {
+ width: 170px;
+ padding: 6px 8px 8px 8px;
+ box-shadow: 0 0;
+ bottom: 3px;
+ left: 3px;
+ }
+ .aboutRoom .profilePic {
+ display:none;
+ }
+ .aboutRoom h2 {
+ font-size: 13px;
+ margin: 1px 0 0 0;
+ }
+ .btn.marg.warn {
+ display:none;
+ }
+ .aboutRoom h1 a, .aboutRoom h1 {
+ font-size: 16px;
+ }
+ .footer {
+ padding:50px 0 120px 0;
+ }
+ .videoModal .ion-ios-close-empty {
+ right: 10px;
+ top: 20px;
+ }
+ .gopro span {
+ font-size: 16px;
+ width: 93%;
+ line-height: 22px;
+ text-align: justify;
+ }
+ .gopro span a{
+ margin-top: 20px;
+ }
+ .greenbtn.learn {
+ display:none;
+ }
+ .reader .topLinks a {
+ display:none;
+ }
+ .reader iframe {
+ display:none;
+ }
+
+}
+
+.mobile .btn.marg, .mobile #share_embed {
+ display:none;
+}
+
+@media screen and (orientation:portrait) {
+ .mobile .aboutRoom {
+ display:none;
+ }
+ .mobile .mx-scene{
+ display:none;
+ }
+ .mobile #scene:after{
+ content: "To view this room, flip your device sideways and spin around in circles :)";
+ z-index: 3;
+ position: fixed;
+ display: inline-block;
+ width: 100%;
+ top: 75px;
+ left: 0;
+ font-size: 27px;
+ font-weight: 300;
+ line-height: 50px;
+ border-top: 1px solid;
+ border-bottom: 1px solid;
+ padding: 20px 7px;
+ }
+}
+
+
+@media screen and (orientation:landscape) and (max-width: 680px){
+ .projectList.about .item span:nth-child(1) {
+ height: 180px;
+ }
+ .projectList .projectItem {
+ width: 55%;
+ }
+ #threesixty {
+ display:inline;
+ }
+}
+
+@media screen and (orientation:landscape) {
+ .mobile #threesixty {
+ display:inline;
+ }
+}
+
+@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (-webkit-min-device-pixel-ratio: 1) {
+ .hero{
+ height: 500pt;
+ }
+ #keyhint {
+ display:none;
+ }
+ .topLinks a[data-role="new-project-modal"], .topLinks a[data-role="show-layouts-modal"] {
+ display:none;
+ }
+}
+
+
+@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (-webkit-min-device-pixel-ratio: 2) {
+ .hero{
+ height: 500pt;
+ }
+ #keyhint {
+ display:none;
+ }
+ .topLinks a[data-role="new-project-modal"], .topLinks a[data-role="show-layouts-modal"] {
+ display:none;
+ }
+}
+
+@media (max-height: 650px) {
+ .settings {
+ right: 80px;
+ }
+} \ No newline at end of file
diff --git a/public/assets/stylesheets/chardinjs.css b/public/assets/stylesheets/chardinjs.css
new file mode 100755
index 0000000..15334cf
--- /dev/null
+++ b/public/assets/stylesheets/chardinjs.css
@@ -0,0 +1,83 @@
+.chardinjs-overlay {
+ position: absolute;
+ z-index: 999999;
+ background-color: #000;
+ opacity: 0;
+ -webkit-transition: all 0.3s ease-out;
+ -moz-transition: all 0.3s ease-out;
+ -ms-transition: all 0.3s ease-out;
+ -o-transition: all 0.3s ease-out;
+ transition: all 0.3s ease-out; }
+
+.chardinjs-helper-layer {
+ position: absolute;
+ z-index: 9999998;
+ color: white;
+ -webkit-transition: all 0.3s ease-out;
+ -moz-transition: all 0.3s ease-out;
+ -ms-transition: all 0.3s ease-out;
+ -o-transition: all 0.3s ease-out;
+ transition: all 0.3s ease-out; }
+ .chardinjs-helper-layer.chardinjs-left {
+ border-left: solid white 1px;
+ margin-left: -10px; }
+ .chardinjs-helper-layer.chardinjs-right {
+ border-right: solid white 1px;
+ padding-right: 10px; }
+ .chardinjs-helper-layer.chardinjs-bottom {
+ border-bottom: solid white 1px;
+ padding-bottom: 10px; }
+ .chardinjs-helper-layer.chardinjs-top {
+ border-top: solid white 1px;
+ padding-top: 10px; }
+
+.chardinjs-tooltip {
+ position: absolute;
+ -webkit-transition: opacity 0.1s ease-out;
+ -moz-transition: opacity 0.1s ease-out;
+ -ms-transition: opacity 0.1s ease-out;
+ -o-transition: opacity 0.1s ease-out;
+ transition: opacity 0.1s ease-out;
+ max-width: 200px; }
+ .chardinjs-tooltip.chardinjs-left {
+ margin-left: -135px;
+ padding-right: 10px; }
+ .chardinjs-tooltip.chardinjs-right {
+ margin-right: -135px;
+ padding-left: 10px; }
+ .chardinjs-tooltip.chardinjs-bottom {
+ margin-bottom: -50px;
+ padding-top: 10px; }
+ .chardinjs-tooltip.chardinjs-top {
+ margin-top: -50px;
+ padding-bottom: 10px; }
+ .chardinjs-tooltip.chardinjs-right:before, .chardinjs-tooltip.chardinjs-left:after, .chardinjs-tooltip.chardinjs-bottom:before, .chardinjs-tooltip.chardinjs-top:after {
+ content: ".";
+ display: inline-block;
+ background-color: white;
+ height: 1px;
+ overflow: hidden;
+ position: absolute; }
+ .chardinjs-tooltip.chardinjs-right:before, .chardinjs-tooltip.chardinjs-left:after {
+ width: 100px;
+ top: 50%; }
+ .chardinjs-tooltip.chardinjs-bottom:before, .chardinjs-tooltip.chardinjs-top:after {
+ width: 1px;
+ height: 50px;
+ left: 50%; }
+ .chardinjs-tooltip.chardinjs-bottom:before {
+ top: -50px; }
+ .chardinjs-tooltip.chardinjs-top:after {
+ bottom: -50px; }
+ .chardinjs-tooltip.chardinjs-right:before {
+ left: -100px; }
+ .chardinjs-tooltip.chardinjs-left:after {
+ right: -100px; }
+
+.chardinjs-show-element {
+ z-index: 9999999;
+ opacity: 0.8; }
+/*
+.chardinjs-relative-position {
+ position: relative; }
+*/ \ No newline at end of file
diff --git a/public/assets/stylesheets/ionicons.css b/public/assets/stylesheets/ionicons.css
index 0d8af36..885aa6b 100755
--- a/public/assets/stylesheets/ionicons.css
+++ b/public/assets/stylesheets/ionicons.css
@@ -1,1335 +1,1480 @@
-@font-face {
- font-family: 'ionicons';
- src:url('../fonts/ionicons.eot');
- src:url('../fonts/ionicons.eot?#iefix') format('embedded-opentype'),
- url('../fonts/ionicons.ttf') format('truetype'),
- url('../fonts/ionicons.woff') format('woff'),
- url('../fonts/ionicons.svg#icomoon') format('svg');
- font-weight: normal;
- font-style: normal;
-}
+@charset "UTF-8";
+/*!
+ Ionicons, v2.0.0
+ Created by Ben Sperry for the Ionic Framework, http://ionicons.com/
+ https://twitter.com/benjsperry https://twitter.com/ionicframework
+ MIT License: https://github.com/driftyco/ionicons
-[class*="icon-"] {
- font-family: 'ionicons';
- speak: none;
- font-style: normal;
- font-weight: normal;
- font-variant: normal;
- text-transform: none;
- line-height: 1;
+ Android-style icons originally built by Google’s
+ Material Design Icons: https://github.com/google/material-design-icons
+ used under CC BY http://creativecommons.org/licenses/by/4.0/
+ Modified icons to fit ionicon’s grid from original.
+*/
+@font-face { font-family: "Ionicons"; src: url("../fonts/ionicons.eot?v=2.0.0"); src: url("../fonts/ionicons.eot?v=2.0.0#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=2.0.0") format("truetype"), url("../fonts/ionicons.woff?v=2.0.0") format("woff"), url("../fonts/ionicons.svg?v=2.0.0#Ionicons") format("svg"); font-weight: normal; font-style: normal; }
+.ion, .ionicons, .ion-alert:before, .ion-alert-circled:before, .ion-android-add:before, .ion-android-add-circle:before, .ion-android-alarm-clock:before, .ion-android-alert:before, .ion-android-apps:before, .ion-android-archive:before, .ion-android-arrow-back:before, .ion-android-arrow-down:before, .ion-android-arrow-dropdown:before, .ion-android-arrow-dropdown-circle:before, .ion-android-arrow-dropleft:before, .ion-android-arrow-dropleft-circle:before, .ion-android-arrow-dropright:before, .ion-android-arrow-dropright-circle:before, .ion-android-arrow-dropup:before, .ion-android-arrow-dropup-circle:before, .ion-android-arrow-forward:before, .ion-android-arrow-up:before, .ion-android-attach:before, .ion-android-bar:before, .ion-android-bicycle:before, .ion-android-boat:before, .ion-android-bookmark:before, .ion-android-bulb:before, .ion-android-bus:before, .ion-android-calendar:before, .ion-android-call:before, .ion-android-camera:before, .ion-android-cancel:before, .ion-android-car:before, .ion-android-cart:before, .ion-android-chat:before, .ion-android-checkbox:before, .ion-android-checkbox-blank:before, .ion-android-checkbox-outline:before, .ion-android-checkbox-outline-blank:before, .ion-android-checkmark-circle:before, .ion-android-clipboard:before, .ion-android-close:before, .ion-android-cloud:before, .ion-android-cloud-circle:before, .ion-android-cloud-done:before, .ion-android-cloud-outline:before, .ion-android-color-palette:before, .ion-android-compass:before, .ion-android-contact:before, .ion-android-contacts:before, .ion-android-contract:before, .ion-android-create:before, .ion-android-delete:before, .ion-android-desktop:before, .ion-android-document:before, .ion-android-done:before, .ion-android-done-all:before, .ion-android-download:before, .ion-android-drafts:before, .ion-android-exit:before, .ion-android-expand:before, .ion-android-favorite:before, .ion-android-favorite-outline:before, .ion-android-film:before, .ion-android-folder:before, .ion-android-folder-open:before, .ion-android-funnel:before, .ion-android-globe:before, .ion-android-hand:before, .ion-android-hangout:before, .ion-android-happy:before, .ion-android-home:before, .ion-android-image:before, .ion-android-laptop:before, .ion-android-list:before, .ion-android-locate:before, .ion-android-lock:before, .ion-android-mail:before, .ion-android-map:before, .ion-android-menu:before, .ion-android-microphone:before, .ion-android-microphone-off:before, .ion-android-more-horizontal:before, .ion-android-more-vertical:before, .ion-android-navigate:before, .ion-android-notifications:before, .ion-android-notifications-none:before, .ion-android-notifications-off:before, .ion-android-open:before, .ion-android-options:before, .ion-android-people:before, .ion-android-person:before, .ion-android-person-add:before, .ion-android-phone-landscape:before, .ion-android-phone-portrait:before, .ion-android-pin:before, .ion-android-plane:before, .ion-android-playstore:before, .ion-android-print:before, .ion-android-radio-button-off:before, .ion-android-radio-button-on:before, .ion-android-refresh:before, .ion-android-remove:before, .ion-android-remove-circle:before, .ion-android-restaurant:before, .ion-android-sad:before, .ion-android-search:before, .ion-android-send:before, .ion-android-settings:before, .ion-android-share:before, .ion-android-share-alt:before, .ion-android-star:before, .ion-android-star-half:before, .ion-android-star-outline:before, .ion-android-stopwatch:before, .ion-android-subway:before, .ion-android-sunny:before, .ion-android-sync:before, .ion-android-textsms:before, .ion-android-time:before, .ion-android-train:before, .ion-android-unlock:before, .ion-android-upload:before, .ion-android-volume-down:before, .ion-android-volume-mute:before, .ion-android-volume-off:before, .ion-android-volume-up:before, .ion-android-walk:before, .ion-android-warning:before, .ion-android-watch:before, .ion-android-wifi:before, .ion-aperture:before, .ion-archive:before, .ion-arrow-down-a:before, .ion-arrow-down-b:before, .ion-arrow-down-c:before, .ion-arrow-expand:before, .ion-arrow-graph-down-left:before, .ion-arrow-graph-down-right:before, .ion-arrow-graph-up-left:before, .ion-arrow-graph-up-right:before, .ion-arrow-left-a:before, .ion-arrow-left-b:before, .ion-arrow-left-c:before, .ion-arrow-move:before, .ion-arrow-resize:before, .ion-arrow-return-left:before, .ion-arrow-return-right:before, .ion-arrow-right-a:before, .ion-arrow-right-b:before, .ion-arrow-right-c:before, .ion-arrow-shrink:before, .ion-arrow-swap:before, .ion-arrow-up-a:before, .ion-arrow-up-b:before, .ion-arrow-up-c:before, .ion-asterisk:before, .ion-at:before, .ion-backspace:before, .ion-backspace-outline:before, .ion-bag:before, .ion-battery-charging:before, .ion-battery-empty:before, .ion-battery-full:before, .ion-battery-half:before, .ion-battery-low:before, .ion-beaker:before, .ion-beer:before, .ion-bluetooth:before, .ion-bonfire:before, .ion-bookmark:before, .ion-bowtie:before, .ion-briefcase:before, .ion-bug:before, .ion-calculator:before, .ion-calendar:before, .ion-camera:before, .ion-card:before, .ion-cash:before, .ion-chatbox:before, .ion-chatbox-working:before, .ion-chatboxes:before, .ion-chatbubble:before, .ion-chatbubble-working:before, .ion-chatbubbles:before, .ion-checkmark:before, .ion-checkmark-circled:before, .ion-checkmark-round:before, .ion-chevron-down:before, .ion-chevron-left:before, .ion-chevron-right:before, .ion-chevron-up:before, .ion-clipboard:before, .ion-clock:before, .ion-close:before, .ion-close-circled:before, .ion-close-round:before, .ion-closed-captioning:before, .ion-cloud:before, .ion-code:before, .ion-code-download:before, .ion-code-working:before, .ion-coffee:before, .ion-compass:before, .ion-compose:before, .ion-connection-bars:before, .ion-contrast:before, .ion-crop:before, .ion-cube:before, .ion-disc:before, .ion-document:before, .ion-document-text:before, .ion-drag:before, .ion-earth:before, .ion-easel:before, .ion-edit:before, .ion-egg:before, .ion-eject:before, .ion-email:before, .ion-email-unread:before, .ion-erlenmeyer-flask:before, .ion-erlenmeyer-flask-bubbles:before, .ion-eye:before, .ion-eye-disabled:before, .ion-female:before, .ion-filing:before, .ion-film-marker:before, .ion-fireball:before, .ion-flag:before, .ion-flame:before, .ion-flash:before, .ion-flash-off:before, .ion-folder:before, .ion-fork:before, .ion-fork-repo:before, .ion-forward:before, .ion-funnel:before, .ion-gear-a:before, .ion-gear-b:before, .ion-grid:before, .ion-hammer:before, .ion-happy:before, .ion-happy-outline:before, .ion-headphone:before, .ion-heart:before, .ion-heart-broken:before, .ion-help:before, .ion-help-buoy:before, .ion-help-circled:before, .ion-home:before, .ion-icecream:before, .ion-image:before, .ion-images:before, .ion-information:before, .ion-information-circled:before, .ion-ionic:before, .ion-ios-alarm:before, .ion-ios-alarm-outline:before, .ion-ios-albums:before, .ion-ios-albums-outline:before, .ion-ios-americanfootball:before, .ion-ios-americanfootball-outline:before, .ion-ios-analytics:before, .ion-ios-analytics-outline:before, .ion-ios-arrow-back:before, .ion-ios-arrow-down:before, .ion-ios-arrow-forward:before, .ion-ios-arrow-left:before, .ion-ios-arrow-right:before, .ion-ios-arrow-thin-down:before, .ion-ios-arrow-thin-left:before, .ion-ios-arrow-thin-right:before, .ion-ios-arrow-thin-up:before, .ion-ios-arrow-up:before, .ion-ios-at:before, .ion-ios-at-outline:before, .ion-ios-barcode:before, .ion-ios-barcode-outline:before, .ion-ios-baseball:before, .ion-ios-baseball-outline:before, .ion-ios-basketball:before, .ion-ios-basketball-outline:before, .ion-ios-bell:before, .ion-ios-bell-outline:before, .ion-ios-body:before, .ion-ios-body-outline:before, .ion-ios-bolt:before, .ion-ios-bolt-outline:before, .ion-ios-book:before, .ion-ios-book-outline:before, .ion-ios-bookmarks:before, .ion-ios-bookmarks-outline:before, .ion-ios-box:before, .ion-ios-box-outline:before, .ion-ios-briefcase:before, .ion-ios-briefcase-outline:before, .ion-ios-browsers:before, .ion-ios-browsers-outline:before, .ion-ios-calculator:before, .ion-ios-calculator-outline:before, .ion-ios-calendar:before, .ion-ios-calendar-outline:before, .ion-ios-camera:before, .ion-ios-camera-outline:before, .ion-ios-cart:before, .ion-ios-cart-outline:before, .ion-ios-chatboxes:before, .ion-ios-chatboxes-outline:before, .ion-ios-chatbubble:before, .ion-ios-chatbubble-outline:before, .ion-ios-checkmark:before, .ion-ios-checkmark-empty:before, .ion-ios-checkmark-outline:before, .ion-ios-circle-filled:before, .ion-ios-circle-outline:before, .ion-ios-clock:before, .ion-ios-clock-outline:before, .ion-ios-close:before, .ion-ios-close-empty:before, .ion-ios-close-outline:before, .ion-ios-cloud:before, .ion-ios-cloud-download:before, .ion-ios-cloud-download-outline:before, .ion-ios-cloud-outline:before, .ion-ios-cloud-upload:before, .ion-ios-cloud-upload-outline:before, .ion-ios-cloudy:before, .ion-ios-cloudy-night:before, .ion-ios-cloudy-night-outline:before, .ion-ios-cloudy-outline:before, .ion-ios-cog:before, .ion-ios-cog-outline:before, .ion-ios-color-filter:before, .ion-ios-color-filter-outline:before, .ion-ios-color-wand:before, .ion-ios-color-wand-outline:before, .ion-ios-compose:before, .ion-ios-compose-outline:before, .ion-ios-contact:before, .ion-ios-contact-outline:before, .ion-ios-copy:before, .ion-ios-copy-outline:before, .ion-ios-crop:before, .ion-ios-crop-strong:before, .ion-ios-download:before, .ion-ios-download-outline:before, .ion-ios-drag:before, .ion-ios-email:before, .ion-ios-email-outline:before, .ion-ios-eye:before, .ion-ios-eye-outline:before, .ion-ios-fastforward:before, .ion-ios-fastforward-outline:before, .ion-ios-filing:before, .ion-ios-filing-outline:before, .ion-ios-film:before, .ion-ios-film-outline:before, .ion-ios-flag:before, .ion-ios-flag-outline:before, .ion-ios-flame:before, .ion-ios-flame-outline:before, .ion-ios-flask:before, .ion-ios-flask-outline:before, .ion-ios-flower:before, .ion-ios-flower-outline:before, .ion-ios-folder:before, .ion-ios-folder-outline:before, .ion-ios-football:before, .ion-ios-football-outline:before, .ion-ios-game-controller-a:before, .ion-ios-game-controller-a-outline:before, .ion-ios-game-controller-b:before, .ion-ios-game-controller-b-outline:before, .ion-ios-gear:before, .ion-ios-gear-outline:before, .ion-ios-glasses:before, .ion-ios-glasses-outline:before, .ion-ios-grid-view:before, .ion-ios-grid-view-outline:before, .ion-ios-heart:before, .ion-ios-heart-outline:before, .ion-ios-help:before, .ion-ios-help-empty:before, .ion-ios-help-outline:before, .ion-ios-home:before, .ion-ios-home-outline:before, .ion-ios-infinite:before, .ion-ios-infinite-outline:before, .ion-ios-information:before, .ion-ios-information-empty:before, .ion-ios-information-outline:before, .ion-ios-ionic-outline:before, .ion-ios-keypad:before, .ion-ios-keypad-outline:before, .ion-ios-lightbulb:before, .ion-ios-lightbulb-outline:before, .ion-ios-list:before, .ion-ios-list-outline:before, .ion-ios-location:before, .ion-ios-location-outline:before, .ion-ios-locked:before, .ion-ios-locked-outline:before, .ion-ios-loop:before, .ion-ios-loop-strong:before, .ion-ios-medical:before, .ion-ios-medical-outline:before, .ion-ios-medkit:before, .ion-ios-medkit-outline:before, .ion-ios-mic:before, .ion-ios-mic-off:before, .ion-ios-mic-outline:before, .ion-ios-minus:before, .ion-ios-minus-empty:before, .ion-ios-minus-outline:before, .ion-ios-monitor:before, .ion-ios-monitor-outline:before, .ion-ios-moon:before, .ion-ios-moon-outline:before, .ion-ios-more:before, .ion-ios-more-outline:before, .ion-ios-musical-note:before, .ion-ios-musical-notes:before, .ion-ios-navigate:before, .ion-ios-navigate-outline:before, .ion-ios-nutrition:before, .ion-ios-nutrition-outline:before, .ion-ios-paper:before, .ion-ios-paper-outline:before, .ion-ios-paperplane:before, .ion-ios-paperplane-outline:before, .ion-ios-partlysunny:before, .ion-ios-partlysunny-outline:before, .ion-ios-pause:before, .ion-ios-pause-outline:before, .ion-ios-paw:before, .ion-ios-paw-outline:before, .ion-ios-people:before, .ion-ios-people-outline:before, .ion-ios-person:before, .ion-ios-person-outline:before, .ion-ios-personadd:before, .ion-ios-personadd-outline:before, .ion-ios-photos:before, .ion-ios-photos-outline:before, .ion-ios-pie:before, .ion-ios-pie-outline:before, .ion-ios-pint:before, .ion-ios-pint-outline:before, .ion-ios-play:before, .ion-ios-play-outline:before, .ion-ios-plus:before, .ion-ios-plus-empty:before, .ion-ios-plus-outline:before, .ion-ios-pricetag:before, .ion-ios-pricetag-outline:before, .ion-ios-pricetags:before, .ion-ios-pricetags-outline:before, .ion-ios-printer:before, .ion-ios-printer-outline:before, .ion-ios-pulse:before, .ion-ios-pulse-strong:before, .ion-ios-rainy:before, .ion-ios-rainy-outline:before, .ion-ios-recording:before, .ion-ios-recording-outline:before, .ion-ios-redo:before, .ion-ios-redo-outline:before, .ion-ios-refresh:before, .ion-ios-refresh-empty:before, .ion-ios-refresh-outline:before, .ion-ios-reload:before, .ion-ios-reverse-camera:before, .ion-ios-reverse-camera-outline:before, .ion-ios-rewind:before, .ion-ios-rewind-outline:before, .ion-ios-rose:before, .ion-ios-rose-outline:before, .ion-ios-search:before, .ion-ios-search-strong:before, .ion-ios-settings:before, .ion-ios-settings-strong:before, .ion-ios-shuffle:before, .ion-ios-shuffle-strong:before, .ion-ios-skipbackward:before, .ion-ios-skipbackward-outline:before, .ion-ios-skipforward:before, .ion-ios-skipforward-outline:before, .ion-ios-snowy:before, .ion-ios-speedometer:before, .ion-ios-speedometer-outline:before, .ion-ios-star:before, .ion-ios-star-half:before, .ion-ios-star-outline:before, .ion-ios-stopwatch:before, .ion-ios-stopwatch-outline:before, .ion-ios-sunny:before, .ion-ios-sunny-outline:before, .ion-ios-telephone:before, .ion-ios-telephone-outline:before, .ion-ios-tennisball:before, .ion-ios-tennisball-outline:before, .ion-ios-thunderstorm:before, .ion-ios-thunderstorm-outline:before, .ion-ios-time:before, .ion-ios-time-outline:before, .ion-ios-timer:before, .ion-ios-timer-outline:before, .ion-ios-toggle:before, .ion-ios-toggle-outline:before, .ion-ios-trash:before, .ion-ios-trash-outline:before, .ion-ios-undo:before, .ion-ios-undo-outline:before, .ion-ios-unlocked:before, .ion-ios-unlocked-outline:before, .ion-ios-upload:before, .ion-ios-upload-outline:before, .ion-ios-videocam:before, .ion-ios-videocam-outline:before, .ion-ios-volume-high:before, .ion-ios-volume-low:before, .ion-ios-wineglass:before, .ion-ios-wineglass-outline:before, .ion-ios-world:before, .ion-ios-world-outline:before, .ion-ipad:before, .ion-iphone:before, .ion-ipod:before, .ion-jet:before, .ion-key:before, .ion-knife:before, .ion-laptop:before, .ion-leaf:before, .ion-levels:before, .ion-lightbulb:before, .ion-link:before, .ion-load-a:before, .ion-load-b:before, .ion-load-c:before, .ion-load-d:before, .ion-location:before, .ion-lock-combination:before, .ion-locked:before, .ion-log-in:before, .ion-log-out:before, .ion-loop:before, .ion-magnet:before, .ion-male:before, .ion-man:before, .ion-map:before, .ion-medkit:before, .ion-merge:before, .ion-mic-a:before, .ion-mic-b:before, .ion-mic-c:before, .ion-minus:before, .ion-minus-circled:before, .ion-minus-round:before, .ion-model-s:before, .ion-monitor:before, .ion-more:before, .ion-mouse:before, .ion-music-note:before, .ion-navicon:before, .ion-navicon-round:before, .ion-navigate:before, .ion-network:before, .ion-no-smoking:before, .ion-nuclear:before, .ion-outlet:before, .ion-paintbrush:before, .ion-paintbucket:before, .ion-paper-airplane:before, .ion-paperclip:before, .ion-pause:before, .ion-person:before, .ion-person-add:before, .ion-person-stalker:before, .ion-pie-graph:before, .ion-pin:before, .ion-pinpoint:before, .ion-pizza:before, .ion-plane:before, .ion-planet:before, .ion-play:before, .ion-playstation:before, .ion-plus:before, .ion-plus-circled:before, .ion-plus-round:before, .ion-podium:before, .ion-pound:before, .ion-power:before, .ion-pricetag:before, .ion-pricetags:before, .ion-printer:before, .ion-pull-request:before, .ion-qr-scanner:before, .ion-quote:before, .ion-radio-waves:before, .ion-record:before, .ion-refresh:before, .ion-reply:before, .ion-reply-all:before, .ion-ribbon-a:before, .ion-ribbon-b:before, .ion-sad:before, .ion-sad-outline:before, .ion-scissors:before, .ion-search:before, .ion-settings:before, .ion-share:before, .ion-shuffle:before, .ion-skip-backward:before, .ion-skip-forward:before, .ion-social-android:before, .ion-social-android-outline:before, .ion-social-angular:before, .ion-social-angular-outline:before, .ion-social-apple:before, .ion-social-apple-outline:before, .ion-social-bitcoin:before, .ion-social-bitcoin-outline:before, .ion-social-buffer:before, .ion-social-buffer-outline:before, .ion-social-chrome:before, .ion-social-chrome-outline:before, .ion-social-codepen:before, .ion-social-codepen-outline:before, .ion-social-css3:before, .ion-social-css3-outline:before, .ion-social-designernews:before, .ion-social-designernews-outline:before, .ion-social-dribbble:before, .ion-social-dribbble-outline:before, .ion-social-dropbox:before, .ion-social-dropbox-outline:before, .ion-social-euro:before, .ion-social-euro-outline:before, .ion-social-facebook:before, .ion-social-facebook-outline:before, .ion-social-foursquare:before, .ion-social-foursquare-outline:before, .ion-social-freebsd-devil:before, .ion-social-github:before, .ion-social-github-outline:before, .ion-social-google:before, .ion-social-google-outline:before, .ion-social-googleplus:before, .ion-social-googleplus-outline:before, .ion-social-hackernews:before, .ion-social-hackernews-outline:before, .ion-social-html5:before, .ion-social-html5-outline:before, .ion-social-instagram:before, .ion-social-instagram-outline:before, .ion-social-javascript:before, .ion-social-javascript-outline:before, .ion-social-linkedin:before, .ion-social-linkedin-outline:before, .ion-social-markdown:before, .ion-social-nodejs:before, .ion-social-octocat:before, .ion-social-pinterest:before, .ion-social-pinterest-outline:before, .ion-social-python:before, .ion-social-reddit:before, .ion-social-reddit-outline:before, .ion-social-rss:before, .ion-social-rss-outline:before, .ion-social-sass:before, .ion-social-skype:before, .ion-social-skype-outline:before, .ion-social-snapchat:before, .ion-social-snapchat-outline:before, .ion-social-tumblr:before, .ion-social-tumblr-outline:before, .ion-social-tux:before, .ion-social-twitch:before, .ion-social-twitch-outline:before, .ion-social-twitter:before, .ion-social-twitter-outline:before, .ion-social-usd:before, .ion-social-usd-outline:before, .ion-social-vimeo:before, .ion-social-vimeo-outline:before, .ion-social-whatsapp:before, .ion-social-whatsapp-outline:before, .ion-social-windows:before, .ion-social-windows-outline:before, .ion-social-wordpress:before, .ion-social-wordpress-outline:before, .ion-social-yahoo:before, .ion-social-yahoo-outline:before, .ion-social-yen:before, .ion-social-yen-outline:before, .ion-social-youtube:before, .ion-social-youtube-outline:before, .ion-soup-can:before, .ion-soup-can-outline:before, .ion-speakerphone:before, .ion-speedometer:before, .ion-spoon:before, .ion-star:before, .ion-stats-bars:before, .ion-steam:before, .ion-stop:before, .ion-thermometer:before, .ion-thumbsdown:before, .ion-thumbsup:before, .ion-toggle:before, .ion-toggle-filled:before, .ion-transgender:before, .ion-trash-a:before, .ion-trash-b:before, .ion-trophy:before, .ion-tshirt:before, .ion-tshirt-outline:before, .ion-umbrella:before, .ion-university:before, .ion-unlocked:before, .ion-upload:before, .ion-usb:before, .ion-videocamera:before, .ion-volume-high:before, .ion-volume-low:before, .ion-volume-medium:before, .ion-volume-mute:before, .ion-wand:before, .ion-waterdrop:before, .ion-wifi:before, .ion-wineglass:before, .ion-woman:before, .ion-wrench:before, .ion-xbox:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
- /* Better Font Rendering =========== */
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
+.ion-alert:before { content: "\f101"; }
-.icon-ios7-folder:before {
- content: "\e60c";
-}
-.icon-ios7-flag:before {
- content: "\e619";
-}
-.icon-ios7-partlysunny:before {
- content: "\e626";
-}
-.icon-ios7-personadd-outline:before {
- content: "\e633";
-}
-.icon-ios7-filing:before {
- content: "\e640";
-}
-.icon-ios7-heart-outline:before {
- content: "\e64d";
-}
-.icon-ios7-film-outline:before {
- content: "\e65a";
-}
-.icon-ios7-fastforward:before {
- content: "\e667";
-}
-.icon-ios7-cloud-download:before {
- content: "\e674";
-}
-.icon-ios7-plus-empty:before {
- content: "\e681";
-}
-.icon-ios7-plus:before {
- content: "\e682";
-}
-.icon-ios7-plus-outline:before {
- content: "\e683";
-}
-.icon-ios7-checkmark-empty:before {
- content: "\e684";
-}
-.icon-ios7-checkmark:before {
- content: "\e685";
-}
-.icon-ios7-checkmark-outline:before {
- content: "\e686";
-}
-.icon-ios7-help-empty:before {
- content: "\e687";
-}
-.icon-ios7-help:before {
- content: "\e688";
-}
-.icon-ios7-help-outline:before {
- content: "\e689";
-}
-.icon-ios7-information-empty:before {
- content: "\e68a";
-}
-.icon-ios7-information:before {
- content: "\e68b";
-}
-.icon-ios7-information-outline:before {
- content: "\e68c";
-}
-.icon-ios7-circle-filled:before {
- content: "\e68d";
-}
-.icon-ios7-circle-outline:before {
- content: "\e68e";
-}
-.icon-ios7-trash-outline:before {
- content: "\e68f";
-}
-.icon-ios7-more:before {
- content: "\e690";
-}
-.icon-ios7-more-outline:before {
- content: "\e691";
-}
-.icon-ios7-upload:before {
- content: "\e692";
-}
-.icon-ios7-upload-outline:before {
- content: "\e693";
-}
-.icon-ios7-download:before {
- content: "\e694";
-}
-.icon-ios7-download-outline:before {
- content: "\e695";
-}
-.icon-ios7-search-strong:before {
- content: "\e696";
-}
-.icon-ios7-search:before {
- content: "\e697";
-}
-.icon-ios7-navigate:before {
- content: "\e698";
-}
-.icon-ios7-navigate-outline:before {
- content: "\e699";
-}
-.icon-ios7-copy:before {
- content: "\e69a";
-}
-.icon-ios7-copy-outline:before {
- content: "\e69b";
-}
-.icon-ios7-photos:before {
- content: "\e69c";
-}
-.icon-ios7-photos-outline:before {
- content: "\e69d";
-}
-.icon-ios7-albums:before {
- content: "\e69e";
-}
-.icon-ios7-albums-outline:before {
- content: "\e69f";
-}
-.icon-ios7-world:before {
- content: "\e6a0";
-}
-.icon-ios7-world-outline:before {
- content: "\e6a1";
-}
-.icon-ios7-recording:before {
- content: "\e6a2";
-}
-.icon-ios7-recording-outline:before {
- content: "\e6a3";
-}
-.icon-ios7-keypad:before {
- content: "\e6a4";
-}
-.icon-ios7-keypad-outline:before {
- content: "\e6a5";
-}
-.icon-ios7-contact:before {
- content: "\e6a6";
-}
-.icon-ios7-contact-outline:before {
- content: "\e6a7";
-}
-.icon-ios7-clock:before {
- content: "\e6a8";
-}
-.icon-ios7-clock-outline:before {
- content: "\e6a9";
-}
-.icon-ios7-star:before {
- content: "\e6aa";
-}
-.icon-ios7-star-outline:before {
- content: "\e6ab";
-}
-.icon-ios7-compose-outline:before {
- content: "\e6ac";
-}
-.icon-ios7-wineglass:before {
- content: "\e6ad";
-}
-.icon-ios7-pie:before {
- content: "\e6ae";
-}
-.icon-ios7-pie-outline:before {
- content: "\e6af";
-}
-.icon-ios7-reload:before {
- content: "\e6b0";
-}
-.icon-ios7-wineglass-outline:before {
- content: "\e6b1";
-}
-.icon-ios7-medkit:before {
- content: "\e6b2";
-}
-.icon-ios7-medkit-outline:before {
- content: "\e6b3";
-}
-.icon-ios7-briefcase-outline:before {
- content: "\e6b4";
-}
-.icon-ios7-briefcase:before {
- content: "\e6b5";
-}
-.icon-ios7-pricetag:before {
- content: "\e6b6";
-}
-.icon-ios7-pricetag-outline:before {
- content: "\e6b7";
-}
-.icon-ios7-speedometer:before {
- content: "\e6b8";
-}
-.icon-ios7-speedometer-outline:before {
- content: "\e6b9";
-}
-.icon-ios7-lightbulb:before {
- content: "\e6ba";
-}
-.icon-ios7-lightbulb-outline:before {
- content: "\e6bb";
-}
-.icon-ios7-calculator:before {
- content: "\e6bc";
-}
-.icon-ios7-calculator-outline:before {
- content: "\e6bd";
-}
-.icon-ios7-arrow-thin-left:before {
- content: "\e6be";
-}
-.icon-ios7-arrow-thin-down:before {
- content: "\e6bf";
-}
-.icon-ios7-arrow-thin-right:before {
- content: "\e6c0";
-}
-.icon-ios7-arrow-thin-up:before {
- content: "\e6c1";
-}
-.icon-ios7-time:before {
- content: "\e6c2";
-}
-.icon-ios7-time-outline:before {
- content: "\e6c3";
-}
-.icon-volume-mute:before {
- content: "\e6c4";
-}
-.icon-thumbsdown:before {
- content: "\e6c5";
-}
-.icon-thumbsup:before {
- content: "\e6c6";
-}
-.icon-calendar:before {
- content: "\e6c7";
-}
-.icon-images:before {
- content: "\e6c8";
-}
-.icon-film-marker:before {
- content: "\e6c9";
-}
-.icon-game-controller-b:before {
- content: "\e6ca";
-}
-.icon-game-controller-a:before {
- content: "\e6cb";
-}
-.icon-man:before {
- content: "\e6cc";
-}
-.icon-archive:before {
- content: "\e6cd";
-}
-.icon-trash-b:before {
- content: "\e6ce";
-}
-.icon-trash-a:before {
- content: "\e6cf";
-}
-.icon-folder:before {
- content: "\e6d0";
-}
-.icon-alert-circled:before {
- content: "\e6d1";
-}
-.icon-information-circled:before {
- content: "\e6d2";
-}
-.icon-minus-circled:before {
- content: "\e6d3";
-}
-.icon-plus-circled:before {
- content: "\e6d4";
-}
-.icon-link:before {
- content: "\e6d5";
-}
-.icon-eject:before {
- content: "\e6d6";
-}
-.icon-skip-backward:before {
- content: "\e6d7";
-}
-.icon-skip-forward:before {
- content: "\e6d8";
-}
-.icon-iphone:before {
- content: "\e6d9";
-}
-.icon-ipad:before {
- content: "\e6da";
-}
-.icon-ipod:before {
- content: "\e6db";
-}
-.icon-alert:before {
- content: "\e6dc";
-}
-.icon-arrow-right-a:before {
- content: "\e6dd";
-}
-.icon-arrow-up-a:before {
- content: "\e6de";
-}
-.icon-arrow-left-a:before {
- content: "\e6df";
-}
-.icon-arrow-down-a:before {
- content: "\e6e0";
-}
-.icon-ionic:before {
- content: "\e6e1";
-}
-.icon-plane:before {
- content: "\e6e2";
-}
-.icon-flask:before {
- content: "\e6e3";
-}
-.icon-card:before {
- content: "\e6e4";
-}
-.icon-bag:before {
- content: "\e6e5";
-}
-.icon-map:before {
- content: "\e6e6";
-}
-.icon-clipboard:before {
- content: "\e6e7";
-}
-.icon-pound:before {
- content: "\e6e8";
-}
-.icon-at:before {
- content: "\e6e9";
-}
-.icon-image:before {
- content: "\e6ea";
-}
-.icon-mic-c:before {
- content: "\e6eb";
-}
-.icon-mic-b:before {
- content: "\e6ec";
-}
-.icon-waterdrop:before {
- content: "\e6ed";
-}
-.icon-record:before {
- content: "\e6ee";
-}
-.icon-stop:before {
- content: "\e6ef";
-}
-.icon-pause:before {
- content: "\e6f0";
-}
-.icon-play:before {
- content: "\e6f1";
-}
-.icon-volume-low:before {
- content: "\e6f2";
-}
-.icon-volume-medium:before {
- content: "\e6f3";
-}
-.icon-volume-high:before {
- content: "\e6f4";
-}
-.icon-mic-a:before {
- content: "\e6f5";
-}
-.icon-music-note:before {
- content: "\e6f6";
-}
-.icon-headphone:before {
- content: "\e6f7";
-}
-.icon-disc:before {
- content: "\e6f8";
-}
-.icon-videocamera:before {
- content: "\e6f9";
-}
-.icon-printer:before {
- content: "\e6fa";
-}
-.icon-laptop:before {
- content: "\e6fb";
-}
-.icon-monitor:before {
- content: "\e6fc";
-}
-.icon-flash-off:before {
- content: "\e6fd";
-}
-.icon-flash:before {
- content: "\e6fe";
-}
-.icon-eye:before {
- content: "\e6ff";
-}
-.icon-camera:before {
- content: "\e700";
-}
-.icon-bluetooth:before {
- content: "\e701";
-}
-.icon-wifi:before {
- content: "\e702";
-}
-.icon-battery-charging:before {
- content: "\e703";
-}
-.icon-battery-empty:before {
- content: "\e704";
-}
-.icon-battery-low:before {
- content: "\e705";
-}
-.icon-battery-half:before {
- content: "\e706";
-}
-.icon-battery-full:before {
- content: "\e707";
-}
-.icon-woman:before {
- content: "\e708";
-}
-.icon-person-stalker:before {
- content: "\e709";
-}
-.icon-person-add:before {
- content: "\e70a";
-}
-.icon-person:before {
- content: "\e70b";
-}
-.icon-chatboxes:before {
-}
-.icon-chatbox-working:before {
- content: "\e70d";
-}
-.icon-chatbox:before {
- content: "\e70e";
-}
-.icon-chatbubbles:before {
- content: "\e70f";
-}
-.icon-chatbubble-working:before {
- content: "\e710";
-}
-.icon-chatbubble:before {
- content: "\e711";
-}
-.icon-unlocked:before {
- content: "\e712";
-}
-.icon-locked:before {
- content: "\e713";
-}
-.icon-more:before {
- content: "\e714";
-}
-.icon-grid:before {
- content: "\e715";
-}
-.icon-upload:before {
- content: "\e716";
-}
-.icon-cloud:before {
- content: "\e717";
-}
-.icon-location:before {
- content: "\e718";
-}
-.icon-compose:before {
- content: "\e719";
-}
-.icon-paperclip:before {
- content: "\e71a";
-}
-.icon-share:before {
- content: "\e71b";
-}
-.icon-email:before {
- content: "\e71c";
-}
-.icon-reply-all:before {
- content: "\e71d";
-}
-.icon-forward:before {
- content: "\e71e";
-}
-.icon-reply:before {
- content: "\e71f";
-}
-.icon-filing:before {
- content: "\e720";
-}
-.icon-document-text:before {
- content: "\e721";
-}
-.icon-document:before {
- content: "\e722";
-}
-.icon-gear-b:before {
- content: "\e723";
-}
-.icon-gear-a:before {
- content: "\e724";
-}
-.icon-help-circled:before {
- content: "\e725";
-}
-.icon-help:before {
- content: "\e726";
-}
-.icon-information:before {
- content: "\e727";
-}
-.icon-minus:before {
- content: "\e728";
-}
-.icon-minus-round:before {
- content: "\e729";
-}
-.icon-plus:before {
- content: "\e72a";
-}
-.icon-plus-round:before {
- content: "\e72b";
-}
-.icon-drag:before {
- content: "\e72c";
-}
-.icon-navicon:before {
- content: "\e72d";
-}
-.icon-navicon-round:before {
- content: "\e72e";
-}
-.icon-heart:before {
- content: "\e72f";
-}
-.icon-star:before {
- content: "\e730";
-}
-.icon-search:before {
- content: "\e731";
-}
-.icon-home:before {
- content: "\e732";
-}
-.icon-shuffle:before {
- content: "\e733";
-}
-.icon-loop:before {
- content: "\e734";
-}
-.icon-close-circled:before {
- content: "\e735";
-}
-.icon-close:before {
- content: "\e736";
-}
-.icon-close-round:before {
- content: "\e737";
-}
-.icon-checkmark-circled:before {
- content: "\e738";
-}
-.icon-checkmark:before {
- content: "\e739";
-}
-.icon-checkmark-round:before {
- content: "\e73a";
-}
-.icon-chevron-left:before {
- content: "\e73b";
-}
-.icon-chevron-right:before {
- content: "\e73c";
-}
-.icon-chevron-down:before {
- content: "\e73d";
-}
-.icon-chevron-up:before {
- content: "\e73e";
-}
-.icon-arrow-down-c:before {
- content: "\e73f";
-}
-.icon-arrow-up-c:before {
- content: "\e740";
-}
-.icon-arrow-right-c:before {
- content: "\e741";
-}
-.icon-arrow-left-c:before {
- content: "\e742";
-}
-.icon-arrow-left-b:before {
- content: "\e743";
-}
-.icon-arrow-down-b:before {
- content: "\e744";
-}
-.icon-arrow-right-b:before {
- content: "\e745";
-}
-.icon-arrow-up-b:before {
- content: "\e746";
-}
-.icon-refresh:before {
- content: "\e747";
-}
-.icon-leaf:before {
- content: "\e748";
-}
-.icon-briefcase:before {
- content: "\e749";
-}
-.icon-clock:before {
- content: "\e74a";
-}
-.icon-thermometer:before {
- content: "\e74b";
-}
-.icon-wrench:before {
- content: "\e74c";
-}
-.icon-medkit:before {
- content: "\e74d";
-}
-.icon-wineglass:before {
- content: "\e74e";
-}
-.icon-load-d:before {
- content: "\e74f";
-}
-.icon-load-c:before {
- content: "\e750";
-}
-.icon-load-b:before {
- content: "\e751";
-}
-.icon-load-a:before {
- content: "\e752";
-}
-.icon-umbrella:before {
- content: "\e753";
-}
-.icon-coffee:before {
- content: "\e754";
-}
-.icon-pizza:before {
- content: "\e755";
-}
-.icon-icecream:before {
- content: "\e756";
-}
-.icon-spoon:before {
- content: "\e757";
-}
-.icon-fork:before {
- content: "\e758";
-}
-.icon-knife:before {
- content: "\e759";
-}
-.icon-earth:before {
- content: "\e75a";
-}
-.icon-egg:before {
- content: "\e75b";
-}
-.icon-pie-graph:before {
- content: "\e75c";
-}
-.icon-magnet:before {
- content: "\e75d";
-}
-.icon-help-buoy:before {
- content: "\e75e";
-}
-.icon-nuclear:before {
- content: "\e75f";
-}
-.icon-beaker:before {
- content: "\e760";
-}
-.icon-pricetags:before {
- content: "\e761";
-}
-.icon-pricetag:before {
- content: "\e762";
-}
-.icon-settings:before {
- content: "\e763";
-}
-.icon-hammer:before {
- content: "\e764";
-}
-.icon-power:before {
- content: "\e765";
-}
-.icon-female:before {
- content: "\e766";
-}
-.icon-male:before {
- content: "\e767";
-}
-.icon-pinpoint:before {
- content: "\e768";
-}
-.icon-pin:before {
- content: "\e769";
-}
-.icon-navigate:before {
- content: "\e76a";
-}
-.icon-flag:before {
- content: "\e76b";
-}
-.icon-code-download:before {
- content: "\e76c";
-}
-.icon-code-working:before {
- content: "\e76d";
-}
-.icon-code:before {
- content: "\e76e";
-}
-.icon-usb:before {
- content: "\e76f";
-}
-.icon-bookmark:before {
- content: "\e770";
-}
-.icon-key:before {
- content: "\e771";
-}
-.icon-lightbulb:before {
- content: "\e772";
-}
-.icon-calculator:before {
- content: "\e773";
-}
-.icon-speakerphone:before {
- content: "\e774";
-}
-.icon-contrast:before {
- content: "\e775";
-}
-.icon-accelerate:before {
- content: "\e776";
-}
-.icon-speedometer:before {
- content: "\e777";
-}
-.icon-compass:before {
- content: "\e778";
-}
-.icon-radio-waves:before {
- content: "\e779";
-}
-.icon-log-out:before {
- content: "\e77a";
-}
-.icon-log-in:before {
- content: "\e77b";
-}
-.icon-levels:before {
- content: "\e77c";
-}
-.icon-connection-bars:before {
- content: "\e77d";
-}
-.icon-stats-bars:before {
- content: "\e77e";
-}
-.icon-arrow-graph-up:before {
- content: "\e77f";
-}
-.icon-arrow-graph-down:before {
- content: "\e780";
-}
-.icon-arrow-resize:before {
- content: "\e781";
-}
-.icon-arrow-move:before {
- content: "\e782";
-}
-.icon-arrow-expand:before {
- content: "\e783";
-}
-.icon-arrow-shrink:before {
- content: "\e784";
-}
-.icon-arrow-swap:before {
- content: "\e785";
-}
-.icon-arrow-return-left:before {
- content: "\e786";
-}
-.icon-arrow-return-right:before {
- content: "\e787";
-}
-.icon-social-android-outline:before {
- content: "\e788";
-}
-.icon-social-android:before {
- content: "\e789";
-}
-.icon-social-dropbox:before {
- content: "\e78a";
-}
-.icon-social-dropbox-outline:before {
- content: "\e78b";
-}
-.icon-social-designernews:before {
- content: "\e78c";
-}
-.icon-social-designernews-outline:before {
- content: "\e78d";
-}
-.icon-social-hackernews:before {
- content: "\e78e";
-}
-.icon-social-hackernews-outline:before {
- content: "\e78f";
-}
-.icon-social-windows:before {
- content: "\e790";
-}
-.icon-social-windows-outline:before {
- content: "\e791";
-}
-.icon-social-apple:before {
- content: "\e792";
-}
-.icon-social-apple-outline:before {
- content: "\e793";
-}
-.icon-social-youtube:before {
- content: "\e794";
-}
-.icon-social-youtube-outline:before {
- content: "\e795";
-}
-.icon-social-linkedin:before {
- content: "\e796";
-}
-.icon-social-linkedin-outline:before {
- content: "\e797";
-}
-.icon-social-skype:before {
- content: "\e798";
-}
-.icon-social-skype-outline:before {
- content: "\e799";
-}
-.icon-social-vimeo:before {
- content: "\e79a";
-}
-.icon-social-vimeo-outline:before {
- content: "\e79b";
-}
-.icon-social-buffer:before {
- content: "\e79c";
-}
-.icon-social-buffer-outline:before {
- content: "\e79d";
-}
-.icon-social-yahoo:before {
- content: "\e79e";
-}
-.icon-social-yahoo-outline:before {
- content: "\e79f";
-}
-.icon-social-reddit:before {
- content: "\e7a0";
-}
-.icon-social-reddit-outline:before {
- content: "\e7a1";
-}
-.icon-social-wordpress:before {
- content: "\e7a2";
-}
-.icon-social-wordpress-outline:before {
- content: "\e7a3";
-}
-.icon-social-tumblr:before {
- content: "\e7a4";
-}
-.icon-social-tumblr-outline:before {
- content: "\e7a5";
-}
-.icon-social-rss:before {
- content: "\e7a6";
-}
-.icon-social-rss-outline:before {
- content: "\e7a7";
-}
-.icon-social-github:before {
- content: "\e7a8";
-}
-.icon-social-github-outline:before {
- content: "\e7a9";
-}
-.icon-social-dribbble:before {
- content: "\e7aa";
-}
-.icon-social-dribbble-outline:before {
- content: "\e7ab";
-}
-.icon-social-googleplus:before {
- content: "\e7ac";
-}
-.icon-social-googleplus-outline:before {
- content: "\e7ad";
-}
-.icon-social-facebook:before {
- content: "\e7ae";
-}
-.icon-social-facebook-outline:before {
- content: "\e7af";
-}
-.icon-social-twitter:before {
- content: "\e7b0";
-}
-.icon-social-twitter-outline:before {
- content: "\e7b1";
-}
-.icon-social-pinterest:before {
- content: "\e7b2";
-}
-.icon-social-pinterest-outline:before {
- content: "\e7b3";
-}
-.icon-social-bitcoin:before {
- content: "\e7b4";
-}
-.icon-social-bitcoin-outline:before {
- content: "\e7b5";
-}
-.icon-ios7-at-outline:before {
- content: "\e600";
-}
-.icon-ios7-bookmarks:before {
- content: "\e601";
-}
-.icon-ios7-bookmarks-outline:before {
- content: "\e602";
-}
-.icon-ios7-at:before {
- content: "\e603";
-}
-.icon-ios7-stopwatch:before {
- content: "\e604";
-}
-.icon-ios7-stopwatch-outline:before {
- content: "\e605";
-}
-.icon-ios7-timer:before {
- content: "\e606";
-}
-.icon-ios7-timer-outline:before {
- content: "\e607";
-}
-.icon-ios7-alarm:before {
- content: "\e608";
-}
-.icon-ios7-alarm-outline:before {
- content: "\e609";
-}
-.icon-ios7-rainy:before {
- content: "\e60a";
-}
-.icon-ios7-rainy-outline:before {
- content: "\e60b";
-}
-.icon-ios7-eye-outline:before {
- content: "\e60d";
-}
-.icon-ios7-gear-outline:before {
- content: "\e60e";
-}
-.icon-ios7-gear:before {
- content: "\e60f";
-}
-.icon-ios7-box-outline:before {
- content: "\e610";
-}
-.icon-ios7-box:before {
- content: "\e611";
-}
-.icon-ios7-drag:before {
- content: "\e612";
-}
-.icon-ios7-ionic-outline:before {
- content: "\e613";
-}
-.icon-ios7-printer-outline:before {
- content: "\e614";
-}
-.icon-ios7-trash:before {
- content: "\e615";
-}
-.icon-ios7-flag-outline:before {
- content: "\e616";
-}
-.icon-ios7-glasses:before {
- content: "\e617";
-}
-.icon-ios7-glasses-outline:before {
- content: "\e618";
-}
-.icon-ios7-infinite:before {
- content: "\e61a";
-}
-.icon-ios7-infinite-outline:before {
- content: "\e61b";
-}
-.icon-ios7-cart:before {
- content: "\e61c";
-}
-.icon-ios7-cart-outline:before {
- content: "\e61d";
-}
-.icon-ios7-moon:before {
- content: "\e61e";
-}
-.icon-ios7-moon-outline:before {
- content: "\e61f";
-}
-.icon-ios7-thunderstorm:before {
- content: "\e620";
-}
-.icon-ios7-thunderstorm-outline:before {
- content: "\e621";
-}
-.icon-ios7-cloudy-outline:before {
- content: "\e622";
-}
-.icon-ios7-sunny:before {
- content: "\e623";
-}
-.icon-ios7-sunny-outline:before {
- content: "\e624";
-}
-.icon-ios7-people:before {
- content: "\e625";
-}
-.icon-ios7-people-outline:before {
- content: "\e627";
-}
-.icon-ios7-person:before {
- content: "\e628";
-}
-.icon-ios7-person-outline:before {
- content: "\e629";
-}
-.icon-ios7-location:before {
- content: "\e62a";
-}
-.icon-ios7-location-outline:before {
- content: "\e62b";
-}
-.icon-ios7-personadd:before {
- content: "\e62c";
-}
-.icon-ios7-email:before {
- content: "\e62f";
-}
-.icon-ios7-email-outline:before {
- content: "\e630";
-}
-.icon-ios7-paperplane:before {
- content: "\e631";
-}
-.icon-ios7-paperplane-outline:before {
- content: "\e632";
-}
-.icon-ios7-undo:before {
- content: "\e634";
-}
-.icon-ios7-undo-outline:before {
- content: "\e635";
-}
-.icon-ios7-redo:before {
- content: "\e636";
-}
-.icon-ios7-redo-outline:before {
- content: "\e637";
-}
-.icon-ios7-refresh-outline:before {
- content: "\e63a";
-}
-.icon-ios7-cog:before {
- content: "\e63b";
-}
-.icon-ios7-cog-outline:before {
- content: "\e63c";
-}
-.icon-ios7-browsers:before {
- content: "\e63d";
-}
-.icon-ios7-browsers-outline:before {
- content: "\e63e";
-}
-.icon-ios7-bolt:before {
- content: "\e63f";
-}
-.icon-ios7-bolt-outline:before {
- content: "\e641";
-}
-.icon-ios7-heart:before {
- content: "\e642";
-}
-.icon-ios7-printer:before {
- content: "\e645";
-}
-.icon-ios7-telephone:before {
- content: "\e646";
-}
-.icon-ios7-telephone-outline:before {
- content: "\e647";
-}
-.icon-ios7-monitor:before {
- content: "\e648";
-}
-.icon-ios7-monitor-outline:before {
- content: "\e649";
-}
-.icon-ios7-camera:before {
- content: "\e64a";
-}
-.icon-ios7-camera-outline:before {
- content: "\e64b";
-}
-.icon-ios7-film:before {
- content: "\e64c";
-}
-.icon-ios7-bell:before {
- content: "\e64e";
-}
-.icon-ios7-bell-outline:before {
- content: "\e64f";
-}
-.icon-ios7-musical-note:before {
- content: "\e650";
-}
-.icon-ios7-musical-notes:before {
- content: "\e651";
-}
-.icon-ios7-skipbackward:before {
- content: "\e652";
-}
-.icon-ios7-skipbackward-outline:before {
- content: "\e653";
-}
-.icon-ios7-skipforward:before {
- content: "\e654";
-}
-.icon-ios7-skipforward-outline:before {
- content: "\e655";
-}
-.icon-ios7-rewind:before {
- content: "\e656";
-}
-.icon-ios7-rewind-outline:before {
- content: "\e657";
-}
-.icon-ios7-pause-outline:before {
- content: "\e658";
-}
-.icon-ios7-pause:before {
- content: "\e659";
-}
-.icon-ios7-play:before {
- content: "\e65b";
-}
-.icon-ios7-volume-high:before {
- content: "\e65c";
-}
-.icon-ios7-volume-low:before {
- content: "\e65d";
-}
-.icon-ios7-mic-off:before {
- content: "\e65e";
-}
-.icon-ios7-mic-outline:before {
- content: "\e65f";
-}
-.icon-ios7-mic:before {
- content: "\e660";
-}
-.icon-ios7-cloud-upload:before {
- content: "\e661";
-}
-.icon-ios7-cloud-upload-outline:before {
- content: "\e662";
-}
-.icon-ios7-cloud-outline:before {
- content: "\e663";
-}
-.icon-ios7-arrow-forward:before {
- content: "\e664";
-}
-.icon-ios7-arrow-back:before {
- content: "\e665";
-}
-.icon-ios7-unlocked:before {
- content: "\e666";
-}
-.icon-ios7-unlocked-outline:before {
- content: "\e668";
-}
-.icon-ios7-locked:before {
- content: "\e669";
-}
-.icon-ios7-locked-outline:before {
- content: "\e66a";
-}
-.icon-ios7-minus-empty:before {
- content: "\e66b";
-}
-.icon-ios7-minus:before {
- content: "\e66c";
-}
-.icon-ios7-minus-outline:before {
- content: "\e66d";
-}
-.icon-ios7-folder-outline:before {
- content: "\e66e";
-}
-.icon-ios7-calendar:before {
- content: "\e66f";
-}
-.icon-ios7-calendar-outline:before {
- content: "\e670";
-}
-.icon-ios7-partlysunny-outline:before {
- content: "\e671";
-}
-.icon-ios7-cloudy:before {
- content: "\e672";
-}
-.icon-ios7-eye:before {
- content: "\e676";
-}
-.icon-ios7-videocam:before {
- content: "\e67b";
-}
-.icon-ios7-videocam-outline:before {
- content: "\e67c";
-}
-.icon-ios7-fastforward-outline:before {
- content: "\e67d";
-}
-.icon-ios7-play-outline:before {
- content: "\e67e";
-}
-.icon-ios7-cloud-download-outline:before {
- content: "\e67f";
-}
-.icon-ios7-cloud:before {
- content: "\e680";
-}
-.icon-ios7-arrow-up:before {
- content: "\e62d";
-}
-.icon-ios7-arrow-down:before {
- content: "\e62e";
-}
-.icon-ios7-arrow-right:before {
- content: "\e638";
-}
-.icon-ios7-arrow-left:before {
- content: "\e639";
-}
-.icon-ios7-chatbubble:before {
- content: "\e643";
-}
-.icon-ios7-chatbubble-outline:before {
- content: "\e644";
-}
-.icon-ios7-refresh:before {
- content: "\e673";
-}
-.icon-ios7-refresh-empty:before {
- content: "\e675";
-}
-.icon-ios7-filing-outline:before {
- content: "\e677";
-}
-.icon-ios7-compose:before {
- content: "\e678";
-}
-.icon-ios7-chatboxes:before {
- content: "\e679";
-}
+.ion-alert-circled:before { content: "\f100"; }
+
+.ion-android-add:before { content: "\f2c7"; }
+
+.ion-android-add-circle:before { content: "\f359"; }
+
+.ion-android-alarm-clock:before { content: "\f35a"; }
+
+.ion-android-alert:before { content: "\f35b"; }
+
+.ion-android-apps:before { content: "\f35c"; }
+
+.ion-android-archive:before { content: "\f2c9"; }
+
+.ion-android-arrow-back:before { content: "\f2ca"; }
+
+.ion-android-arrow-down:before { content: "\f35d"; }
+
+.ion-android-arrow-dropdown:before { content: "\f35f"; }
+
+.ion-android-arrow-dropdown-circle:before { content: "\f35e"; }
+
+.ion-android-arrow-dropleft:before { content: "\f361"; }
+
+.ion-android-arrow-dropleft-circle:before { content: "\f360"; }
+
+.ion-android-arrow-dropright:before { content: "\f363"; }
+
+.ion-android-arrow-dropright-circle:before { content: "\f362"; }
+
+.ion-android-arrow-dropup:before { content: "\f365"; }
+
+.ion-android-arrow-dropup-circle:before { content: "\f364"; }
+
+.ion-android-arrow-forward:before { content: "\f30f"; }
+
+.ion-android-arrow-up:before { content: "\f366"; }
+
+.ion-android-attach:before { content: "\f367"; }
+
+.ion-android-bar:before { content: "\f368"; }
+
+.ion-android-bicycle:before { content: "\f369"; }
+
+.ion-android-boat:before { content: "\f36a"; }
+
+.ion-android-bookmark:before { content: "\f36b"; }
+
+.ion-android-bulb:before { content: "\f36c"; }
+
+.ion-android-bus:before { content: "\f36d"; }
+
+.ion-android-calendar:before { content: "\f2d1"; }
+
+.ion-android-call:before { content: "\f2d2"; }
+
+.ion-android-camera:before { content: "\f2d3"; }
+
+.ion-android-cancel:before { content: "\f36e"; }
+
+.ion-android-car:before { content: "\f36f"; }
+
+.ion-android-cart:before { content: "\f370"; }
+
+.ion-android-chat:before { content: "\f2d4"; }
+
+.ion-android-checkbox:before { content: "\f374"; }
+
+.ion-android-checkbox-blank:before { content: "\f371"; }
+
+.ion-android-checkbox-outline:before { content: "\f373"; }
+
+.ion-android-checkbox-outline-blank:before { content: "\f372"; }
+
+.ion-android-checkmark-circle:before { content: "\f375"; }
+
+.ion-android-clipboard:before { content: "\f376"; }
+
+.ion-android-close:before { content: "\f2d7"; }
+
+.ion-android-cloud:before { content: "\f37a"; }
+
+.ion-android-cloud-circle:before { content: "\f377"; }
+
+.ion-android-cloud-done:before { content: "\f378"; }
+
+.ion-android-cloud-outline:before { content: "\f379"; }
+
+.ion-android-color-palette:before { content: "\f37b"; }
+
+.ion-android-compass:before { content: "\f37c"; }
+
+.ion-android-contact:before { content: "\f2d8"; }
+
+.ion-android-contacts:before { content: "\f2d9"; }
+
+.ion-android-contract:before { content: "\f37d"; }
+
+.ion-android-create:before { content: "\f37e"; }
+
+.ion-android-delete:before { content: "\f37f"; }
+
+.ion-android-desktop:before { content: "\f380"; }
+
+.ion-android-document:before { content: "\f381"; }
+
+.ion-android-done:before { content: "\f383"; }
+
+.ion-android-done-all:before { content: "\f382"; }
+
+.ion-android-download:before { content: "\f2dd"; }
+
+.ion-android-drafts:before { content: "\f384"; }
+
+.ion-android-exit:before { content: "\f385"; }
+
+.ion-android-expand:before { content: "\f386"; }
+
+.ion-android-favorite:before { content: "\f388"; }
+
+.ion-android-favorite-outline:before { content: "\f387"; }
+
+.ion-android-film:before { content: "\f389"; }
+
+.ion-android-folder:before { content: "\f2e0"; }
+
+.ion-android-folder-open:before { content: "\f38a"; }
+
+.ion-android-funnel:before { content: "\f38b"; }
+
+.ion-android-globe:before { content: "\f38c"; }
+
+.ion-android-hand:before { content: "\f2e3"; }
+
+.ion-android-hangout:before { content: "\f38d"; }
+
+.ion-android-happy:before { content: "\f38e"; }
+
+.ion-android-home:before { content: "\f38f"; }
+
+.ion-android-image:before { content: "\f2e4"; }
+
+.ion-android-laptop:before { content: "\f390"; }
+
+.ion-android-list:before { content: "\f391"; }
+
+.ion-android-locate:before { content: "\f2e9"; }
+
+.ion-android-lock:before { content: "\f392"; }
+
+.ion-android-mail:before { content: "\f2eb"; }
+
+.ion-android-map:before { content: "\f393"; }
+
+.ion-android-menu:before { content: "\f394"; }
+
+.ion-android-microphone:before { content: "\f2ec"; }
+
+.ion-android-microphone-off:before { content: "\f395"; }
+
+.ion-android-more-horizontal:before { content: "\f396"; }
+
+.ion-android-more-vertical:before { content: "\f397"; }
+
+.ion-android-navigate:before { content: "\f398"; }
+
+.ion-android-notifications:before { content: "\f39b"; }
+
+.ion-android-notifications-none:before { content: "\f399"; }
+
+.ion-android-notifications-off:before { content: "\f39a"; }
+
+.ion-android-open:before { content: "\f39c"; }
+
+.ion-android-options:before { content: "\f39d"; }
+
+.ion-android-people:before { content: "\f39e"; }
+
+.ion-android-person:before { content: "\f3a0"; }
+
+.ion-android-person-add:before { content: "\f39f"; }
+
+.ion-android-phone-landscape:before { content: "\f3a1"; }
+
+.ion-android-phone-portrait:before { content: "\f3a2"; }
+
+.ion-android-pin:before { content: "\f3a3"; }
+
+.ion-android-plane:before { content: "\f3a4"; }
+
+.ion-android-playstore:before { content: "\f2f0"; }
+
+.ion-android-print:before { content: "\f3a5"; }
+
+.ion-android-radio-button-off:before { content: "\f3a6"; }
+
+.ion-android-radio-button-on:before { content: "\f3a7"; }
+
+.ion-android-refresh:before { content: "\f3a8"; }
+
+.ion-android-remove:before { content: "\f2f4"; }
+
+.ion-android-remove-circle:before { content: "\f3a9"; }
+
+.ion-android-restaurant:before { content: "\f3aa"; }
+
+.ion-android-sad:before { content: "\f3ab"; }
+
+.ion-android-search:before { content: "\f2f5"; }
+
+.ion-android-send:before { content: "\f2f6"; }
+
+.ion-android-settings:before { content: "\f2f7"; }
+
+.ion-android-share:before { content: "\f2f8"; }
+
+.ion-android-share-alt:before { content: "\f3ac"; }
+
+.ion-android-star:before { content: "\f2fc"; }
+
+.ion-android-star-half:before { content: "\f3ad"; }
+
+.ion-android-star-outline:before { content: "\f3ae"; }
+
+.ion-android-stopwatch:before { content: "\f2fd"; }
+
+.ion-android-subway:before { content: "\f3af"; }
+
+.ion-android-sunny:before { content: "\f3b0"; }
+
+.ion-android-sync:before { content: "\f3b1"; }
+
+.ion-android-textsms:before { content: "\f3b2"; }
+
+.ion-android-time:before { content: "\f3b3"; }
+
+.ion-android-train:before { content: "\f3b4"; }
+
+.ion-android-unlock:before { content: "\f3b5"; }
+
+.ion-android-upload:before { content: "\f3b6"; }
+
+.ion-android-volume-down:before { content: "\f3b7"; }
+
+.ion-android-volume-mute:before { content: "\f3b8"; }
+
+.ion-android-volume-off:before { content: "\f3b9"; }
+
+.ion-android-volume-up:before { content: "\f3ba"; }
+
+.ion-android-walk:before { content: "\f3bb"; }
+
+.ion-android-warning:before { content: "\f3bc"; }
+
+.ion-android-watch:before { content: "\f3bd"; }
+
+.ion-android-wifi:before { content: "\f305"; }
+
+.ion-aperture:before { content: "\f313"; }
+
+.ion-archive:before { content: "\f102"; }
+
+.ion-arrow-down-a:before { content: "\f103"; }
+
+.ion-arrow-down-b:before { content: "\f104"; }
+
+.ion-arrow-down-c:before { content: "\f105"; }
+
+.ion-arrow-expand:before { content: "\f25e"; }
+
+.ion-arrow-graph-down-left:before { content: "\f25f"; }
+
+.ion-arrow-graph-down-right:before { content: "\f260"; }
+
+.ion-arrow-graph-up-left:before { content: "\f261"; }
+
+.ion-arrow-graph-up-right:before { content: "\f262"; }
+
+.ion-arrow-left-a:before { content: "\f106"; }
+
+.ion-arrow-left-b:before { content: "\f107"; }
+
+.ion-arrow-left-c:before { content: "\f108"; }
+
+.ion-arrow-move:before { content: "\f263"; }
+
+.ion-arrow-resize:before { content: "\f264"; }
+
+.ion-arrow-return-left:before { content: "\f265"; }
+
+.ion-arrow-return-right:before { content: "\f266"; }
+
+.ion-arrow-right-a:before { content: "\f109"; }
+
+.ion-arrow-right-b:before { content: "\f10a"; }
+
+.ion-arrow-right-c:before { content: "\f10b"; }
+
+.ion-arrow-shrink:before { content: "\f267"; }
+
+.ion-arrow-swap:before { content: "\f268"; }
+
+.ion-arrow-up-a:before { content: "\f10c"; }
+
+.ion-arrow-up-b:before { content: "\f10d"; }
+
+.ion-arrow-up-c:before { content: "\f10e"; }
+
+.ion-asterisk:before { content: "\f314"; }
+
+.ion-at:before { content: "\f10f"; }
+
+.ion-backspace:before { content: "\f3bf"; }
+
+.ion-backspace-outline:before { content: "\f3be"; }
+
+.ion-bag:before { content: "\f110"; }
+
+.ion-battery-charging:before { content: "\f111"; }
+
+.ion-battery-empty:before { content: "\f112"; }
+
+.ion-battery-full:before { content: "\f113"; }
+
+.ion-battery-half:before { content: "\f114"; }
+
+.ion-battery-low:before { content: "\f115"; }
+
+.ion-beaker:before { content: "\f269"; }
+
+.ion-beer:before { content: "\f26a"; }
+
+.ion-bluetooth:before { content: "\f116"; }
+
+.ion-bonfire:before { content: "\f315"; }
+
+.ion-bookmark:before { content: "\f26b"; }
+
+.ion-bowtie:before { content: "\f3c0"; }
+
+.ion-briefcase:before { content: "\f26c"; }
+
+.ion-bug:before { content: "\f2be"; }
+
+.ion-calculator:before { content: "\f26d"; }
+
+.ion-calendar:before { content: "\f117"; }
+
+.ion-camera:before { content: "\f118"; }
+
+.ion-card:before { content: "\f119"; }
+
+.ion-cash:before { content: "\f316"; }
+
+.ion-chatbox:before { content: "\f11b"; }
+
+.ion-chatbox-working:before { content: "\f11a"; }
+
+.ion-chatboxes:before { content: "\f11c"; }
+
+.ion-chatbubble:before { content: "\f11e"; }
+
+.ion-chatbubble-working:before { content: "\f11d"; }
+
+.ion-chatbubbles:before { content: "\f11f"; }
+
+.ion-checkmark:before { content: "\f122"; }
+
+.ion-checkmark-circled:before { content: "\f120"; }
+
+.ion-checkmark-round:before { content: "\f121"; }
+
+.ion-chevron-down:before { content: "\f123"; }
+
+.ion-chevron-left:before { content: "\f124"; }
+
+.ion-chevron-right:before { content: "\f125"; }
+
+.ion-chevron-up:before { content: "\f126"; }
+
+.ion-clipboard:before { content: "\f127"; }
+
+.ion-clock:before { content: "\f26e"; }
+
+.ion-close:before { content: "\f12a"; }
+
+.ion-close-circled:before { content: "\f128"; }
+
+.ion-close-round:before { content: "\f129"; }
+
+.ion-closed-captioning:before { content: "\f317"; }
+
+.ion-cloud:before { content: "\f12b"; }
+
+.ion-code:before { content: "\f271"; }
+
+.ion-code-download:before { content: "\f26f"; }
+
+.ion-code-working:before { content: "\f270"; }
+
+.ion-coffee:before { content: "\f272"; }
+
+.ion-compass:before { content: "\f273"; }
+
+.ion-compose:before { content: "\f12c"; }
+
+.ion-connection-bars:before { content: "\f274"; }
+
+.ion-contrast:before { content: "\f275"; }
+
+.ion-crop:before { content: "\f3c1"; }
+
+.ion-cube:before { content: "\f318"; }
+
+.ion-disc:before { content: "\f12d"; }
+
+.ion-document:before { content: "\f12f"; }
+
+.ion-document-text:before { content: "\f12e"; }
+
+.ion-drag:before { content: "\f130"; }
+
+.ion-earth:before { content: "\f276"; }
+
+.ion-easel:before { content: "\f3c2"; }
+
+.ion-edit:before { content: "\f2bf"; }
+
+.ion-egg:before { content: "\f277"; }
+
+.ion-eject:before { content: "\f131"; }
+
+.ion-email:before { content: "\f132"; }
+
+.ion-email-unread:before { content: "\f3c3"; }
+
+.ion-erlenmeyer-flask:before { content: "\f3c5"; }
+
+.ion-erlenmeyer-flask-bubbles:before { content: "\f3c4"; }
+
+.ion-eye:before { content: "\f133"; }
+
+.ion-eye-disabled:before { content: "\f306"; }
+
+.ion-female:before { content: "\f278"; }
+
+.ion-filing:before { content: "\f134"; }
+
+.ion-film-marker:before { content: "\f135"; }
+
+.ion-fireball:before { content: "\f319"; }
+
+.ion-flag:before { content: "\f279"; }
+
+.ion-flame:before { content: "\f31a"; }
+
+.ion-flash:before { content: "\f137"; }
+
+.ion-flash-off:before { content: "\f136"; }
+
+.ion-folder:before { content: "\f139"; }
+
+.ion-fork:before { content: "\f27a"; }
+
+.ion-fork-repo:before { content: "\f2c0"; }
+
+.ion-forward:before { content: "\f13a"; }
+
+.ion-funnel:before { content: "\f31b"; }
+
+.ion-gear-a:before { content: "\f13d"; }
+
+.ion-gear-b:before { content: "\f13e"; }
+
+.ion-grid:before { content: "\f13f"; }
+
+.ion-hammer:before { content: "\f27b"; }
+
+.ion-happy:before { content: "\f31c"; }
+
+.ion-happy-outline:before { content: "\f3c6"; }
+
+.ion-headphone:before { content: "\f140"; }
+
+.ion-heart:before { content: "\f141"; }
+
+.ion-heart-broken:before { content: "\f31d"; }
+
+.ion-help:before { content: "\f143"; }
+
+.ion-help-buoy:before { content: "\f27c"; }
+
+.ion-help-circled:before { content: "\f142"; }
+
+.ion-home:before { content: "\f144"; }
+
+.ion-icecream:before { content: "\f27d"; }
+
+.ion-image:before { content: "\f147"; }
+
+.ion-images:before { content: "\f148"; }
+
+.ion-information:before { content: "\f14a"; }
+
+.ion-information-circled:before { content: "\f149"; }
+
+.ion-ionic:before { content: "\f14b"; }
+
+.ion-ios-alarm:before { content: "\f3c8"; }
+
+.ion-ios-alarm-outline:before { content: "\f3c7"; }
+
+.ion-ios-albums:before { content: "\f3ca"; }
+
+.ion-ios-albums-outline:before { content: "\f3c9"; }
+
+.ion-ios-americanfootball:before { content: "\f3cc"; }
+
+.ion-ios-americanfootball-outline:before { content: "\f3cb"; }
+
+.ion-ios-analytics:before { content: "\f3ce"; }
+
+.ion-ios-analytics-outline:before { content: "\f3cd"; }
+
+.ion-ios-arrow-back:before { content: "\f3cf"; }
+
+.ion-ios-arrow-down:before { content: "\f3d0"; }
+
+.ion-ios-arrow-forward:before { content: "\f3d1"; }
+
+.ion-ios-arrow-left:before { content: "\f3d2"; }
+
+.ion-ios-arrow-right:before { content: "\f3d3"; }
+
+.ion-ios-arrow-thin-down:before { content: "\f3d4"; }
+
+.ion-ios-arrow-thin-left:before { content: "\f3d5"; }
+
+.ion-ios-arrow-thin-right:before { content: "\f3d6"; }
+
+.ion-ios-arrow-thin-up:before { content: "\f3d7"; }
+
+.ion-ios-arrow-up:before { content: "\f3d8"; }
+
+.ion-ios-at:before { content: "\f3da"; }
+
+.ion-ios-at-outline:before { content: "\f3d9"; }
+
+.ion-ios-barcode:before { content: "\f3dc"; }
+
+.ion-ios-barcode-outline:before { content: "\f3db"; }
+
+.ion-ios-baseball:before { content: "\f3de"; }
+
+.ion-ios-baseball-outline:before { content: "\f3dd"; }
+
+.ion-ios-basketball:before { content: "\f3e0"; }
+
+.ion-ios-basketball-outline:before { content: "\f3df"; }
+
+.ion-ios-bell:before { content: "\f3e2"; }
+
+.ion-ios-bell-outline:before { content: "\f3e1"; }
+
+.ion-ios-body:before { content: "\f3e4"; }
+
+.ion-ios-body-outline:before { content: "\f3e3"; }
+
+.ion-ios-bolt:before { content: "\f3e6"; }
+
+.ion-ios-bolt-outline:before { content: "\f3e5"; }
+
+.ion-ios-book:before { content: "\f3e8"; }
+
+.ion-ios-book-outline:before { content: "\f3e7"; }
+
+.ion-ios-bookmarks:before { content: "\f3ea"; }
+
+.ion-ios-bookmarks-outline:before { content: "\f3e9"; }
+
+.ion-ios-box:before { content: "\f3ec"; }
+
+.ion-ios-box-outline:before { content: "\f3eb"; }
+
+.ion-ios-briefcase:before { content: "\f3ee"; }
+
+.ion-ios-briefcase-outline:before { content: "\f3ed"; }
+
+.ion-ios-browsers:before { content: "\f3f0"; }
+
+.ion-ios-browsers-outline:before { content: "\f3ef"; }
+
+.ion-ios-calculator:before { content: "\f3f2"; }
+
+.ion-ios-calculator-outline:before { content: "\f3f1"; }
+
+.ion-ios-calendar:before { content: "\f3f4"; }
+
+.ion-ios-calendar-outline:before { content: "\f3f3"; }
+
+.ion-ios-camera:before { content: "\f3f6"; }
+
+.ion-ios-camera-outline:before { content: "\f3f5"; }
+
+.ion-ios-cart:before { content: "\f3f8"; }
+
+.ion-ios-cart-outline:before { content: "\f3f7"; }
+
+.ion-ios-chatboxes:before { content: "\f3fa"; }
+
+.ion-ios-chatboxes-outline:before { content: "\f3f9"; }
+
+.ion-ios-chatbubble:before { content: "\f3fc"; }
+
+.ion-ios-chatbubble-outline:before { content: "\f3fb"; }
+
+.ion-ios-checkmark:before { content: "\f3ff"; }
+
+.ion-ios-checkmark-empty:before { content: "\f3fd"; }
+
+.ion-ios-checkmark-outline:before { content: "\f3fe"; }
+
+.ion-ios-circle-filled:before { content: "\f400"; }
+
+.ion-ios-circle-outline:before { content: "\f401"; }
+
+.ion-ios-clock:before { content: "\f403"; }
+
+.ion-ios-clock-outline:before { content: "\f402"; }
+
+.ion-ios-close:before { content: "\f406"; }
+
+.ion-ios-close-empty:before { content: "\f404"; }
+
+.ion-ios-close-outline:before { content: "\f405"; }
+
+.ion-ios-cloud:before { content: "\f40c"; }
+
+.ion-ios-cloud-download:before { content: "\f408"; }
+
+.ion-ios-cloud-download-outline:before { content: "\f407"; }
+
+.ion-ios-cloud-outline:before { content: "\f409"; }
+
+.ion-ios-cloud-upload:before { content: "\f40b"; }
+
+.ion-ios-cloud-upload-outline:before { content: "\f40a"; }
+
+.ion-ios-cloudy:before { content: "\f410"; }
+
+.ion-ios-cloudy-night:before { content: "\f40e"; }
+
+.ion-ios-cloudy-night-outline:before { content: "\f40d"; }
+
+.ion-ios-cloudy-outline:before { content: "\f40f"; }
+
+.ion-ios-cog:before { content: "\f412"; }
+
+.ion-ios-cog-outline:before { content: "\f411"; }
+
+.ion-ios-color-filter:before { content: "\f414"; }
+
+.ion-ios-color-filter-outline:before { content: "\f413"; }
+
+.ion-ios-color-wand:before { content: "\f416"; }
+
+.ion-ios-color-wand-outline:before { content: "\f415"; }
+
+.ion-ios-compose:before { content: "\f418"; }
+
+.ion-ios-compose-outline:before { content: "\f417"; }
+
+.ion-ios-contact:before { content: "\f41a"; }
+
+.ion-ios-contact-outline:before { content: "\f419"; }
+
+.ion-ios-copy:before { content: "\f41c"; }
+
+.ion-ios-copy-outline:before { content: "\f41b"; }
+
+.ion-ios-crop:before { content: "\f41e"; }
+
+.ion-ios-crop-strong:before { content: "\f41d"; }
+
+.ion-ios-download:before { content: "\f420"; }
+
+.ion-ios-download-outline:before { content: "\f41f"; }
+
+.ion-ios-drag:before { content: "\f421"; }
+
+.ion-ios-email:before { content: "\f423"; }
+
+.ion-ios-email-outline:before { content: "\f422"; }
+
+.ion-ios-eye:before { content: "\f425"; }
+
+.ion-ios-eye-outline:before { content: "\f424"; }
+
+.ion-ios-fastforward:before { content: "\f427"; }
+
+.ion-ios-fastforward-outline:before { content: "\f426"; }
+
+.ion-ios-filing:before { content: "\f429"; }
+
+.ion-ios-filing-outline:before { content: "\f428"; }
+
+.ion-ios-film:before { content: "\f42b"; }
+
+.ion-ios-film-outline:before { content: "\f42a"; }
+
+.ion-ios-flag:before { content: "\f42d"; }
+
+.ion-ios-flag-outline:before { content: "\f42c"; }
+
+.ion-ios-flame:before { content: "\f42f"; }
+
+.ion-ios-flame-outline:before { content: "\f42e"; }
+
+.ion-ios-flask:before { content: "\f431"; }
+
+.ion-ios-flask-outline:before { content: "\f430"; }
+
+.ion-ios-flower:before { content: "\f433"; }
+
+.ion-ios-flower-outline:before { content: "\f432"; }
+
+.ion-ios-folder:before { content: "\f435"; }
+
+.ion-ios-folder-outline:before { content: "\f434"; }
+
+.ion-ios-football:before { content: "\f437"; }
+
+.ion-ios-football-outline:before { content: "\f436"; }
+
+.ion-ios-game-controller-a:before { content: "\f439"; }
+
+.ion-ios-game-controller-a-outline:before { content: "\f438"; }
+
+.ion-ios-game-controller-b:before { content: "\f43b"; }
+
+.ion-ios-game-controller-b-outline:before { content: "\f43a"; }
+
+.ion-ios-gear:before { content: "\f43d"; }
+
+.ion-ios-gear-outline:before { content: "\f43c"; }
+
+.ion-ios-glasses:before { content: "\f43f"; }
+
+.ion-ios-glasses-outline:before { content: "\f43e"; }
+
+.ion-ios-grid-view:before { content: "\f441"; }
+
+.ion-ios-grid-view-outline:before { content: "\f440"; }
+
+.ion-ios-heart:before { content: "\f443"; }
+
+.ion-ios-heart-outline:before { content: "\f442"; }
+
+.ion-ios-help:before { content: "\f446"; }
+
+.ion-ios-help-empty:before { content: "\f444"; }
+
+.ion-ios-help-outline:before { content: "\f445"; }
+
+.ion-ios-home:before { content: "\f448"; }
+
+.ion-ios-home-outline:before { content: "\f447"; }
+
+.ion-ios-infinite:before { content: "\f44a"; }
+
+.ion-ios-infinite-outline:before { content: "\f449"; }
+
+.ion-ios-information:before { content: "\f44d"; }
+
+.ion-ios-information-empty:before { content: "\f44b"; }
+
+.ion-ios-information-outline:before { content: "\f44c"; }
+
+.ion-ios-ionic-outline:before { content: "\f44e"; }
+
+.ion-ios-keypad:before { content: "\f450"; }
+
+.ion-ios-keypad-outline:before { content: "\f44f"; }
+
+.ion-ios-lightbulb:before { content: "\f452"; }
+
+.ion-ios-lightbulb-outline:before { content: "\f451"; }
+
+.ion-ios-list:before { content: "\f454"; }
+
+.ion-ios-list-outline:before { content: "\f453"; }
+
+.ion-ios-location:before { content: "\f456"; }
+
+.ion-ios-location-outline:before { content: "\f455"; }
+
+.ion-ios-locked:before { content: "\f458"; }
+
+.ion-ios-locked-outline:before { content: "\f457"; }
+
+.ion-ios-loop:before { content: "\f45a"; }
+
+.ion-ios-loop-strong:before { content: "\f459"; }
+
+.ion-ios-medical:before { content: "\f45c"; }
+
+.ion-ios-medical-outline:before { content: "\f45b"; }
+
+.ion-ios-medkit:before { content: "\f45e"; }
+
+.ion-ios-medkit-outline:before { content: "\f45d"; }
+
+.ion-ios-mic:before { content: "\f461"; }
+
+.ion-ios-mic-off:before { content: "\f45f"; }
+
+.ion-ios-mic-outline:before { content: "\f460"; }
+
+.ion-ios-minus:before { content: "\f464"; }
+
+.ion-ios-minus-empty:before { content: "\f462"; }
+
+.ion-ios-minus-outline:before { content: "\f463"; }
+
+.ion-ios-monitor:before { content: "\f466"; }
+
+.ion-ios-monitor-outline:before { content: "\f465"; }
+
+.ion-ios-moon:before { content: "\f468"; }
+
+.ion-ios-moon-outline:before { content: "\f467"; }
+
+.ion-ios-more:before { content: "\f46a"; }
+
+.ion-ios-more-outline:before { content: "\f469"; }
+
+.ion-ios-musical-note:before { content: "\f46b"; }
+
+.ion-ios-musical-notes:before { content: "\f46c"; }
+
+.ion-ios-navigate:before { content: "\f46e"; }
+
+.ion-ios-navigate-outline:before { content: "\f46d"; }
+
+.ion-ios-nutrition:before { content: "\f470"; }
+
+.ion-ios-nutrition-outline:before { content: "\f46f"; }
+
+.ion-ios-paper:before { content: "\f472"; }
+
+.ion-ios-paper-outline:before { content: "\f471"; }
+
+.ion-ios-paperplane:before { content: "\f474"; }
+
+.ion-ios-paperplane-outline:before { content: "\f473"; }
+
+.ion-ios-partlysunny:before { content: "\f476"; }
+
+.ion-ios-partlysunny-outline:before { content: "\f475"; }
+
+.ion-ios-pause:before { content: "\f478"; }
+
+.ion-ios-pause-outline:before { content: "\f477"; }
+
+.ion-ios-paw:before { content: "\f47a"; }
+
+.ion-ios-paw-outline:before { content: "\f479"; }
+
+.ion-ios-people:before { content: "\f47c"; }
+
+.ion-ios-people-outline:before { content: "\f47b"; }
+
+.ion-ios-person:before { content: "\f47e"; }
+
+.ion-ios-person-outline:before { content: "\f47d"; }
+
+.ion-ios-personadd:before { content: "\f480"; }
+
+.ion-ios-personadd-outline:before { content: "\f47f"; }
+
+.ion-ios-photos:before { content: "\f482"; }
+
+.ion-ios-photos-outline:before { content: "\f481"; }
+
+.ion-ios-pie:before { content: "\f484"; }
+
+.ion-ios-pie-outline:before { content: "\f483"; }
+
+.ion-ios-pint:before { content: "\f486"; }
+
+.ion-ios-pint-outline:before { content: "\f485"; }
+
+.ion-ios-play:before { content: "\f488"; }
+
+.ion-ios-play-outline:before { content: "\f487"; }
+
+.ion-ios-plus:before { content: "\f48b"; }
+
+.ion-ios-plus-empty:before { content: "\f489"; }
+
+.ion-ios-plus-outline:before { content: "\f48a"; }
+
+.ion-ios-pricetag:before { content: "\f48d"; }
+
+.ion-ios-pricetag-outline:before { content: "\f48c"; }
+
+.ion-ios-pricetags:before { content: "\f48f"; }
+
+.ion-ios-pricetags-outline:before { content: "\f48e"; }
+
+.ion-ios-printer:before { content: "\f491"; }
+
+.ion-ios-printer-outline:before { content: "\f490"; }
+
+.ion-ios-pulse:before { content: "\f493"; }
+
+.ion-ios-pulse-strong:before { content: "\f492"; }
+
+.ion-ios-rainy:before { content: "\f495"; }
+
+.ion-ios-rainy-outline:before { content: "\f494"; }
+
+.ion-ios-recording:before { content: "\f497"; }
+
+.ion-ios-recording-outline:before { content: "\f496"; }
+
+.ion-ios-redo:before { content: "\f499"; }
+
+.ion-ios-redo-outline:before { content: "\f498"; }
+
+.ion-ios-refresh:before { content: "\f49c"; }
+
+.ion-ios-refresh-empty:before { content: "\f49a"; }
+
+.ion-ios-refresh-outline:before { content: "\f49b"; }
+
+.ion-ios-reload:before { content: "\f49d"; }
+
+.ion-ios-reverse-camera:before { content: "\f49f"; }
+
+.ion-ios-reverse-camera-outline:before { content: "\f49e"; }
+
+.ion-ios-rewind:before { content: "\f4a1"; }
+
+.ion-ios-rewind-outline:before { content: "\f4a0"; }
+
+.ion-ios-rose:before { content: "\f4a3"; }
+
+.ion-ios-rose-outline:before { content: "\f4a2"; }
+
+.ion-ios-search:before { content: "\f4a5"; }
+
+.ion-ios-search-strong:before { content: "\f4a4"; }
+
+.ion-ios-settings:before { content: "\f4a7"; }
+
+.ion-ios-settings-strong:before { content: "\f4a6"; }
+
+.ion-ios-shuffle:before { content: "\f4a9"; }
+
+.ion-ios-shuffle-strong:before { content: "\f4a8"; }
+
+.ion-ios-skipbackward:before { content: "\f4ab"; }
+
+.ion-ios-skipbackward-outline:before { content: "\f4aa"; }
+
+.ion-ios-skipforward:before { content: "\f4ad"; }
+
+.ion-ios-skipforward-outline:before { content: "\f4ac"; }
+
+.ion-ios-snowy:before { content: "\f4ae"; }
+
+.ion-ios-speedometer:before { content: "\f4b0"; }
+
+.ion-ios-speedometer-outline:before { content: "\f4af"; }
+
+.ion-ios-star:before { content: "\f4b3"; }
+
+.ion-ios-star-half:before { content: "\f4b1"; }
+
+.ion-ios-star-outline:before { content: "\f4b2"; }
+
+.ion-ios-stopwatch:before { content: "\f4b5"; }
+
+.ion-ios-stopwatch-outline:before { content: "\f4b4"; }
+
+.ion-ios-sunny:before { content: "\f4b7"; }
+
+.ion-ios-sunny-outline:before { content: "\f4b6"; }
+
+.ion-ios-telephone:before { content: "\f4b9"; }
+
+.ion-ios-telephone-outline:before { content: "\f4b8"; }
+
+.ion-ios-tennisball:before { content: "\f4bb"; }
+
+.ion-ios-tennisball-outline:before { content: "\f4ba"; }
+
+.ion-ios-thunderstorm:before { content: "\f4bd"; }
+
+.ion-ios-thunderstorm-outline:before { content: "\f4bc"; }
+
+.ion-ios-time:before { content: "\f4bf"; }
+
+.ion-ios-time-outline:before { content: "\f4be"; }
+
+.ion-ios-timer:before { content: "\f4c1"; }
+
+.ion-ios-timer-outline:before { content: "\f4c0"; }
+
+.ion-ios-toggle:before { content: "\f4c3"; }
+
+.ion-ios-toggle-outline:before { content: "\f4c2"; }
+
+.ion-ios-trash:before { content: "\f4c5"; }
+
+.ion-ios-trash-outline:before { content: "\f4c4"; }
+
+.ion-ios-undo:before { content: "\f4c7"; }
+
+.ion-ios-undo-outline:before { content: "\f4c6"; }
+
+.ion-ios-unlocked:before { content: "\f4c9"; }
+
+.ion-ios-unlocked-outline:before { content: "\f4c8"; }
+
+.ion-ios-upload:before { content: "\f4cb"; }
+
+.ion-ios-upload-outline:before { content: "\f4ca"; }
+
+.ion-ios-videocam:before { content: "\f4cd"; }
+
+.ion-ios-videocam-outline:before { content: "\f4cc"; }
+
+.ion-ios-volume-high:before { content: "\f4ce"; }
+
+.ion-ios-volume-low:before { content: "\f4cf"; }
+
+.ion-ios-wineglass:before { content: "\f4d1"; }
+
+.ion-ios-wineglass-outline:before { content: "\f4d0"; }
+
+.ion-ios-world:before { content: "\f4d3"; }
+
+.ion-ios-world-outline:before { content: "\f4d2"; }
+
+.ion-ipad:before { content: "\f1f9"; }
+
+.ion-iphone:before { content: "\f1fa"; }
+
+.ion-ipod:before { content: "\f1fb"; }
+
+.ion-jet:before { content: "\f295"; }
+
+.ion-key:before { content: "\f296"; }
+
+.ion-knife:before { content: "\f297"; }
+
+.ion-laptop:before { content: "\f1fc"; }
+
+.ion-leaf:before { content: "\f1fd"; }
+
+.ion-levels:before { content: "\f298"; }
+
+.ion-lightbulb:before { content: "\f299"; }
+
+.ion-link:before { content: "\f1fe"; }
+
+.ion-load-a:before { content: "\f29a"; }
+
+.ion-load-b:before { content: "\f29b"; }
+
+.ion-load-c:before { content: "\f29c"; }
+
+.ion-load-d:before { content: "\f29d"; }
+
+.ion-location:before { content: "\f1ff"; }
+
+.ion-lock-combination:before { content: "\f4d4"; }
+
+.ion-locked:before { content: "\f200"; }
+
+.ion-log-in:before { content: "\f29e"; }
+
+.ion-log-out:before { content: "\f29f"; }
+
+.ion-loop:before { content: "\f201"; }
+
+.ion-magnet:before { content: "\f2a0"; }
+
+.ion-male:before { content: "\f2a1"; }
+
+.ion-man:before { content: "\f202"; }
+
+.ion-map:before { content: "\f203"; }
+
+.ion-medkit:before { content: "\f2a2"; }
+
+.ion-merge:before { content: "\f33f"; }
+
+.ion-mic-a:before { content: "\f204"; }
+
+.ion-mic-b:before { content: "\f205"; }
+
+.ion-mic-c:before { content: "\f206"; }
+
+.ion-minus:before { content: "\f209"; }
+
+.ion-minus-circled:before { content: "\f207"; }
+
+.ion-minus-round:before { content: "\f208"; }
+
+.ion-model-s:before { content: "\f2c1"; }
+
+.ion-monitor:before { content: "\f20a"; }
+
+.ion-more:before { content: "\f20b"; }
+
+.ion-mouse:before { content: "\f340"; }
+
+.ion-music-note:before { content: "\f20c"; }
+
+.ion-navicon:before { content: "\f20e"; }
+
+.ion-navicon-round:before { content: "\f20d"; }
+
+.ion-navigate:before { content: "\f2a3"; }
+
+.ion-network:before { content: "\f341"; }
+
+.ion-no-smoking:before { content: "\f2c2"; }
+
+.ion-nuclear:before { content: "\f2a4"; }
+
+.ion-outlet:before { content: "\f342"; }
+
+.ion-paintbrush:before { content: "\f4d5"; }
+
+.ion-paintbucket:before { content: "\f4d6"; }
+
+.ion-paper-airplane:before { content: "\f2c3"; }
+
+.ion-paperclip:before { content: "\f20f"; }
+
+.ion-pause:before { content: "\f210"; }
+
+.ion-person:before { content: "\f213"; }
+
+.ion-person-add:before { content: "\f211"; }
+
+.ion-person-stalker:before { content: "\f212"; }
+
+.ion-pie-graph:before { content: "\f2a5"; }
+
+.ion-pin:before { content: "\f2a6"; }
+
+.ion-pinpoint:before { content: "\f2a7"; }
+
+.ion-pizza:before { content: "\f2a8"; }
+
+.ion-plane:before { content: "\f214"; }
+
+.ion-planet:before { content: "\f343"; }
+
+.ion-play:before { content: "\f215"; }
+
+.ion-playstation:before { content: "\f30a"; }
+
+.ion-plus:before { content: "\f218"; }
+
+.ion-plus-circled:before { content: "\f216"; }
+
+.ion-plus-round:before { content: "\f217"; }
+
+.ion-podium:before { content: "\f344"; }
+
+.ion-pound:before { content: "\f219"; }
+
+.ion-power:before { content: "\f2a9"; }
+
+.ion-pricetag:before { content: "\f2aa"; }
+
+.ion-pricetags:before { content: "\f2ab"; }
+
+.ion-printer:before { content: "\f21a"; }
+
+.ion-pull-request:before { content: "\f345"; }
+
+.ion-qr-scanner:before { content: "\f346"; }
+
+.ion-quote:before { content: "\f347"; }
+
+.ion-radio-waves:before { content: "\f2ac"; }
+
+.ion-record:before { content: "\f21b"; }
+
+.ion-refresh:before { content: "\f21c"; }
+
+.ion-reply:before { content: "\f21e"; }
+
+.ion-reply-all:before { content: "\f21d"; }
+
+.ion-ribbon-a:before { content: "\f348"; }
+
+.ion-ribbon-b:before { content: "\f349"; }
+
+.ion-sad:before { content: "\f34a"; }
+
+.ion-sad-outline:before { content: "\f4d7"; }
+
+.ion-scissors:before { content: "\f34b"; }
+
+.ion-search:before { content: "\f21f"; }
+
+.ion-settings:before { content: "\f2ad"; }
+
+.ion-share:before { content: "\f220"; }
+
+.ion-shuffle:before { content: "\f221"; }
+
+.ion-skip-backward:before { content: "\f222"; }
+
+.ion-skip-forward:before { content: "\f223"; }
+
+.ion-social-android:before { content: "\f225"; }
+
+.ion-social-android-outline:before { content: "\f224"; }
+
+.ion-social-angular:before { content: "\f4d9"; }
+
+.ion-social-angular-outline:before { content: "\f4d8"; }
+
+.ion-social-apple:before { content: "\f227"; }
+
+.ion-social-apple-outline:before { content: "\f226"; }
+
+.ion-social-bitcoin:before { content: "\f2af"; }
+
+.ion-social-bitcoin-outline:before { content: "\f2ae"; }
+
+.ion-social-buffer:before { content: "\f229"; }
+
+.ion-social-buffer-outline:before { content: "\f228"; }
+
+.ion-social-chrome:before { content: "\f4db"; }
+
+.ion-social-chrome-outline:before { content: "\f4da"; }
+
+.ion-social-codepen:before { content: "\f4dd"; }
+
+.ion-social-codepen-outline:before { content: "\f4dc"; }
+
+.ion-social-css3:before { content: "\f4df"; }
+
+.ion-social-css3-outline:before { content: "\f4de"; }
+
+.ion-social-designernews:before { content: "\f22b"; }
+
+.ion-social-designernews-outline:before { content: "\f22a"; }
+
+.ion-social-dribbble:before { content: "\f22d"; }
+
+.ion-social-dribbble-outline:before { content: "\f22c"; }
+
+.ion-social-dropbox:before { content: "\f22f"; }
+
+.ion-social-dropbox-outline:before { content: "\f22e"; }
+
+.ion-social-euro:before { content: "\f4e1"; }
+
+.ion-social-euro-outline:before { content: "\f4e0"; }
+
+.ion-social-facebook:before { content: "\f231"; }
+
+.ion-social-facebook-outline:before { content: "\f230"; }
+
+.ion-social-foursquare:before { content: "\f34d"; }
+
+.ion-social-foursquare-outline:before { content: "\f34c"; }
+
+.ion-social-freebsd-devil:before { content: "\f2c4"; }
+
+.ion-social-github:before { content: "\f233"; }
+
+.ion-social-github-outline:before { content: "\f232"; }
+
+.ion-social-google:before { content: "\f34f"; }
+
+.ion-social-google-outline:before { content: "\f34e"; }
+
+.ion-social-googleplus:before { content: "\f235"; }
+
+.ion-social-googleplus-outline:before { content: "\f234"; }
+
+.ion-social-hackernews:before { content: "\f237"; }
+
+.ion-social-hackernews-outline:before { content: "\f236"; }
+
+.ion-social-html5:before { content: "\f4e3"; }
+
+.ion-social-html5-outline:before { content: "\f4e2"; }
+
+.ion-social-instagram:before { content: "\f351"; }
+
+.ion-social-instagram-outline:before { content: "\f350"; }
+
+.ion-social-javascript:before { content: "\f4e5"; }
+
+.ion-social-javascript-outline:before { content: "\f4e4"; }
+
+.ion-social-linkedin:before { content: "\f239"; }
+
+.ion-social-linkedin-outline:before { content: "\f238"; }
+
+.ion-social-markdown:before { content: "\f4e6"; }
+
+.ion-social-nodejs:before { content: "\f4e7"; }
+
+.ion-social-octocat:before { content: "\f4e8"; }
+
+.ion-social-pinterest:before { content: "\f2b1"; }
+
+.ion-social-pinterest-outline:before { content: "\f2b0"; }
+
+.ion-social-python:before { content: "\f4e9"; }
+
+.ion-social-reddit:before { content: "\f23b"; }
+
+.ion-social-reddit-outline:before { content: "\f23a"; }
+
+.ion-social-rss:before { content: "\f23d"; }
+
+.ion-social-rss-outline:before { content: "\f23c"; }
+
+.ion-social-sass:before { content: "\f4ea"; }
+
+.ion-social-skype:before { content: "\f23f"; }
+
+.ion-social-skype-outline:before { content: "\f23e"; }
+
+.ion-social-snapchat:before { content: "\f4ec"; }
+
+.ion-social-snapchat-outline:before { content: "\f4eb"; }
+
+.ion-social-tumblr:before { content: "\f241"; }
+
+.ion-social-tumblr-outline:before { content: "\f240"; }
+
+.ion-social-tux:before { content: "\f2c5"; }
+
+.ion-social-twitch:before { content: "\f4ee"; }
+
+.ion-social-twitch-outline:before { content: "\f4ed"; }
+
+.ion-social-twitter:before { content: "\f243"; }
+
+.ion-social-twitter-outline:before { content: "\f242"; }
+
+.ion-social-usd:before { content: "\f353"; }
+
+.ion-social-usd-outline:before { content: "\f352"; }
+
+.ion-social-vimeo:before { content: "\f245"; }
+
+.ion-social-vimeo-outline:before { content: "\f244"; }
+
+.ion-social-whatsapp:before { content: "\f4f0"; }
+
+.ion-social-whatsapp-outline:before { content: "\f4ef"; }
+
+.ion-social-windows:before { content: "\f247"; }
+
+.ion-social-windows-outline:before { content: "\f246"; }
+
+.ion-social-wordpress:before { content: "\f249"; }
+
+.ion-social-wordpress-outline:before { content: "\f248"; }
+
+.ion-social-yahoo:before { content: "\f24b"; }
+
+.ion-social-yahoo-outline:before { content: "\f24a"; }
+
+.ion-social-yen:before { content: "\f4f2"; }
+
+.ion-social-yen-outline:before { content: "\f4f1"; }
+
+.ion-social-youtube:before { content: "\f24d"; }
+
+.ion-social-youtube-outline:before { content: "\f24c"; }
+
+.ion-soup-can:before { content: "\f4f4"; }
+
+.ion-soup-can-outline:before { content: "\f4f3"; }
+
+.ion-speakerphone:before { content: "\f2b2"; }
+
+.ion-speedometer:before { content: "\f2b3"; }
+
+.ion-spoon:before { content: "\f2b4"; }
+
+.ion-star:before { content: "\f24e"; }
+
+.ion-stats-bars:before { content: "\f2b5"; }
+
+.ion-steam:before { content: "\f30b"; }
+
+.ion-stop:before { content: "\f24f"; }
+
+.ion-thermometer:before { content: "\f2b6"; }
+
+.ion-thumbsdown:before { content: "\f250"; }
+
+.ion-thumbsup:before { content: "\f251"; }
+
+.ion-toggle:before { content: "\f355"; }
+
+.ion-toggle-filled:before { content: "\f354"; }
+
+.ion-transgender:before { content: "\f4f5"; }
+
+.ion-trash-a:before { content: "\f252"; }
+
+.ion-trash-b:before { content: "\f253"; }
+
+.ion-trophy:before { content: "\f356"; }
+
+.ion-tshirt:before { content: "\f4f7"; }
+
+.ion-tshirt-outline:before { content: "\f4f6"; }
+
+.ion-umbrella:before { content: "\f2b7"; }
+
+.ion-university:before { content: "\f357"; }
+
+.ion-unlocked:before { content: "\f254"; }
+
+.ion-upload:before { content: "\f255"; }
+
+.ion-usb:before { content: "\f2b8"; }
+
+.ion-videocamera:before { content: "\f256"; }
+
+.ion-volume-high:before { content: "\f257"; }
+
+.ion-volume-low:before { content: "\f258"; }
+
+.ion-volume-medium:before { content: "\f259"; }
+
+.ion-volume-mute:before { content: "\f25a"; }
+
+.ion-wand:before { content: "\f358"; }
+
+.ion-waterdrop:before { content: "\f25b"; }
+
+.ion-wifi:before { content: "\f25c"; }
+
+.ion-wineglass:before { content: "\f2b9"; }
+
+.ion-woman:before { content: "\f25d"; }
+
+.ion-wrench:before { content: "\f2ba"; }
+
+.ion-xbox:before { content: "\f30c"; }
diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css
index aa21f9b..7ae4a1e 100644
--- a/public/assets/stylesheets/staff.css
+++ b/public/assets/stylesheets/staff.css
@@ -28,15 +28,33 @@ nav {
text-align: left;
}
nav a {
- padding-left: 20px;
+ margin-left: 10px;
+}
+nav.subnav {
+ background: white;
+ padding: 10px;
+ font-weight: 200;
+ font-size: 12px;
+}
+.alphabet a {
+ margin-left: 5px;
+}
+.body .error {
+ color: #f00;
+ border: 1px solid #f00;
+ margin: 20px 5px 200px 5px;
+ padding: 10px;
+ width: 400px;
+ display: block;
}
hr {
border: 1px solid #bbb;
- margin: 5px auto 10px;
+ margin: 10px auto 10px;
+ background: transparent;
}
.body {
width: 80%;
- margin: 0 auto;
+ margin: 40px auto;
}
.json {
display: none;
@@ -61,10 +79,35 @@ hr {
user-select: none;
}
.staff {
+ background: white;
font-size: 15px;
}
-.staff .editLinks a {
+.staff hr {
+ border: 1px solid black;
+ border-top: 0;
+}
+.staff .body a {
+ border-bottom: 1px dotted;
+}
+.staff .editLinks a, .staff a.bluelink {
color: #00f;
+ border-bottom: 1px solid;
+}
+.staff form {
+ max-width: none;
+ width: 600px;
+ padding: 20px;
+}
+.staff form label {
+ float: none;
+}
+.staff form p {
+ width: 350px;
+ margin: 5px 0;
+ color: #444;
+}
+.staff form div li {
+ width: 180px;
}
#iframe-embed, #iframe-embed tr, #iframe-embed td {
width: 79vw;
diff --git a/public/assets/test/bg.html b/public/assets/test/bg.html
new file mode 100644
index 0000000..65dd5d9
--- /dev/null
+++ b/public/assets/test/bg.html
@@ -0,0 +1,115 @@
+<div id="scene"></div>
+<div style="position:fixed;top:419px;left:10px;">
+<input id="url" value="http://i.asdf.us/im/97/imgrid_1400887539_xx_abridged___dmgk.png">
+<input id="scale" type="range" min="0.01" max="10.0" step="0.1" value="1.0">
+<div id="cursor" style="width:30px;height:30px;background:blue;display:inline-block;"></div>
+</div>
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/vendor/loader.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/surface.js"></script>
+<script>
+
+var w = scene.width = 600
+var h = scene.height = 400
+
+var surface = new Surface ()
+surface.add( new Rect( new vec2(10, 100), new vec2(0, 400) ) )
+surface.add( new Rect( new vec2(100, 300), new vec2(200, 400) ) )
+surface.add( new Rect( new vec2(300, 400), new vec2(0, 300) ) )
+surface.add( new Rect( new vec2(400, 500), new vec2(0, 400) ) )
+
+var colors = "#f00 #ff0 #0ff #00f #f0f".split(" ")
+surface.faces.forEach(function(face, i){
+ var el = document.createElement("div")
+ el.style.position = "absolute"
+ el.style.backgroundColor = colors[i%colors.length]
+ el.style.top = face.y.a + "px"
+ el.style.left = face.x.a + "px"
+ el.style.width = face.width() + "px"
+ el.style.height = face.height() + "px"
+ scene.appendChild(el)
+ face.el = el
+})
+
+url.addEventListener("input", updateBackgroundImage)
+scale.addEventListener("input", updateScale)
+
+var bg_w = 1, bg_h = 1, x = 0, y = 0, s = 1
+function updateBackgroundImage(){
+ var img = new Image ()
+ img.onload = function(){
+ x0 = 0
+ y0 = 0
+ bg_w = img.naturalWidth
+ bg_h = img.naturalHeight
+ surface.faces.forEach(function(face, i){
+ face.el.style.backgroundImage = 'url(' + url.value + ')'
+ })
+ update(x,y,bg_w,bg_h)
+ }
+ img.src = url.value
+ img.complete && img.onload()
+}
+function update(x,y,w,h){
+ dx = x
+ dy = y
+ surface.faces.forEach(function(face, i){
+ dx = x-face.x.a
+ dy = y-face.y.a
+ face.el.style.backgroundPosition = dx + 'px ' + dy + 'px'
+ face.el.style.backgroundSize = w*s + 'px ' + h*s + 'px'
+// console.log(x,y,' ',dx,dy)
+ })
+}
+updateBackgroundImage()
+
+function updateScale(){
+ s = parseFloat(scale.value)
+ console.log(scale.value, s)
+ update(x,y,bg_w,bg_h)
+}
+
+var leftOffset = 0
+
+var position = new vec2( 40, 40 )
+var dimension = new vec2( 50, 80 )
+var bounds = surface.bounds_at_index_with_dimensions(0, dimension)
+
+var delta = new vec2( 0, 0 )
+
+var dragging = false
+
+var x0 = 0, y0 = 0
+var mymouse = new mouse({
+ el: cursor,
+ down: function(e, cursor){
+ console.log(cursor.x.a, cursor.y.a)
+ dragging = true
+ },
+ drag: function(e, cursor){
+ if (! dragging) return
+ delta = cursor.delta()
+ delta.a = - delta.a
+ x0 = delta.a*s
+ y0 = delta.b*s
+// console.log(x0,y0)
+ update(x+x0,y+y0,bg_w,bg_h)
+ },
+ up: function(e, cursor, new_cursor){
+ x += delta.a*s
+ y += delta.b*s
+ delta.zero()
+ dragging = false
+ },
+})
+
+
+
+
+</script>
diff --git a/public/assets/test/intersect.html b/public/assets/test/intersect.html
new file mode 100644
index 0000000..92f1d5d
--- /dev/null
+++ b/public/assets/test/intersect.html
@@ -0,0 +1,140 @@
+<canvas id="canvas"></canvas>
+<div id="hud"></div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/vendor/canvasutilities.js"></script>
+<script>
+
+var w = canvas.width = 600
+var h = canvas.height = 400
+
+var ctx = canvas.getContext('2d')
+
+var vec_a = new Rect( 100, 120, 50, 100 )
+var vec_b = new Rect( 20, 200, 120, 120 )
+var vecs = [ vec_a, vec_b ]
+var points = [ vec_a.x, vec_a.y, vec_b.x, vec_b.y ]
+var r = 4
+
+var vec_c = new Rect()
+vec_c.x = vec_a.x
+vec_c.y = vec_b.x
+
+var intersect = new vec2 ()
+
+var dragging = false, dragging_a, dragging_b
+var delta = new vec2( 0, 0 )
+
+var mymouse = new mouse({
+ el: canvas,
+ down: function(e, cursor){
+ points.some(function(p){
+ if (-cursor.x.a > p.a - r && -cursor.x.a < p.a + r &&
+ cursor.y.a > p.b - r && cursor.y.a < p.b + r) {
+ dragging_a = p.a
+ dragging_b = p.b
+ dragging = p
+ return true
+ }
+ })
+ },
+ drag: function(e, cursor){
+ if (! dragging) return
+ delta = cursor.delta()
+ delta.a = - delta.a
+ dragging.a = dragging_a + delta.a
+ dragging.b = dragging_b + delta.b
+ },
+ up: function(e, cursor, new_cursor){
+ delta.zero()
+ dragging.dragging = false
+ dragging = false
+ },
+})
+
+function draw () {
+ ctx.fillStyle = "#fff"
+ ctx.fillRect(0,0,w,h)
+
+ ctx.fillStyle = "#bbb"
+ points.forEach(drawPoint)
+
+ drawLine(vec_a.x, vec_a.y, "#f00")
+ drawLine(vec_b.x, vec_b.y, "#00f")
+ drawLine(vec_a.x, vec_b.x, "#080")
+
+ var t = perp(vec_c, vec_b) / ( perp(vec_a, vec_b) || 0.0000001 )
+ intersect.a = vec_a.x.a + ( vec_a.y.a - vec_a.x.a ) * t
+ intersect.b = vec_a.x.b + ( vec_a.y.b - vec_a.x.b ) * t
+
+ var collinear = is_collinear( intersect, vec_b )
+ var long_enough_to_intersect = 0 <= t && t <= 1
+ var msg
+
+ if (long_enough_to_intersect && collinear) {
+ ctx.fillStyle = "#f00"
+ msg = "through"
+ }
+ else if (collinear) {
+ ctx.fillStyle = "#0f0"
+ msg = "to"
+ }
+ else {
+ ctx.fillStyle = "#000"
+ msg = "off"
+ }
+ hud.innerHTML = [intersect.exactString(), vec_b.exactString(), msg].join("<br>")
+
+ drawPoint(intersect)
+}
+function drawLine (pa, pb, color) {
+ ctx.fillStyle = color
+ ctx.strokeStyle = color
+ var x1 = pa.a
+ var y1 = pa.b
+ var x2 = pb.a
+ var y2 = pb.b
+ drawArrow(ctx, x1, y1, x2, y2)
+}
+function drawPoint (p) {
+ var x = p.a - r
+ var y = p.b - r
+ ctx.fillRect(x, y, r*2, r*2)
+}
+function perp (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a)
+}
+function is_collinear (p, vec) {
+ var on_x, on_y
+ var pa = round(p.a), pb = round(p.b)
+
+ if (vec.x.a < vec.y.a) {
+ on_x = vec.x.a <= pa && pa <= vec.y.a
+ }
+ else {
+ on_x = vec.x.a >= pa && pa >= vec.y.a
+ }
+
+ if (vec.x.b < vec.y.b) {
+ on_y = vec.x.b <= pb && pb <= vec.y.b
+ }
+ else {
+ on_y = vec.x.b >= pb && pb >= vec.y.b
+ }
+
+ return !! (on_x && on_y)
+}
+
+function animate(){
+ requestAnimationFrame(animate)
+ draw()
+}
+animate()
+
+</script>
diff --git a/public/assets/test/intersect2.html b/public/assets/test/intersect2.html
new file mode 100644
index 0000000..553e2f7
--- /dev/null
+++ b/public/assets/test/intersect2.html
@@ -0,0 +1,220 @@
+<style>
+body,html{margin:0;padding:0;}
+#hud { position: absolute; top: 0; left: 0; pointer-events: none; }
+</style>
+<canvas id="canvas"></canvas>
+<div id="hud"></div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/sort.js"></script>
+<script src="/assets/javascripts/rectangles/util/uid.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/room.js"></script>
+<script src="/assets/javascripts/rectangles/models/surface.js"></script>
+<script src="/assets/javascripts/rectangles/models/wall.js"></script>
+<script src="/assets/javascripts/rectangles/models/floor.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/_rooms.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/_walls.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/clipper.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/builder.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/grouper.js"></script>
+<script src="/assets/javascripts/vendor/canvasutilities.js"></script>
+<script>
+
+var w = canvas.width = window.innerWidth
+var h = canvas.height = window.innerHeight
+
+var ctx = canvas.getContext('2d')
+var scene = new MX.Scene()
+
+var cursor = new Rect( 150, 250, 150, 250 )
+var wall_vec = new Rect ( 0, 0, 0, 0 )
+var points = [ cursor.x, cursor.y ]
+
+var origins = new Rect()
+origins.x = cursor.x
+origins.y = wall_vec.x
+
+var radius = 1
+
+var rect = new Rect( new vec2(100,400), new vec2(100,400) )
+var east = new Rect( new vec2(200,600), new vec2(100,400) )
+var corner = new Rect( new vec2(300,700), new vec2(300,700) )
+var peninsula = new Rect( new vec2(400,600), new vec2(600,800) )
+var peninsula2 = new Rect( new vec2(650,750), new vec2(350,450) )
+
+var rect_room = new Room({ id: "rect", rect: rect, height: 2 })
+var east_room = new Room({ id: "east", rect: east, height: 2 })
+var corner_room = new Room({ id: "corner", rect: corner, height: 2 })
+var peninsula_room = new Room({ id: "peninsula", rect: peninsula, height: 3 })
+var peninsula2_room = new Room({ id: "peninsula2", rect: peninsula2, height: 1 })
+
+Rooms.add( rect_room )
+Rooms.add( east_room )
+Rooms.add( corner_room )
+Rooms.add( peninsula_room )
+Rooms.add( peninsula2_room )
+
+Rooms.clipper.update()
+Rooms.builder.build()
+Rooms.grouper.build()
+
+var r = 4
+
+var intersect = new vec2 ()
+
+var dragging = false, dragging_a, dragging_b
+var delta = new vec2( 0, 0 )
+
+var mymouse = new mouse({
+ el: canvas,
+ down: function(e, cursor){
+ points.some(function(p){
+ if (-cursor.x.a > p.a - r && -cursor.x.a < p.a + r &&
+ cursor.y.a > p.b - r && cursor.y.a < p.b + r) {
+ dragging_a = p.a
+ dragging_b = p.b
+ dragging = p
+ return true
+ }
+ })
+ },
+ drag: function(e, cursor){
+ if (! dragging) return
+ delta = cursor.delta()
+ delta.a = - delta.a
+ dragging.a = dragging_a + delta.a
+ dragging.b = dragging_b + delta.b
+ },
+ up: function(e, cursor, new_cursor){
+ delta.zero()
+ dragging.dragging = false
+ dragging = false
+ },
+})
+
+function draw () {
+ ctx.fillStyle = "#fff"
+ ctx.fillRect(0,0,w,h)
+
+ Rooms.forEach(function(room, i){
+ ctx.fillStyle = "#eee"
+ ctx.fillRect(room.rect.x.a, room.rect.y.a, room.rect.width(), room.rect.height())
+ })
+
+ ctx.fillStyle = "#333"
+ points.forEach(drawPoint)
+
+ drawLine(cursor.x, cursor.y, "#f00")
+ hud.innerHTML = ""
+ Walls.list.forEach(function(wall, i){
+ if (wall.side & LEFT_RIGHT) {
+ wall_vec.x.a = wall.edge
+ wall_vec.x.b = wall.vec.a
+ wall_vec.y.a = wall.edge
+ wall_vec.y.b = wall.vec.b
+ }
+ else {
+ wall_vec.x.a = wall.vec.a
+ wall_vec.x.b = wall.edge
+ wall_vec.y.a = wall.vec.b
+ wall_vec.y.b = wall.edge
+ }
+ drawLine(wall_vec.x, wall_vec.y, "#888", true)
+ drawLine(origins.x, origins.y, "rgba(0,0,0,0.1)")
+
+ var t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 )
+ intersect.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * t
+ intersect.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * t
+
+ var collinear = is_collinear( intersect, wall_vec )
+ var long_enough_to_intersect = 0 <= t && t <= 1
+ var actually_intersects = false
+ var intersecting_face
+ var msg
+
+ if (long_enough_to_intersect && collinear) {
+ if (wall.side & LEFT_RIGHT) {
+ intersecting_face = wall.surface.face_for_x(intersect.b)
+ }
+ else {
+ intersecting_face = wall.surface.face_for_x(intersect.a)
+ }
+ actually_intersects = !! (intersecting_face && intersecting_face.y.a == 0)
+ }
+
+ if (actually_intersects) {
+ ctx.fillStyle = "#f00"
+ msg = "through"
+ }
+ else if (collinear) {
+ ctx.fillStyle = "#0f0"
+ msg = "to"
+ }
+ else {
+ ctx.fillStyle = "rgba(0,0,0,0.1)"
+ msg = "off"
+ }
+
+ drawPoint(intersect)
+ if (intersecting_face) {
+ hud.innerHTML += intersecting_face.y.a + "<br>"
+ }
+ })
+
+}
+function drawLine (pa, pb, color, headless) {
+ ctx.fillStyle = color
+ ctx.strokeStyle = color
+ var x1 = pa.a
+ var y1 = pa.b
+ var x2 = pb.a
+ var y2 = pb.b
+ drawArrow(ctx, x1, y1, x2, y2, 3, headless ? 0 : 1)
+}
+function drawPoint (p) {
+ var x = p.a - r
+ var y = p.b - r
+ ctx.fillRect(x, y, r*2, r*2)
+}
+function perp (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a)
+}
+function is_collinear (p, vec) {
+ var on_x, on_y
+ var pa = round(p.a), pb = round(p.b)
+
+ if (vec.x.a < vec.y.a) {
+ on_x = vec.x.a <= pa && pa <= vec.y.a
+ }
+ else {
+ on_x = vec.x.a >= pa && pa >= vec.y.a
+ }
+
+ if (vec.x.b < vec.y.b) {
+ on_y = vec.x.b <= pb && pb <= vec.y.b
+ }
+ else {
+ on_y = vec.x.b >= pb && pb >= vec.y.b
+ }
+
+ return !! (on_x && on_y)
+}
+
+function animate(){
+ requestAnimationFrame(animate)
+ draw()
+}
+animate()
+
+</script>
diff --git a/public/assets/test/intersect3.html b/public/assets/test/intersect3.html
new file mode 100644
index 0000000..b8f9a0d
--- /dev/null
+++ b/public/assets/test/intersect3.html
@@ -0,0 +1,320 @@
+<style>
+body,html{margin:0;padding:0;}
+#hud { position: absolute; top: 0; left: 0; pointer-events: none; }
+</style>
+<canvas id="canvas"></canvas>
+<div id="hud"></div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/sort.js"></script>
+<script src="/assets/javascripts/rectangles/util/uid.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/room.js"></script>
+<script src="/assets/javascripts/rectangles/models/surface.js"></script>
+<script src="/assets/javascripts/rectangles/models/wall.js"></script>
+<script src="/assets/javascripts/rectangles/models/floor.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/_rooms.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/_walls.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/clipper.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/builder.js"></script>
+<script src="/assets/javascripts/rectangles/engine/rooms/grouper.js"></script>
+<script src="/assets/javascripts/vendor/canvasutilities.js"></script>
+<script>
+
+var w = canvas.width = window.innerWidth
+var h = canvas.height = window.innerHeight
+
+var ctx = canvas.getContext('2d')
+var scene = new MX.Scene()
+
+var cursor = new Rect( new vec2(400, 200), new vec2(800, 500) )
+var wall_vec = new Rect ( 0, 0, 0, 0 )
+var points = [ cursor.x, cursor.y ]
+
+var origins = new Rect()
+origins.x = cursor.x
+origins.y = wall_vec.x
+
+scene.camera.radius = 20
+
+var rect = new Rect( new vec2(100,400), new vec2(100,400) )
+var east = new Rect( new vec2(200,600), new vec2(100,400) )
+var corner = new Rect( new vec2(300,700), new vec2(300,700) )
+var peninsula = new Rect( new vec2(400,600), new vec2(600,800) )
+var peninsula2 = new Rect( new vec2(650,750), new vec2(350,450) )
+
+var rect_room = new Room({ id: "rect", rect: rect, height: 2 })
+var east_room = new Room({ id: "east", rect: east, height: 2 })
+var corner_room = new Room({ id: "corner", rect: corner, height: 2 })
+var peninsula_room = new Room({ id: "peninsula", rect: peninsula, height: 3 })
+var peninsula2_room = new Room({ id: "peninsula2", rect: peninsula2, height: 1 })
+
+Rooms.add( rect_room )
+Rooms.add( east_room )
+Rooms.add( corner_room )
+Rooms.add( peninsula_room )
+Rooms.add( peninsula2_room )
+
+Rooms.clipper.update()
+Rooms.builder.build()
+Rooms.grouper.build()
+
+var r = 6
+
+var intersect = new vec2 ()
+
+var dragging = false, dragging_a, dragging_b
+var delta = new vec2( 0, 0 )
+
+var mymouse = new mouse({
+ el: canvas,
+ down: function(e, cursor){
+ points.some(function(p){
+ if (-cursor.x.a > p.a - r && -cursor.x.a < p.a + r &&
+ cursor.y.a > p.b - r && cursor.y.a < p.b + r) {
+ dragging_a = p.a
+ dragging_b = p.b
+ dragging = p
+ return true
+ }
+ })
+ },
+ drag: function(e, cursor){
+ if (! dragging) return
+ delta = cursor.delta()
+ delta.a = - delta.a
+ dragging.a = dragging_a + delta.a
+ dragging.b = dragging_b + delta.b
+ },
+ up: function(e, cursor, new_cursor){
+ delta.zero()
+ dragging.dragging = false
+ dragging = false
+ },
+})
+
+function draw (time) {
+ ctx.fillStyle = "#fff"
+ ctx.fillRect(0,0,w,h)
+
+ Rooms.forEach(function(room, i){
+ ctx.fillStyle = "#eee"
+ ctx.fillRect(room.rect.x.a, room.rect.y.a, room.rect.width(), room.rect.height())
+ })
+
+ ctx.fillStyle = "#333"
+ points.forEach(drawPoint)
+
+ drawLine(cursor.x, cursor.y, "#f00")
+// hud.innerHTML = ""
+ var closest_intersect, t, min_t = 1
+ var cursor_copy = cursor.extend_ends(scene.camera.radius)
+
+ hud.innerHTML = cursor_copy.x
+ drawPoint(cursor_copy.x, "#ff0")
+
+ Walls.list.forEach(function(wall, i){
+ wall.get_points(wall_vec)
+ drawLine(wall_vec.x, wall_vec.y, "#088")
+
+ origins.x = cursor_copy.x
+ origins.y = wall_vec.x
+
+ t = perp(origins, wall_vec) / ( perp(cursor_copy, wall_vec) || 0.0000001 )
+ intersect.a = cursor_copy.x.a + ( cursor_copy.y.a - cursor_copy.x.a ) * t
+ intersect.b = cursor_copy.x.b + ( cursor_copy.y.b - cursor_copy.x.b ) * t
+
+ var collinear = is_collinear( intersect, wall_vec )
+ var long_enough_to_intersect = 0 <= t && t <= 1
+ var actually_intersects = false
+ var intersecting_face
+ var msg
+
+ if (long_enough_to_intersect && collinear) {
+ if (wall.side & LEFT_RIGHT) {
+ intersecting_face = wall.surface.face_for_x(intersect.b)
+ }
+ else {
+ intersecting_face = wall.surface.face_for_x(intersect.a)
+ }
+ actually_intersects = !! (intersecting_face && intersecting_face.y.a == 0)
+ }
+
+ if (actually_intersects) {
+ ctx.fillStyle = "#f00"
+ msg = "through"
+ }
+ else if (collinear) {
+ ctx.fillStyle = "#0f0"
+ msg = "to"
+ }
+ else {
+ ctx.fillStyle = "rgba(0,0,0,0.1)"
+ msg = "off"
+ }
+
+ drawPoint(intersect)
+ if (actually_intersects && t < min_t) {
+ min_t = t
+ closest_intersect = intersect.clone()
+ closest_wall = wall_vec.clone()
+ }
+ })
+
+ if (closest_intersect) {
+ var a = angle(closest_wall)
+ wall_vec.assign(closest_wall)
+ wall_vec.x.a -= scene.camera.radius * sin(a)
+ wall_vec.x.b += scene.camera.radius * cos(a)
+ wall_vec.y.a -= scene.camera.radius * sin(a)
+ wall_vec.y.b += scene.camera.radius * cos(a)
+
+ drawLine(wall_vec.x, wall_vec.y, "rgba(0,255,255,1.0)")
+
+ origins.x = cursor.x
+ origins.y = wall_vec.x
+
+ var new_t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 )
+ var wall_t = perp(origins, cursor) / ( perp(wall_vec, cursor) || 0.0000001 )
+
+ var closest_intersect2 = new vec2 ()
+ closest_intersect2.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * new_t
+ closest_intersect2.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * new_t
+
+ ctx.fillStyle = "#0ff"
+ drawPoint(closest_intersect2)
+ drawLine(cursor.x, closest_intersect2, "#00f")
+
+ var len = sqrt(dot(wall_vec, wall_vec))
+
+ // here compare len to the length of the wall in the direction we are travelling
+ var aw = angle(closest_wall)
+ var dd = dot2(diff(closest_wall), diff(cursor))
+
+// hud.innerHTML += " " + dd + " " + round(deg(aw))
+ if (dd > 0) {
+ len *= 1-abs(wall_t)
+ }
+ else {
+ len *= abs(wall_t)
+ aw += PI
+ }
+
+ len = clamp(len, 0, (1-min_t) * sqrt(dot(cursor, cursor)))
+
+// hud.innerHTML = [ aw ].map(function(n){ return round(deg(n)) })
+// hud.innerHTML += "__&nbsp;" + (dd > 0 ? "gt": "lt") + " " + round(len) + " " + (1-min_t) + " " + round((1-min_t)*sqrt(dot2(diff(cursor), diff(cursor))))
+
+ var end_of_ray = closest_intersect2.clone()
+ end_of_ray.a += len * cos(aw)
+ end_of_ray.b += len * sin(aw)
+
+ wall_vec.normalize()
+ end_of_ray.a = clamp(end_of_ray.a, wall_vec.x.a, wall_vec.y.a)
+ end_of_ray.b = clamp(end_of_ray.b, wall_vec.x.b, wall_vec.y.b)
+
+ drawPoint(end_of_ray)
+ drawLine(closest_intersect2, end_of_ray, "#00f")
+ }
+ else {
+// hud.innerHTML = [ (angle(cursor) + TWO_PI) % TWO_PI ].map(function(n){ return round(deg(n)) })
+ }
+
+}
+function drawLine (pa, pb, color, headless) {
+ ctx.fillStyle = color
+ ctx.strokeStyle = color
+ var x1 = pa.a
+ var y1 = pa.b
+ var x2 = pb.a
+ var y2 = pb.b
+ drawArrow(ctx, x1, y1, x2, y2, 3, headless ? 0 : 1)
+}
+function drawPoint (p, color) {
+ if (color) {
+ ctx.fillStyle = color
+ }
+ var x = p.a - r
+ var y = p.b - r
+ ctx.fillRect(x, y, r*2, r*2)
+}
+function angle (va) {
+ return atan2(va.y.b - va.x.b, va.y.a - va.x.a)
+}
+function angle2 (pa, pb) {
+ return atan2(pb.b - pa.b, pb.a - pa.a)
+}
+function normal (va) {
+ return atan2(va.x.a - va.y.a, va.y.b - va.x.b)
+}
+function dot (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.a - vb.x.a) + (va.y.b - va.x.b) * (vb.y.b - vb.x.b)
+}
+function diff (v) {
+ return new vec2(v.y.a - v.x.a, v.y.b - v.x.b)
+}
+function dot2 (pa, pb) {
+ return pa.a * pb.a + pa.b * pb.b
+}
+function perp (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a)
+}
+function is_collinear (p, vec) {
+ var on_x, on_y
+ var pa = round(p.a), pb = round(p.b)
+
+ if (vec.x.a < vec.y.a) {
+ on_x = vec.x.a <= pa && pa <= vec.y.a
+ }
+ else {
+ on_x = vec.x.a >= pa && pa >= vec.y.a
+ }
+
+ if (vec.x.b < vec.y.b) {
+ on_y = vec.x.b <= pb && pb <= vec.y.b
+ }
+ else {
+ on_y = vec.x.b >= pb && pb >= vec.y.b
+ }
+
+ return !! (on_x && on_y)
+}
+cursor.extend_ends = function(n){
+ var a = angle(this)
+ var clone = this.clone()
+ clone.x.a -= n*cos(a)
+ clone.x.b -= n*sin(a)
+ clone.y.a += n*cos(a)
+ clone.y.b += n*sin(a)
+ return clone
+}
+wall_vec.normalize = function(){
+ var carry
+ if (this.x.a > this.y.a) {
+ carry = this.x.a
+ this.x.a = this.y.a
+ this.y.a = carry
+ }
+ if (this.x.b > this.y.b) {
+ carry = this.x.b
+ this.x.b = this.y.b
+ this.y.b = carry
+ }
+}
+function animate(time){
+ requestAnimationFrame(animate)
+ draw(time)
+}
+animate()
+
+</script>
diff --git a/public/assets/test/orbit.html b/public/assets/test/orbit.html
new file mode 100644
index 0000000..0416ff7
--- /dev/null
+++ b/public/assets/test/orbit.html
@@ -0,0 +1,154 @@
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ font-family: Menlo, monospace;
+ overflow: hidden;
+}
+#perspective {
+ position: absolute;
+ left:0%;
+ top:0px
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+#hud {
+ white-space: pre;
+}
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div id="hud"></div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+
+<script>
+
+Map.UI = Map.UI || {}
+Map.UI.Ortho = function(map){
+
+ var base = this
+
+ base.creating = base.dragging = base.resizing = false
+
+ base.mouse = new mouse({
+ el: map.el,
+ move: function(e, cursor){
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
+ },
+ })
+}
+
+var scene, map, controls
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+})
+
+var ctx = map.draw.ctx
+
+document.addEventListener('DOMContentLoaded', build_circle)
+function add_mx_point (p, theta, i) {
+ var mx = new MX.Object3D()
+ mx.updateChildren = false
+ mx.move({
+ x: p.a,
+ y: i/2,
+ z: p.b,
+ rotationY: -theta,
+ width: 1,
+ height: i,
+ })
+ mx.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')'
+ mx.el.style.backfaceVisibility = "visible"
+ scene.add(mx)
+ mx.update()
+}
+function add_center () {
+ var mx = new MX.Object3D()
+ mx.width = 79
+ mx.height = 64
+ mx.y = 32 * 0.05
+ mx.scale = 0.05
+ mx.el.style.backgroundImage = "url(http://i.asdf.us/im/b8/_1400215546_frankhats_1400215573_frankhats.gif)"
+ scene.add(mx)
+}
+function build_circle () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.move({
+ "x": 0,
+ "y": 0,
+ "z": 0,
+ "rotationX": 0, // PI/2,
+ "rotationY": PI/2, // PI
+ })
+ scene.camera.radius = 20
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ var theta, rad = 16;
+ for (var i = 0; i < 100; i++) {
+ theta = (i/100 * TWO_PI)
+ add_mx_point({
+ a: sin(theta) * rad,
+ b: cos(theta) * rad,
+ }, theta, i)
+ }
+
+ add_center()
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({ el: document.querySelector("#perspective") })
+ controls.init()
+
+ console.log("ready..perhaps")
+ animate(0)
+}
+function animate(time){
+ requestAnimationFrame(animate)
+ map.update(time)
+
+ controls.update()
+ hud.innerHTML = scene.camera.toString()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ map.draw.coords()
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/ortho.html b/public/assets/test/ortho.html
new file mode 100644
index 0000000..2257006
--- /dev/null
+++ b/public/assets/test/ortho.html
@@ -0,0 +1,290 @@
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ font-family: Menlo, monospace;
+ overflow: hidden;
+}
+#perspective {
+ position: absolute;
+ left:0%;
+ top:0px
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+#hud {
+ white-space: pre;
+}
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div id="hud"></div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+
+<script>
+
+Map.UI = Map.UI || {}
+Map.UI.Ortho = function(map){
+
+ var base = this
+
+ base.creating = base.dragging = base.resizing = false
+
+ base.mouse = new mouse({
+ el: map.el,
+ down: function(e, cursor){
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
+ // compare to initial point
+ var p = new vec2( cursor.x.a, cursor.y.a )
+ if (placing) {
+ if (points.length > 2 && points[0].distanceTo( p ) < 10/map.zoom) {
+ points.push( points[0].clone() )
+ placing = false
+ add_mx_polyline(points)
+ }
+ else {
+ points.push( p )
+ mx_points.push( add_mx_point(p) )
+ }
+ }
+ else {
+ placing = true
+ points = []
+ points.push( p )
+ mx_points.push( add_mx_point(p) )
+ }
+ },
+ move: function(e, cursor){
+ cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a)
+ cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
+ last_point = new vec2( cursor.x.a, cursor.y.a )
+ if (placing && points.length > 1 && points[0].distanceTo( last_point ) < 10/map.zoom) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(points[0])
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b =last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ },
+ drag: function(e, cursor){
+ cursor.x.b = ((cursor.x.b/map.dimensions.a)+0.5) * map.dimensions.a / map.zoom + map.center.a
+ cursor.y.b = ((cursor.y.b/map.dimensions.b)-0.5) * map.dimensions.b / map.zoom - map.center.b
+ },
+ up: function(e, cursor, new_cursor){
+ new_cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a)
+ new_cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b)
+ }
+ })
+
+ base.wheel = new wheel({
+ el: map.el,
+ update: mousewheel,
+ })
+
+ function mousewheel (e, deltaY, deltaX){
+ map.set_zoom(map.zoom_exponent - deltaY/20)
+ }
+}
+
+var scene, map, controls
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: 0,
+})
+
+var placing = false
+var points, mx_points = []
+var shapes = []
+var ctx = map.draw.ctx
+var last_point
+
+function polyline (points, finished) {
+ if (! points) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = "#ff0"
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ ctx.stroke()
+ if (! placing || finished) {
+ ctx.fill()
+ }
+ }
+}
+
+function add_mx_polyline (points) {
+ mx_points.forEach(function(mx){ scene.remove(mx) })
+ var faces = []
+ for (var i = 1; i < points.length; i++) {
+ var head = points[i-1]
+ var tail = points[i]
+ face = add_mx_polyline_face(head, tail)
+ faces.push(face)
+ }
+ shapes.push({
+ mx: faces,
+ points: points,
+ })
+ points = []
+}
+function add_mx_polyline_face(head, tail){
+ var mx = new MX.Object3D()
+ var mid_x = (head.a + tail.a)
+ var mid_z = (head.b + tail.b)
+ var len = head.distanceTo( tail )
+ var angle = atan2( head.b - tail.b, head.a - tail.a )
+ mx.move({
+ x: mid_x / 2,
+ y: 25 + 1,
+ z: mid_z / 2,
+ width: ceil(len),
+ height: 50,
+ rotationY: angle
+ })
+ var hue = abs(round( angle / PI * 90 + 300))
+ mx.el.style.backgroundColor = 'hsl(' + [hue, "100%", "50%"] + ')'
+ scene.add(mx)
+ return mx
+}
+
+function add_mx_point (p, i) {
+ var mx = new MX.Object3D()
+ mx.updateChildren = false
+ mx.move({
+ x: p.a,
+ y: 11,
+ z: p.b,
+ width: 20,
+ height: 20,
+ })
+ mx.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')'
+ mx.el.style.backfaceVisibility = "visible"
+ scene.add(mx)
+ return mx
+}
+function mx_grid () {
+ var space = 20, cells = 20, side = space*cells
+ var ctx, canvas = document.createElement("canvas")
+ canvas.width = canvas.height = side + 4
+ ctx = canvas.getContext('2d')
+
+ draw_grid(ctx, 20, 20)
+
+ var mx = new MX.Object3D(canvas)
+ mx.rotationX = PI/2
+ scene.add(mx)
+}
+function draw_grid (ctx, cells, space) {
+ var side = space * cells
+ ctx.strokeStyle = "#444"
+ ctx.lineWidth = 1
+ ctx.beginPath()
+ ctx.translate(1,1)
+ for (var i = 0; i <= cells; i++) {
+ ctx.moveTo(i*space, 0)
+ ctx.lineTo(i*space, side)
+ ctx.moveTo(0, i*space)
+ ctx.lineTo(side, i*space)
+ }
+ ctx.closePath()
+ ctx.stroke()
+}
+
+document.addEventListener('DOMContentLoaded', build)
+function build () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ mx_grid()
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ radius: 1000,
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+
+ animate(0)
+}
+function animate(time){
+ requestAnimationFrame(animate)
+ map.update(time)
+
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ map.draw.ctx.save()
+ map.draw.ctx.translate(-(20*20)/2, -(20*20)/2)
+ draw_grid(map.draw.ctx, 20, 20)
+ map.draw.ctx.restore()
+
+ map.draw.coords()
+
+ polyline(points)
+ if (placing && last_point) {
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[points.length-1].a, points[points.length-1].b)
+ ctx.lineTo(last_point.a, last_point.b)
+ ctx.stroke()
+ }
+
+ shapes.forEach(function(shape){
+ polyline(shape.points, true)
+ })
+
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/ortho2.html b/public/assets/test/ortho2.html
new file mode 100644
index 0000000..ef77256
--- /dev/null
+++ b/public/assets/test/ortho2.html
@@ -0,0 +1,374 @@
+<link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ font-family: Menlo, monospace;
+ overflow: hidden;
+}
+#perspective {
+ position: absolute;
+ left:0%;
+ top:0px
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+#hud {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 10px;
+ background: white;
+}
+#url { width: 300px }
+#hud span { color: #888; cursor: pointer; }
+#hud span.active { color: #000; }
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div id="hud">
+ <input type="text" id="url" placeholder="paste an image URL here!">
+ <span class="ion-ionic active" data-role="orbit-mode"></span>
+ <span class="ion-archive" data-role="keyboard-mode"></span>
+</div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/defaults.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.movements.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.grid.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.image.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/coords.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+
+<script>
+var app = window.app || {}
+app.tube = new Tube ()
+app.on = function(){ app.tube.on.apply(app.tube, arguments) }
+app.off = function(){ app.tube.off.apply(app.tube, arguments) }
+
+var MapTool = Fiber.extend(function(base){
+ var exports = {
+ down: function(e, cursor){},
+ move: function(e, cursor){},
+ drag: function(e, cursor){},
+ up: function(e, cursor, new_cursor){},
+ cancel: function(){},
+ }
+ return exports
+})
+
+var PositionTool = MapTool.extend(function(base){
+ var exports = {
+ down: function(e, cursor){
+ cursor.quantize(1/map.zoom)
+ map.center.a = cursor.x.a
+ map.center.b = -cursor.y.a
+ cursor.x.b = cursor.x.a
+ cursor.y.b = cursor.y.a
+ map.ui.mouse.down = false
+ },
+ }
+ return exports
+})
+
+var PolylineTool = MapTool.extend(function (base) {
+ var exports = {}
+ exports.down = function(e, cursor){
+
+ // rightclick?
+ if (e.ctrlKey || e.which === 3) {
+ e.preventDefault()
+ e.stopPropagation()
+ if (placing) {
+ // close polyline or cancel
+ placing = false
+ if (points.length > 2) {
+ add_mx_polyline(points)
+ }
+ else {
+ points.length = 0
+ }
+ return
+ }
+ map.ui.tools.position.down(e, cursor)
+ return
+ }
+
+ // compare to initial point
+ var p = new vec2( cursor.x.a, cursor.y.a )
+ if (placing) {
+ if (points.length > 2 && points[0].distanceTo( p ) < 10/map.zoom) {
+ points.push( points[0].clone() )
+ placing = false
+ add_mx_polyline(points)
+ }
+ else {
+ points.push( p )
+ mx_points.push( add_mx_point(p) )
+ }
+ }
+ else {
+ placing = true
+ points = []
+ points.push( p )
+ mx_points.push( add_mx_point(p) )
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point = new vec2( cursor.x.a, cursor.y.a )
+ if (placing && points.length > 1 && points[0].distanceTo( last_point ) < 10/map.zoom) {
+ document.body.style.cursor = "pointer"
+ last_point.assign(points[0])
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ return exports
+})
+
+var scene, map, controls
+var last_point = new vec2(0,0)
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: -2,
+})
+map.ui.add_tool("arrow", new ArrowTool)
+map.ui.add_tool("polyline", new PolylineTool)
+map.ui.add_tool("position", new PositionTool)
+map.ui.set_tool("arrow")
+
+$(window).resize(function(){
+ scene.width = window.innerWidth/2
+ map.canvas.width = map.dimensions.a = window.innerWidth/2
+})
+
+var wallHeight = 180
+var placing = false
+var points, mx_points = []
+var shapes = []
+var ctx = map.draw.ctx
+var last_point
+
+shapes.findClosestPoint = function(){}
+
+function polyline (points, finished) {
+ if (! points) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = "rgba(255,255,0,0.1)"
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ ctx.stroke()
+ if (! placing || finished) {
+ ctx.fill()
+ }
+ }
+}
+
+function add_mx_polyline (points) {
+ mx_points.forEach(function(mx){ scene.remove(mx) })
+ var faces = []
+ for (var i = 1; i < points.length; i++) {
+ var head = points[i-1]
+ var tail = points[i]
+ face = add_mx_polyline_face(head, tail)
+ faces.push(face)
+ }
+ shapes.push({
+ mx: faces,
+ points: points,
+ })
+ points = []
+}
+function add_mx_polyline_face(head, tail){
+ var mx = new MX.Object3D()
+ var mid_x = (head.a + tail.a)
+ var mid_z = (head.b + tail.b)
+ var len = head.distanceTo( tail )
+ var angle = atan2( head.b - tail.b, head.a - tail.a )
+ mx.move({
+ x: mid_x / 2,
+ y: wallHeight/2 + 1,
+ z: mid_z / 2,
+ width: ceil(len),
+ height: wallHeight,
+ rotationY: angle
+ })
+ var hue = abs(round( angle / PI * 90 + 300))
+ mx.el.style.backgroundColor = 'hsl(' + [hue, "100%", "50%"] + ')'
+ scene.add(mx)
+ return mx
+}
+function add_mx_point (p, i) {
+ var mx = new MX.Object3D()
+ mx.updateChildren = false
+ mx.move({
+ x: p.a,
+ y: 11,
+ z: p.b,
+ width: 20,
+ height: 20,
+ rotationX: PI/2,
+ })
+ mx.el.style.backgroundColor = 'rgb(' + [abs(floor(p.a*30)), 0, abs(floor(p.b*30))] + ')'
+ mx.el.style.backfaceVisibility = "visible"
+ mx.el.style.borderRadius = "50%"
+ scene.add(mx)
+ return mx
+}
+
+$("#url").on("input", function(){
+ floorplan.load({ src: this.value })
+})
+$("[data-role=orbit-mode]").click(function(){
+ $("#hud .active").removeClass('active')
+ $(this).addClass('active')
+ controls.toggle(true)
+ movements.lock()
+})
+$("[data-role=keyboard-mode]").click(function(){
+ $("#hud .active").removeClass('active')
+ $(this).addClass('active')
+ controls.toggle(false)
+ movements.unlock()
+ movements.gravity(true)
+ cam.rotationX = 0
+ cam.rotationY = -cam.rotationY
+ cam.x = 0
+ cam.y = viewHeight + 100
+ cam.z = 0
+})
+
+document.addEventListener('DOMContentLoaded', build)
+function build () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+
+ viewHeight = 100
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ cam = scene.camera
+ movements = new MX.Movements(cam, viewHeight)
+ movements.init()
+ movements.lock()
+ movements.velocity(8)
+ app.on("move", function(pos){
+ cam.x = pos.x
+ cam.y = pos.y
+ cam.z = pos.z
+ })
+
+ floorplan = new MX.Image({
+ src: "https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg",
+ keepImage: true,
+ rotationX: -PI/2,
+ rotationY: PI,
+ })
+ scene.add(floorplan)
+ floorplan.el.addEventListener("contextmenu", function(e){
+ e.preventDefault()
+ var offset = offsetFromPoint(e, this)
+ var x = (offset.left - 0.5) * floorplan.width * floorplan.scale
+ var z = (offset.top - 0.5) * floorplan.height * floorplan.scale
+ controls.opt.center.x = -x
+ controls.opt.center.y = 0
+ controls.opt.center.z = -z
+ }, true)
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ el: scene.el,
+ radius: 3000,
+ radiusRange: [ 10, 10000 ],
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+
+ animate(0)
+}
+var last_t = 0
+function animate(t){
+ requestAnimationFrame(animate)
+
+ var dt = t - last_t
+ last_t = t
+
+ map.update(t)
+
+ movements.update(dt)
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ floorplan.draw(map.draw.ctx, true)
+
+ map.draw.coords()
+
+ polyline(points)
+ if (placing && last_point) {
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[points.length-1].a, points[points.length-1].b)
+ ctx.lineTo(last_point.a, last_point.b)
+ ctx.stroke()
+ }
+
+ shapes.forEach(function(shape){
+ polyline(shape.points, true)
+ })
+
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/ortho3.html b/public/assets/test/ortho3.html
new file mode 100644
index 0000000..71e43f1
--- /dev/null
+++ b/public/assets/test/ortho3.html
@@ -0,0 +1,258 @@
+<link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ font-family: Menlo, monospace;
+ overflow: hidden;
+}
+#perspective {
+ position: absolute;
+ left:0%;
+ top:0px
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+.hud {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 10px;
+ background: white;
+}
+.ortho-hud {
+ left: 50%;
+ border-left: 1px solid black;
+}
+#url { width: 300px }
+.hud span { color: #888; cursor: pointer; }
+.hud span.active { color: #000; }
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div class="hud persp-hud">
+ <input type="text" id="url" placeholder="paste an image URL here!">
+ <span class="ion-ionic active" data-role="orbit-mode"></span>
+ <span class="ion-archive" data-role="keyboard-mode"></span>
+</div>
+
+<div class="hud ortho-hud">
+ <span class="ion-navigate" data-role="arrow-mode"></span>
+ <span class="ion-ios-pulse active" data-role="polyline-mode"></span>
+ <span class="ion-ios-grid-view-outline" data-role="ortho-polyline-mode"></span>
+ <span class="ion-scissors" data-role="eraser-mode"></span>
+</div>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/defaults.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.movements.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.grid.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.image.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.point.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.polyline.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/coords.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/eraser.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/polyline.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/position.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/shapelist.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/polyline.js"></script>
+<script src="/assets/javascripts/ui/lib/Toolbar.js"></script>
+
+<script>
+var app = window.app || {}
+app.tube = new Tube ()
+app.on = function(){ app.tube.on.apply(app.tube, arguments) }
+app.off = function(){ app.tube.off.apply(app.tube, arguments) }
+
+var scene, map, controls
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: -2,
+ zoom_min: -6.2,
+ zoom_max: 1,
+})
+map.ui.add_tool("arrow", new ArrowTool)
+map.ui.add_tool("polyline", new PolylineTool)
+map.ui.add_tool("ortho-polyline", new OrthoPolylineTool)
+map.ui.add_tool("eraser", new EraserTool)
+map.ui.add_tool("position", new PositionTool)
+
+map.ui.placing = false
+
+$(window).resize(function(){
+ scene.width = window.innerWidth/2
+ map.canvas.width = map.dimensions.a = window.innerWidth/2
+})
+
+var wallHeight = 180
+var shapes = new ShapeList
+var ctx = map.draw.ctx
+var last_point = new vec2 (0,0)
+
+$("#url").on("input", function(){
+ floorplan.load({ src: this.value })
+})
+
+var PerspectiveToolbar = new Toolbar (".persp-hud")
+PerspectiveToolbar.add("orbit-mode", function(){
+ controls.toggle(true)
+ movements.lock()
+})
+PerspectiveToolbar.add("keyboard-mode", function(){
+ controls.toggle(false)
+ movements.unlock()
+ movements.gravity(true)
+ cam.rotationX = 0
+ cam.rotationY = -cam.rotationY
+ cam.x = 0
+ cam.y = viewHeight + 100
+ cam.z = 0
+})
+
+var OrthographicToolbar = new Toolbar (".ortho-hud")
+OrthographicToolbar.add("arrow-mode", function(){
+ map.ui.set_tool("arrow")
+})
+OrthographicToolbar.add("polyline-mode", function(){
+ map.ui.set_tool("polyline")
+})
+OrthographicToolbar.add("ortho-polyline-mode", function(){
+ map.ui.set_tool("ortho-polyline")
+})
+OrthographicToolbar.add("eraser-mode", function(){
+ map.ui.set_tool("eraser")
+})
+OrthographicToolbar.pick("ortho-polyline-mode")
+// OrthographicToolbar.pick("eraser-mode")
+
+
+document.addEventListener('DOMContentLoaded', build)
+function build () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+
+ viewHeight = 100
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ cam = scene.camera
+ movements = new MX.Movements(cam, viewHeight)
+ movements.init()
+ movements.lock()
+ movements.velocity(8)
+ app.on("move", function(pos){
+ cam.x = pos.x
+ cam.y = pos.y
+ cam.z = pos.z
+ })
+
+ floorplan = new MX.Image({
+ src: "https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg",
+ keepImage: true,
+ rotationX: -PI/2,
+ rotationY: PI,
+ })
+ scene.add(floorplan)
+
+ // recenter perspective view by rightclicking map
+ floorplan.el.addEventListener("contextmenu", function(e){
+ e.preventDefault()
+ var offset = offsetFromPoint(e, this)
+ var x = (offset.left - 0.5) * floorplan.width * floorplan.scale
+ var z = (offset.top - 0.5) * floorplan.height * floorplan.scale
+ controls.opt.center.x = -x
+ controls.opt.center.y = 0
+ controls.opt.center.z = -z
+ }, true)
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ el: scene.el,
+ radius: 3000,
+ radiusRange: [ 10, 10000 ],
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+
+ var line = new Polyline ()
+ line.add( new vec2(-100,100) )
+ line.add( new vec2(100,100) )
+ line.add( new vec2(100,-100) )
+ line.add( new vec2(-100,-100) )
+ line.close()
+ line.build()
+
+ animate(0)
+}
+var last_t = 0
+function animate(t){
+ requestAnimationFrame(animate)
+
+ var dt = t - last_t
+ last_t = t
+
+ map.update(t)
+
+ movements.update(dt)
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ floorplan.draw(map.draw.ctx, true)
+
+ map.draw.coords()
+
+ if (shapes.workline) {
+ shapes.workline.draw(map.draw.ctx)
+ if (map.ui.placing && last_point) {
+ shapes.workline.draw_line( map.draw.ctx, last_point )
+ }
+ }
+
+ shapes.forEach(function(shape){
+ shape.draw(map.draw.ctx)
+ })
+
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/ortho4.html b/public/assets/test/ortho4.html
new file mode 100644
index 0000000..8db7ead
--- /dev/null
+++ b/public/assets/test/ortho4.html
@@ -0,0 +1,303 @@
+<link href='/assets/stylesheets/app.css' rel='stylesheet' type='text/css'>
+<link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
+<style type="text/css">
+html,body{width:100%;height:100%;margin:0;padding:0;}
+body {
+ overflow: hidden;
+}
+#perspective,
+#perspective .mx-scene {
+ position: absolute;
+ left:0%;
+ top:0px;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+}
+
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+.hud {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 10px;
+ background: white;
+}
+.ortho-hud {
+ left: 50%;
+ border-left: 1px solid black;
+}
+#url { width: 300px }
+.hud span { color: #888; cursor: pointer; }
+.hud span.active { color: #000; }
+
+#blueprintForm {
+ width: 240px;
+}
+</style>
+
+<div id="perspective"></div>
+<div id="orthographic"></div>
+
+<div class="hud persp-hud">
+ <input type="text" id="url" placeholder="paste an image URL here!">
+ <span class="ion-ionic active" data-role="orbit-mode"></span>
+ <span class="ion-archive" data-role="keyboard-mode"></span>
+</div>
+
+<div class="hud ortho-hud">
+ <span class="ion-navigate" data-role="arrow-mode"></span>
+ <span class="ion-ios-pulse active" data-role="polyline-mode"></span>
+ <span class="ion-ios-grid-view-outline" data-role="ortho-polyline-mode"></span>
+ <span class="ion-scissors" data-role="eraser-mode"></span>
+</div>
+
+<div class="mediaDrawer fixed animate blueprintUpload active">
+ <span class="close">X</span>
+ <div class="box">
+
+ <h2>Upload A Room Image</h2>
+
+ <div id="blueprintForm">
+ <div class="wallpaperUpload toolButton">
+ <form>
+ <span class="ion-ios-upload-outline upload-icon"></span>
+ <label>Upload</label>
+ <input type="file" accept="image/*" multiple>
+ </form>
+ </div>
+ <input type="text" class="url" placeholder="Enter an image URL or...">
+ </div>
+
+ Please tell us the scale of your map.
+ Click both corners of a wall, and then enter how long the wall is.
+
+ <div id="blueprintMap">
+ </div>
+
+ <div id="blueprintDimensions">
+ <input type="text" name="blueprint-dimensions">
+ <select id="blueprint-units" name="blueprint-units">
+ <option value="ft">foot</option>
+ <option value="m">meter</option>
+ </select>
+
+ <button id="saveBlueprint">Save</button>
+ </div>
+
+ </div>
+</div>
+
+<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script>
+<script src="/assets/javascripts/vendor/polyfill.js"></script>
+<script src="/assets/javascripts/vendor/tube.js"></script>
+
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/defaults.js"></script>
+
+<script src="/assets/javascripts/mx/mx.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+<script src="/assets/javascripts/mx/extensions/mx.movements.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.grid.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.image.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.point.js"></script>
+<script src="/assets/javascripts/mx/primitives/mx.polyline.js"></script>
+<script src="/assets/javascripts/rectangles/util/constants.js"></script>
+<script src="/assets/javascripts/rectangles/util/coords.js"></script>
+<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+<script src="/assets/javascripts/rectangles/models/vec2.js"></script>
+<script src="/assets/javascripts/rectangles/models/rect.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/eraser.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/ortho.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/polyline.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/position.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/shapelist.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/polyline.js"></script>
+<script src="/assets/javascripts/ui/lib/View.js"></script>
+<script src="/assets/javascripts/ui/lib/ModalView.js"></script>
+<script src="/assets/javascripts/ui/lib/UploadView.js"></script>
+<script src="/assets/javascripts/ui/lib/Parser.js"></script>
+<script src="/assets/javascripts/ui/lib/Toolbar.js"></script>
+<script src="/assets/javascripts/ui/builder/BlueprintUpload.js"></script>
+
+<script>
+var app = window.app || {}
+app.tube = new Tube ()
+app.on = function(){ app.tube.on.apply(app.tube, arguments) }
+app.off = function(){ app.tube.off.apply(app.tube, arguments) }
+
+var scene, map, controls
+
+map = new Map ({
+ type: "ortho",
+ el: document.querySelector("#orthographic"),
+ width: window.innerWidth/2,
+ height: window.innerHeight,
+ zoom: -2,
+ zoom_min: -6.2,
+ zoom_max: 1,
+})
+map.ui.add_tool("arrow", new ArrowTool)
+map.ui.add_tool("polyline", new PolylineTool)
+map.ui.add_tool("ortho-polyline", new OrthoPolylineTool)
+map.ui.add_tool("eraser", new EraserTool)
+map.ui.add_tool("position", new PositionTool)
+
+map.ui.placing = false
+
+$(window).resize(function(){
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ map.canvas.width = map.dimensions.a = window.innerWidth/2
+ map.canvas.height = map.dimensions.b = window.innerHeight/2
+})
+
+var wallHeight = 180
+var shapes = new ShapeList
+var ctx = map.draw.ctx
+var last_point = new vec2 (0,0)
+
+$("#url").on("input", function(){
+ floorplan.load({ src: this.value })
+})
+
+var PerspectiveToolbar = new Toolbar (".persp-hud")
+PerspectiveToolbar.add("orbit-mode", function(){
+ controls.toggle(true)
+ movements.lock()
+})
+PerspectiveToolbar.add("keyboard-mode", function(){
+ controls.toggle(false)
+ movements.unlock()
+ movements.gravity(true)
+ cam.rotationX = 0
+ cam.rotationY = -cam.rotationY
+ cam.x = 0
+ cam.y = viewHeight + 100
+ cam.z = 0
+})
+
+var OrthographicToolbar = new Toolbar (".ortho-hud")
+OrthographicToolbar.add("arrow-mode", function(){
+ map.ui.set_tool("arrow")
+})
+OrthographicToolbar.add("polyline-mode", function(){
+ map.ui.set_tool("polyline")
+})
+OrthographicToolbar.add("ortho-polyline-mode", function(){
+ map.ui.set_tool("ortho-polyline")
+})
+OrthographicToolbar.add("eraser-mode", function(){
+ map.ui.set_tool("eraser")
+})
+OrthographicToolbar.pick("ortho-polyline-mode")
+
+var BlueprintUpload = new BlueprintUploadView ({})
+
+document.addEventListener('DOMContentLoaded', build)
+function build () {
+ scene = new MX.Scene().addTo("#perspective")
+ scene.camera.radius = 20
+
+ viewHeight = 100
+
+ scene.width = window.innerWidth/2
+ scene.height = window.innerHeight
+ scene.perspective = window.innerHeight
+
+ cam = scene.camera
+ movements = new MX.Movements(cam, viewHeight)
+ movements.init()
+ movements.lock()
+ movements.velocity(8)
+ app.on("move", function(pos){
+ cam.x = pos.x
+ cam.y = pos.y
+ cam.z = pos.z
+ })
+
+ floorplan = new MX.Image({
+ src: "https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg",
+ keepImage: true,
+ rotationX: -PI/2,
+ rotationY: PI,
+ })
+ scene.add(floorplan)
+
+ // recenter perspective view by rightclicking map
+ floorplan.el.addEventListener("contextmenu", function(e){
+ e.preventDefault()
+ var offset = offsetFromPoint(e, this)
+ var x = (offset.left - 0.5) * floorplan.width * floorplan.scale
+ var z = (offset.top - 0.5) * floorplan.height * floorplan.scale
+ controls.opt.center.x = -x
+ controls.opt.center.y = 0
+ controls.opt.center.z = -z
+ }, true)
+
+ scene.update()
+
+ controls = new MX.OrbitCamera({
+ el: scene.el,
+ radius: 3000,
+ radiusRange: [ 10, 10000 ],
+ rotationX: PI/4,
+ rotationY: PI/2,
+ })
+ controls.init()
+
+ animate(0)
+}
+var last_t = 0
+function animate(t){
+ requestAnimationFrame(animate)
+
+ var dt = t - last_t
+ last_t = t
+
+ map.update(t)
+
+ movements.update(dt)
+ controls.update()
+ scene.update()
+
+ map.draw.ctx.save()
+ map.draw.translate()
+
+ floorplan.draw(map.draw.ctx, true)
+
+ map.draw.coords()
+
+ if (shapes.workline) {
+ shapes.workline.draw(map.draw.ctx)
+ if (map.ui.placing && last_point) {
+ shapes.workline.draw_line( map.draw.ctx, last_point )
+ }
+ }
+
+ shapes.forEach(function(shape){
+ shape.draw(map.draw.ctx)
+ })
+
+ ctx.strokeStyle = "#f00";
+ map.draw.x_at(0,0)
+ map.draw.mouse(map.ui.mouse.cursor)
+ map.draw.camera(scene.camera)
+
+ map.draw.ctx.restore()
+}
+
+</script> \ No newline at end of file
diff --git a/public/assets/test/static.html b/public/assets/test/static.html
new file mode 100644
index 0000000..dc098de
--- /dev/null
+++ b/public/assets/test/static.html
@@ -0,0 +1,152 @@
+<!doctype html>
+<html>
+<head>
+ <title>VValls</title>
+
+<!-----+ +------+ +------+ +------+ +------+
+|`. `. |\ \ | | / /| .' .'|
+| `+------+ | +------+ +------+ +------+ | +------+' |
+| | | | | | | | | | | | | |
++ | | + | | | | | | + | | +
+ `. | | \| | | | | |/ | | .'
+ `+------+ +------+ +------+ +------+ +------+'
+ VVALLS - developed by okfoc.us
+ .+------+ +------+ +------+ +------+ +------+.
+ .' .'| / /| | | |\ \ |`. `.
++------+' | +------+ | +------+ | +------+ | `+------+
+| | | | | | | | | | | | | |
+| | + | | + | | + | | + | |
+| | .' | |/ | | \| | `. | |
++------+' +------+ +------+ +------+ `+------->
+
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable = no">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <meta name="description" content="3D gallery space, fully customizable" />
+ <meta name="author" content="VValls" />
+ <link rel="shortcut icon" href="/favicon.ico" />
+ <meta property="og:title" content="Leaves and such" />
+ <meta property="og:type" content="website" />
+ <meta property="og:image" content="http://www.sport-fitness-advisor.com/images/plyometric_drills_overhead_throws.gif" />
+ <meta property="og:url" content="http://vvalls.com/project/leaves-and-such-1429563199123/" />
+ <meta property="og:site_name" content="vvalls" />
+ <link rel="icon" href="/favicon.ico" type="image/x-icon">
+ <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+ <link href='http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic' rel='stylesheet' type='text/css'>
+ <link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
+ <link href='/assets/stylesheets/app.css' rel='stylesheet' type='text/css'>
+</head>
+<body class="loading reader">
+
+<div id="scene"></div>
+
+<div class="rapper">
+ <div id="header">
+ <a href="/" class="logo">
+ <svg version="1.1"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ x="0px" y="0px" width="117px" height="44px" viewBox="-0.896 -0.441 117 44"
+ overflow="visible" enable-background="new -0.896 -0.441 117 44" xml:space="preserve">
+ <defs>
+ </defs>
+ <path d="M0.54,38.759c0-1.44,0.66-3.72,1.56-6.18c1.38-3.84,3.42-8.22,4.5-11.16c0.48-1.32,0.78-2.34,0.78-2.88
+ c0-0.72-0.24-1.02-0.72-1.02c-1.38,0-4.74,5.16-5.4,6.24c-0.36,0.6-0.48,0.78-0.78,0.78c-0.3,0-0.48-0.06-0.48-0.36
+ c0-0.18,0.18-0.84,0.66-1.62c0.9-1.44,2.22-3.6,3.9-5.28c1.44-1.5,3.12-2.64,4.74-2.64c1.38,0,1.92,1.32,1.92,2.7
+ c0,1.02-0.42,2.58-1.02,4.32c-1.26,3.72-3.359,8.521-4.68,12.18c-0.66,1.92-1.14,3.54-1.14,4.62c0,1.38,0.48,2.459,1.979,2.459
+ c6.48,0,13.56-14.639,13.56-17.759c0-1.2-0.3-1.92-0.6-2.58c-0.42-0.9-0.9-1.62-0.9-3.18c0-1.86,0.84-2.76,1.8-2.76
+ c0.9,0,1.98,1.08,1.98,3.66c0,9.179-9.6,24.66-17.58,24.66c-2.82,0-4.08-1.561-4.08-4.141V38.759z"/>
+ <path d="M23.879,38.759c0-1.44,0.66-3.72,1.56-6.18c1.38-3.84,3.42-8.22,4.5-11.16c0.48-1.32,0.78-2.34,0.78-2.88
+ c0-0.72-0.24-1.02-0.72-1.02c-1.38,0-4.74,5.16-5.4,6.24c-0.36,0.6-0.48,0.78-0.78,0.78c-0.3,0-0.48-0.06-0.48-0.36
+ c0-0.18,0.18-0.84,0.66-1.62c0.9-1.44,2.22-3.6,3.9-5.28c1.44-1.5,3.12-2.64,4.74-2.64c1.38,0,1.92,1.32,1.92,2.7
+ c0,1.02-0.42,2.58-1.02,4.32c-1.26,3.72-3.36,8.521-4.68,12.18c-0.66,1.92-1.14,3.54-1.14,4.62c0,1.38,0.48,2.459,1.98,2.459
+ c6.479,0,13.559-14.639,13.559-17.759c0-1.2-0.3-1.92-0.6-2.58c-0.42-0.9-0.9-1.62-0.9-3.18c0-1.86,0.84-2.76,1.8-2.76
+ c0.9,0,1.979,1.08,1.979,3.66c0,9.179-9.6,24.66-17.579,24.66c-2.82,0-4.08-1.561-4.08-4.141V38.759z"/>
+ <path d="M44.339,37.799c0-5.22,2.76-10.92,6.36-15.299c3.66-4.44,8.159-7.5,11.759-7.5c2.7,0,3.78,1.44,3.9,1.44
+ s0.48-0.96,0.66-1.44c0.18-0.48,0.3-0.6,1.02-0.6h1.74c0.359,0,0.6,0.06,0.6,0.42c0,0.18-0.119,0.6-0.24,0.9
+ c-1.919,5.82-3.839,11.64-5.819,17.519c-1.14,3.48-1.26,4.381-1.26,5.041c0,0.659,0.3,0.84,0.66,0.84c0.54,0,1.68-1.141,3.72-4.26
+ c1.5-2.28,1.26-2.94,1.86-2.94c0.3,0,0.42,0.181,0.42,0.479c0,0.84-1.38,3.541-3.24,6c-1.8,2.52-4.14,4.8-6.12,4.8
+ c-1.38,0-1.62-0.96-1.62-2.159c0-0.961,0.24-2.101,0.72-3.66c0.54-1.98,1.5-4.62,2.82-8.52l-0.12-0.12
+ c-2.16,3.3-9.36,14.459-14.1,14.459c-2.76,0-3.72-2.159-3.72-5.339V37.799z M65.338,18.839c0-1.8-1.08-2.76-2.76-2.76
+ c-3,0-6.6,3.72-9.48,8.22c-2.82,4.5-4.919,9.839-4.919,13.019c0,1.561,0.54,2.641,1.86,2.641c2.22,0,6.06-4.26,9.3-9
+ c3.3-4.74,6-10.02,6-12.06V18.839z"/>
+ <path d="M72.178,39.839c0-1.08,0.479-3.479,1.2-6.479c1.74-7.02,4.979-17.52,6.6-23.64c0.66-2.46,1.08-4.2,1.08-4.8
+ c0-0.78-0.24-1.32-1.62-1.44c-1.14-0.12-1.38-0.3-1.38-0.78c0.061-0.42,0.779-0.66,1.8-0.66c2.58,0,4.2-0.78,5.16-1.38
+ c0.6-0.36,0.96-0.66,1.14-0.66c0.3,0,0.42,0.12,0.42,0.48c0,0.3-0.6,1.56-1.14,3.479c-5.04,17.759-7.38,25.799-8.46,29.698
+ c-0.84,3.061-0.96,3.84-0.96,4.681c0,0.6,0.3,1.02,0.78,1.02c0.84,0,1.619-0.659,3.479-3.72c1.08-1.74,1.92-4.199,2.46-4.199
+ c0.301,0,0.42,0.239,0.42,0.539c0,0.42-0.84,2.521-2.16,4.74c-1.739,3-4.319,6.24-6.719,6.24c-1.681,0-2.101-1.32-2.101-3.061
+ V39.839z"/>
+ <path d="M85.497,39.839c0-1.08,0.48-3.479,1.2-6.479c1.739-7.02,4.979-17.52,6.6-23.64c0.66-2.46,1.08-4.2,1.08-4.8
+ c0-0.78-0.24-1.32-1.62-1.44c-1.14-0.12-1.38-0.3-1.38-0.78c0.06-0.42,0.78-0.66,1.8-0.66c2.58,0,4.2-0.78,5.16-1.38
+ c0.6-0.36,0.96-0.66,1.14-0.66c0.3,0,0.42,0.12,0.42,0.48c0,0.3-0.6,1.56-1.14,3.479c-5.04,17.759-7.38,25.799-8.46,29.698
+ c-0.84,3.061-0.96,3.84-0.96,4.681c0,0.6,0.301,1.02,0.78,1.02c0.84,0,1.62-0.659,3.479-3.72c1.08-1.74,1.92-4.199,2.46-4.199
+ c0.3,0,0.42,0.239,0.42,0.539c0,0.42-0.84,2.521-2.159,4.74c-1.74,3-4.32,6.24-6.721,6.24c-1.68,0-2.1-1.32-2.1-3.061V39.839z"/>
+ <path d="M111.416,34.619c0,2.34-0.96,4.439-2.46,5.939c-1.68,1.68-4.02,2.64-6.479,2.64c-1.86,0-3.84-0.78-5.04-1.56
+ c-0.6-0.42-1.02-0.84-1.02-1.2c0-0.96,0.359-3.12,0.959-5.819c0.42-1.98,0.48-2.34,1.08-2.34c0.541,0,0.601,0.359,0.601,2.16
+ c0,3.84,1.2,7.319,4.92,7.319c2.34,0,4.2-2.46,4.2-4.74c0-2.819-1.561-4.979-3.24-6.96c-1.68-1.979-3.24-4.08-3.24-6.899
+ c0-4.38,3.24-8.76,7.859-8.76c3,0,5.82,1.38,5.82,2.1c0,1.14-0.301,2.4-0.66,3.9c-0.72,2.76-0.779,3.06-1.38,3.06
+ c-0.899,0-0.78-1.92-1.08-3.84c-0.3-1.86-1.08-3.78-3.6-3.78c-2.34,0-4.08,2.04-4.08,4.439s1.62,4.44,3.24,6.6
+ c1.8,2.34,3.6,4.68,3.6,7.68V34.619z"/>
+ </svg>
+ </a>
+
+ <div id="minotaur">
+ <span class="label"></span>
+ </div>
+
+ <span class="topLinks">
+ </span>
+ </div>
+
+ <div id="editorView">
+ <div class="aboutRoom vvbox">
+ <h1>
+ <span class="roomName">Leaves and such</span>
+ <br>
+ <a href="/profile/asdf" class="authorName"><div class="profilePic" style="background-image:url(https://vvalls.s3.amazonaws.com/images/avatars/20141010/1412971714922-Screen-Shot-2014-10-09-at-12.png)"></div></a>
+ <a href="/profile/asdf" class="authorName">asdf</a>
+ </h1>
+ <span class="txt">Last modified 4/20/2015</span>
+ <!--
+ <div class="share">
+ <h2>Share on–</h2>
+ <a id="share_facebook">Facebook</a>
+ <a id="share_twitter">Twitter</a>
+ </div>
+ -->
+ </div>
+
+ <div class="vvbox settings" id="mediaPlayer">
+ <span class="playButton video audio" data-role="play-media">
+ <span class="on ion-play"></span>
+ <span class="off ion-pause"></span>
+ </span>
+
+ <span class="muteButton video" data-role="mute-media">
+ <span class="on ion-volume-high"></span>
+ <span class="off ion-volume-mute"></span>
+ </span>
+
+ <span class="name"></span>
+
+ <div class="author"></div>
+ <div class="txt description"></div>
+ <div class="dimensions"></div>
+ </div>
+ </div>
+
+ <div id="minimap" class="vvbox" data-intro="Mini-map shows your position and orientation in a room. Navigate with WASD keys or drag here." data-position="top">
+ <span class="el"></span>
+ </div>
+</div>
+
+ <img src="/assets/img/keys.png" id="keyhint">
+ <img src="/assets/img/360.png" id="threesixty">
+</body>
+<script type="text/javascript">
+vvalls_data={"name":"Leaves and such","viewHeight":186,"colors":{"wall":[255,255,255],"outline":[0,0,0],"floor":[246,246,246],"ceiling":[255,255,255]},"startPosition":false,"lastPosition":{"x":-224,"y":186,"z":300.756,"rotationX":0,"rotationY":1.665},"user_id":"54383cb3b45a88b2a64dc240","slug":"leaves-and-such-1429563199123","created_at":"2015-04-01T19:08:10.150Z","photo":"https://vvalls.s3.amazonaws.com/images/projects/20150401/1427920106818-blob.png","updated_at":"2015-04-20T21:27:41.909Z","featured":false,"sculpture":[{"media":{"url":"http://www.sport-fitness-advisor.com/images/soccer_circuit_dips.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2014-11-17T16:53:21.043Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":200,"width":200,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":2.513,"rotationX":0,"z":-470.285,"y":180,"x":-1541.305},"dimensions":[200,200],"id":"sculpture1"},{"backface":true,"billboard":true,"media":{"url":"http://dumpfm.s3.amazonaws.com/images/20120519/1337401400140-dumpfm-FAUXreal-Greek_Marble_Statue.png","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-03T22:49:00.855Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":380,"width":280,"thumbnail":"","token":""},"scale":0.501,"position":{"scale":0.501,"rotationY":1.665,"rotationX":0,"z":370.922,"y":144.466,"x":-1111.901},"dimensions":[141,191],"id":"sculpture5"},{"backface":true,"billboard":false,"media":{"token":"","thumbnail":"","width":238,"height":210,"title":"","description":"","autoplay":false,"loop":false,"mute":true,"keyframe":0,"tag":"","created_at":"2014-11-17T16:53:38.690Z","user_id":"54383cb3b45a88b2a64dc240","type":"image","url":"http://www.sport-fitness-advisor.com/images/plyometric_drills_overhead_throws.gif"},"scale":0.715,"position":{"scale":0.715,"rotationY":2.911,"rotationX":0,"z":-504.672,"y":480.528,"x":-1015.969},"dimensions":[170,150],"id":"sculpture0"},{"backface":true,"billboard":false,"media":{"url":"http://dump.fm/images/20100825/1282780054021-dumpfm-timb-statue.eyez.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-03T22:48:39.613Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":409,"width":295,"thumbnail":"","token":""},"scale":0.800,"position":{"scale":0.800,"rotationY":0.827,"rotationX":0,"z":457.221,"y":250.467,"x":-1331.614},"dimensions":[236,327],"id":"sculpture2"},{"backface":true,"billboard":true,"media":{"url":"http://simpleascension.com/wp-content/uploads/2009/05/leaves.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-20T20:52:13.261Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":300,"width":300,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":1.665,"rotationX":0,"z":500.971,"y":535.5,"x":-919.926},"dimensions":[300,300],"id":"sculpture3"},{"backface":true,"billboard":false,"media":{"url":"http://simpleascension.com/wp-content/uploads/2009/05/leaves.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-20T20:52:13.261Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":300,"width":300,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":2.358,"rotationX":0,"z":-402.875,"y":493.5,"x":-1341.121},"dimensions":[300,300],"id":"sculpture4"},{"backface":true,"billboard":false,"media":{"url":"http://simpleascension.com/wp-content/uploads/2009/05/leaves.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2015-04-20T20:52:13.261Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":300,"width":300,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":2.264,"rotationX":0,"z":-310.913,"y":492,"x":-718.718},"dimensions":[300,300],"id":"sculpture6"}],"media":[{"media":{"url":"http://www.sport-fitness-advisor.com/images/plyometric_drills_overhead_throws.gif","type":"image","user_id":"54383cb3b45a88b2a64dc240","created_at":"2014-11-17T16:53:38.690Z","tag":"","keyframe":0,"mute":true,"loop":false,"autoplay":false,"description":"","title":"","height":210,"width":238,"thumbnail":"","token":""},"scale":1,"position":{"rotationY":1.570,"rotationX":0,"z":137.5,"y":350,"x":-1721},"dimensions":[238,210],"side":4,"wall_id":"4_-1731_-636","id":"scenery0"}],"walls":[{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"1_-636_-1731"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"1_-168_-204"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"2_156_-204"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"2_652_-1731"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"4_-1731_-636"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"8_726_-168"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"8_-204_-636"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"8_-204_156"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"floor"},{"background":{"src":"none","x":0,"y":0,"scale":1},"id":"ceiling"}],"rooms":[{"height":681,"rect":{"y":[-168,156],"x":[-284,726]},"id":"room_0"},{"height":681,"rect":{"y":[-636,652],"x":[-1731,-204]},"id":"room_1"}],"privacy":false,"description":""}
+</script>
+<script type="text/javascript" src="/assets/javascripts/static.min.js"></script>
+<script type="text/javascript" src="http://www.youtube.com/player_api"></script>
+<script type="text/javascript" src="https://w.soundcloud.com/player/api.js"></script>
+</html>
diff --git a/public/assets/test/surface.html b/public/assets/test/surface.html
index 85e3a7b..9e6abe8 100644
--- a/public/assets/test/surface.html
+++ b/public/assets/test/surface.html
@@ -1,6 +1,7 @@
<canvas id="canvas"></canvas>
<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
<script src="/assets/javascripts/vendor/tube.js"></script>
<script src="/assets/javascripts/rectangles/util/constants.js"></script>
<script src="/assets/javascripts/rectangles/util/mouse.js"></script>
@@ -9,11 +10,11 @@
<script src="/assets/javascripts/rectangles/models/surface.js"></script>
<script>
-var ctx = canvas.getContext('2d')
-
var w = canvas.width = 600
var h = canvas.height = 400
+var ctx = canvas.getContext('2d')
+
var surface = new Surface ()
surface.add( new Rect( new vec2(10, 100), new vec2(0, 400) ) )
surface.add( new Rect( new vec2(100, 300), new vec2(200, 400) ) )
diff --git a/public/assets/test/wheel.html b/public/assets/test/wheel.html
new file mode 100644
index 0000000..054945e
--- /dev/null
+++ b/public/assets/test/wheel.html
@@ -0,0 +1,29 @@
+<style>
+#cursor {
+ position:absolute;margin-top:-5px;margin-left:-5px;
+ width:10px;height:10px;border-radius:50%;
+ background:red;
+}
+</style>
+<div id="cursor"></div>
+<script src="/assets/javascripts/util.js"></script>
+<script src="/assets/javascripts/rectangles/util/wheel.js"></script>
+
+<script>
+x = window.innerWidth/2
+y = window.innerHeight/2
+function draw(){
+ cursor.style.top = y + 'px'
+ cursor.style.left = x + 'px'
+}
+new wheel({
+ el: document,
+ propagate: false,
+ update: function(e,dy,dx){
+ y = mod(y + dy, window.innerHeight)
+ x = mod(x + dx, window.innerWidth)
+ draw()
+ },
+})
+draw()
+</script> \ No newline at end of file
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..19c9da3
--- /dev/null
+++ b/public/favicon.ico
Binary files differ
diff --git a/server/fetch.js b/server/fetch.js
new file mode 100644
index 0000000..b76eeff
--- /dev/null
+++ b/server/fetch.js
@@ -0,0 +1,41 @@
+var DB_HOST = 'localhost'
+var mongoose = require('mongoose')
+var _ = require('lodash')
+var Project = require("./lib/schemas/Project")
+
+if (process.argv.length != 3) {
+ console.error("usage: node fetch.js [project-slug] > project.json")
+ process.exit()
+}
+var slug = process.argv[2]
+
+mongoose.connect('mongodb://' + DB_HOST + '/vvalls', {}, function(){
+ // console.error("vvalls: connected to", DB_HOST)
+ Project.findOne({ slug: slug }).exec(function(err, data){
+ if (err || ! data) {
+ console.error("Project " + slug + " not found!")
+ }
+ else {
+ console.error("Exporting " + data.name + " (" + slug + ") as JSON")
+ var str = JSON.stringify( simplify(data.toObject()) ).replace(/(\.\d\d\d)\d+/g, "$1")
+ console.log( "vvalls_data=" + str )
+ }
+ process.exit()
+ })
+})
+
+function simplify (data) {
+ delete data._id
+ delete data.__v
+ _(data).keys().forEach(function(key){
+ var val = data[key]
+ if (typeof val != "object") return;
+ if (val.hasOwnProperty('length')) {
+ data[key].forEach(simplify)
+ }
+ else {
+ data[key] = simplify(val)
+ }
+ })
+ return data
+}
diff --git a/server/index.js b/server/index.js
index c2df4ca..237355d 100644
--- a/server/index.js
+++ b/server/index.js
@@ -16,11 +16,13 @@ var http = require('http'),
MongoStore = require('connect-mongo')(express),
passport = require('passport'),
path = require('path'),
- mongoose = require('mongoose');
+ mongoose = require('mongoose'),
+ methodOverride = require('method-override');
var app = express()
var server
-var DATABASE_URI = process.env.MONGOLAB_URI || ('mongodb://localhost/vvalls')
+// var DATABASE_URI = process.env.MONGOLAB_URI || ('mongodb://localhost/vvalls')
+var DATABASE_URI = process.env.MONGOLAB_URI || ('mongodb://' + config.databaseHost + '/vvalls')
//
@@ -39,6 +41,7 @@ site.ready = function(){
site.setup = function(){
var SessionStore = new MongoStore({ mongoose_connection: mongoose.connection })
+ // auth.initBasicAuth(app)
app.set('port', config.port);
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'ejs');
@@ -57,30 +60,41 @@ site.setup = function(){
app.use(multer());
app.use(express.query());
app.use(express.csrf());
- app.use(express.methodOverride());
+ app.use(methodOverride('X-HTTP-Method-Override'))
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.set('trust proxy', true)
+ app.set('env', config.env.production ? "production" : "development")
app.get('env') === 'development' && app.use(express.errorHandler());
+ if (config.env.production) {
+ app.set('json spaces', 0)
+ }
+
// Essential middleware
// app.all('*', middleware.enableCORS);
app.all('*', middleware.ensureLocals);
+ app.all('*', middleware.ensureIP);
server = http.createServer(app)
server.listen(app.get('port'), function () {
- console.log('Express server listening on port ' + app.get('port'));
+ console.log('VValls server listening on port ' + app.get('port'));
});
// var io = websocket.listen(server)
// auth.initSockets(io, SessionStore)
+
+ middleware.updatePlans()
}
site.route = function () {
app.get('/', views.home);
+ app.get('/home', views.demoHome);
app.get('/login', views.modal);
app.get('/logout', auth.logout);
+ app.get('/signin', views.modal);
+ app.get('/signout', auth.logout);
app.get('/signup', views.modal);
app.post('/auth/signin', auth.loggedInLocal);
app.post('/auth/signup', auth.signup);
@@ -97,6 +111,7 @@ site.route = function () {
app.get('/profile', views.profile)
app.get('/profile/edit', views.profile)
+ app.get('/profile/billing', views.profile)
app.get('/profile/:username', views.profile)
app.get('/about', views.docs);
@@ -114,6 +129,9 @@ site.route = function () {
app.get('/layout', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.modal)
app.get('/layout/:name', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.builder)
+ app.get('/blueprint', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.blueprint)
+ app.get('/blueprint/:name', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.blueprint)
+
app.get('/join/:nonce', middleware.ensureAuthenticated, api.collaborator.join)
app.get('/api/collaborator/:slug/index', middleware.ensureAuthenticated, middleware.ensureProject, api.collaborator.index)
app.post('/api/collaborator/:slug/create', middleware.ensureAuthenticated, middleware.ensureProject, api.collaborator.create)
@@ -122,17 +140,19 @@ site.route = function () {
app.get('/project', middleware.ensureAuthenticated, views.modal)
app.get('/project/new', middleware.ensureAuthenticated, views.modal)
app.get('/project/new/:layout', middleware.ensureAuthenticated, views.editor_new)
+ app.get('/project/blueprint/:layout', middleware.ensureAuthenticated, views.editor_new)
app.get('/project/:slug', middleware.ensureProject, middleware.ensureIsCollaborator, views.reader)
app.get('/project/:slug/view', middleware.ensureProject, middleware.ensureIsCollaborator, views.reader)
app.get('/project/:slug/edit', middleware.ensureProject, middleware.ensureIsCollaborator, views.editor)
- app.get('/api/layout', middleware.ensureAuthenticated, api.layouts.index)
+ app.get('/api/layout', middleware.ensureAuthenticated, middleware.ensureUserProjectsCount, middleware.ensureUserLayoutsCount, api.layouts.index)
app.get('/api/layout/:slug', middleware.ensureAuthenticated, api.layouts.show)
app.post('/api/layout/new', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.create)
app.post('/api/layout/edit', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.update)
app.delete('/api/layout/destroy', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.destroy)
app.get('/api/project', middleware.ensureAuthenticated, api.projects.index)
+ app.get('/api/project/paginate', views.projectsPaginate)
app.get('/api/project/:slug', api.projects.show)
app.get('/api/rooms/:slug', api.rooms.show)
app.post('/api/project/new', middleware.ensureAuthenticated, api.projects.create)
@@ -144,6 +164,21 @@ site.route = function () {
app.post('/api/media/upload', middleware.ensureAuthenticated, api.media.upload)
app.delete('/api/media/destroy', middleware.ensureAuthenticated, api.media.destroy)
+ app.post('/api/blueprint/new', middleware.ensureAuthenticated, api.blueprint.create)
+ app.post('/api/blueprint/upload', middleware.ensureAuthenticated, api.blueprint.upload)
+ app.get('/api/blueprint/user/:slug', middleware.ensureAuthenticated, api.blueprint.show)
+ app.get('/api/blueprint/user', middleware.ensureAuthenticated, api.blueprint.user)
+ app.post('/api/blueprint/scale', middleware.ensureAuthenticated, api.blueprint.scale)
+ app.post('/api/blueprint/edit', middleware.ensureAuthenticated, api.blueprint.update)
+ app.delete('/api/blueprint/destroy', middleware.ensureAuthenticated, api.blueprint.destroy)
+
+ app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show)
+ app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update)
+ app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.sync)
+ app.delete('/api/subscription/destroy', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy)
+
+ app.get('/partials/plans', views.partials.plans)
+
app.get('/test/*', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.modal)
views.staff.route(app)
diff --git a/server/lib/api/blueprint.js b/server/lib/api/blueprint.js
new file mode 100644
index 0000000..e780b92
--- /dev/null
+++ b/server/lib/api/blueprint.js
@@ -0,0 +1,142 @@
+/* jshint node: true */
+
+var _ = require('lodash'),
+ crypto = require('crypto'),
+ util = require('../util'),
+ upload = require('../upload'),
+ config = require('../../../config.json'),
+ Blueprint = require('../schemas/Blueprint');
+
+var blueprint = {
+
+ user: function(req, res){
+ var offset = Number(req.query.offset) || 0
+ var limit = Math.min( Number(req.query.limit), 50 ) || 20
+ var query = { user_id: req.user._id }
+ if (req.query.tag) {
+ query.tag = req.query.tag
+ }
+ Blueprint.find(query)
+ .sort({'created_at': -1})
+ .skip(offset)
+ .limit(limit)
+ .exec(function(err, media){
+ res.json(media || [])
+ })
+ },
+
+ show: function(req, res){
+ Blueprint.findOne({ slug: req.params.slug }, function(err, doc){
+ if (doc) {
+ res.json(doc)
+ return
+ }
+ else {
+ Project.count({}, function(err, count){
+ var name = "Project #" + (count || 0)
+ res.json({ _id: "new", name: name, isNew: true })
+ })
+ }
+ })
+ },
+
+ create: function(req, res){
+ var data = util.cleanQuery(req.body)
+ data.user_id = req.user._id
+ data.created_at = new Date ()
+
+ if (data.tag) {
+ data.tag = util.sanitize(data.tag)
+ }
+
+ new Blueprint(data).save(function(err, rec){
+ if (err || ! rec) { return res.json({ error: err }) }
+ return res.json(rec)
+ })
+ },
+
+ upload: function(req, res){
+ var data = util.cleanQuery(req.body)
+ data.user_id = req.user._id
+ data.created_at = new Date ()
+ data.type = "image"
+
+ upload.put("media", req.files.image, {
+ username: req.user.username,
+ unacceptable: function(err){
+ res.json({ error: { errors: { media: { message: "Problem saving image: " + err } } } })
+ },
+ success: function(url){
+ data.url = url
+ done()
+ }
+ })
+
+ function done () {
+ new Blueprint(data).save(function(err, rec) {
+ if (err || ! rec) { return res.json({ error: err }) }
+ res.json(rec)
+ })
+ }
+ },
+
+ scale: function(req, res){
+ var _id = req.body._id
+ var data = util.cleanQuery(req.body)
+ if (! _id) { return res.json({ error: 404 }) }
+ Blueprint.findOne({ _id: _id }, function(err, doc){
+ if (! doc) { return res.json({ error: 404 }) }
+ if (String(doc.user_id) !== String(req.user._id)) { return res.json({ error: 404 }) }
+ doc.scale = data.scale
+ doc.units = data.units
+ doc.line = data.line
+ doc.save(function(err, rec){
+ if (err || ! rec) { return res.json({ error: err }) }
+ res.json(rec)
+ })
+ })
+ },
+
+ update: function(req, res){
+ var _id = req.body._id
+ var data = util.cleanQuery(req.body)
+ if (! _id) { return res.json({ error: 404 }) }
+ Blueprint.findOne({ _id: _id }, function(err, doc){
+ if (! doc) { return res.json({ error: 404 }) }
+ if (String(doc.user_id) !== String(req.user._id)) { return res.json({ error: 404 }) }
+
+ doc.name = util.sanitize(data.name)
+ doc.slug = util.slugify(data.name)
+ doc.units = util.sanitize(data.units)
+ doc.viewHeight = util.sanitizeNumber(data.viewHeight)
+ doc.wallHeight = util.sanitizeNumber(data.wallHeight)
+ doc.shapes = JSON.parse(data.shapes)
+ doc.startPosition = JSON.parse(data.startPosition)
+
+ doc.save(function(err, rec){
+ if (err || ! rec) { return res.json({ error: err }) }
+ res.json(rec)
+ })
+ })
+ },
+
+ destroy: function(req, res){
+ var _id = util.sanitize(req.body._id)
+ if (! _id || ! _id.length) {
+ res.json({ error: 404 })
+ return
+ }
+ Blueprint.findOne({ _id: _id }, function(err, doc){
+ if (! doc) { return res.json({ error: 404 }) }
+ if (String(doc.user_id) !== String(req.user._id)) {
+ return res.json({ error: "access denied" })
+ }
+ Blueprint.remove({ _id: _id }, function(err){
+ res.json({ status: "OK" })
+ })
+ })
+ }
+
+}
+
+module.exports = blueprint
diff --git a/server/lib/api/index.js b/server/lib/api/index.js
index 11e13fc..8254232 100644
--- a/server/lib/api/index.js
+++ b/server/lib/api/index.js
@@ -1,6 +1,7 @@
/* jshint node: true */
var api = {
+ blueprint: require('./blueprint'),
docs: require('./docs'),
layouts: require('./layouts'),
media: require('./media'),
@@ -8,6 +9,7 @@ var api = {
projects: require('./projects'),
rooms: require('./rooms'),
collaborator: require('./collaborator'),
+ subscription: require('./subscription'),
}
module.exports = api
diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js
index 641e9e2..2c68f71 100644
--- a/server/lib/api/layouts.js
+++ b/server/lib/api/layouts.js
@@ -3,13 +3,26 @@
var _ = require('lodash'),
util = require('../util'),
upload = require('../upload'),
+ middleware = require('../middleware'),
config = require('../../../config.json'),
+ Blueprint = require('../schemas/Blueprint'),
Layout = require('../schemas/Layout');
var layouts = {
index: function(req, res){
- Layout.find({}, function(err, docs){
- res.json(docs)
+ Layout.find({ is_stock: true }, function(err, stock_layouts){
+ Layout.find({ user_id: req.user._id, is_stock: false }, function(err, user_layouts){
+ Blueprint.find({ user_id: req.user._id }, function(err, blueprints){
+ res.json({
+ layouts: stock_layouts,
+ user_layouts: user_layouts,
+ blueprints: blueprints,
+ user: res.locals.user,
+ layoutCount: res.locals.layoutCount,
+ projectCount: res.locals.projectCount,
+ })
+ })
+ })
})
},
@@ -37,15 +50,24 @@ var layouts = {
data.rooms = JSON.parse(data.rooms)
data.startPosition = JSON.parse(data.startPosition)
- upload.put("layouts", req.files.thumbnail, {
- unacceptable: function(err){
- res.json({ error: { errors: { thumbnail: { message: "Problem saving thumbnail: " + err } } } })
- },
- success: function(url){
- data.photo = url
- done()
- }
- })
+ Layout.findOne({ slug: data.slug }, function(err, doc){
+ if (! err || doc) {
+ data.slug = data.slug + "-" + Date.now()
+ }
+ do_upload()
+ })
+
+ function do_upload () {
+ upload.put("layouts", req.files.thumbnail, {
+ unacceptable: function(err){
+ res.json({ error: { errors: { thumbnail: { message: "Problem saving thumbnail: " + err } } } })
+ },
+ success: function(url){
+ data.photo = url
+ done()
+ }
+ })
+ }
function done() {
new Layout(data).save(function(err, doc){
diff --git a/server/lib/api/media.js b/server/lib/api/media.js
index 1eb08c1..85cbdd6 100644
--- a/server/lib/api/media.js
+++ b/server/lib/api/media.js
@@ -10,13 +10,19 @@ var _ = require('lodash'),
var media = {
user: function(req, res){
+ var offset = Number(req.query.offset) || 0
+ var limit = Math.min( Number(req.query.limit), 50 ) || 20
var query = { user_id: req.user._id }
if (req.query.tag) {
query.tag = req.query.tag
}
- Media.find(query, function(err, media){
- res.json(media || [])
- })
+ Media.find(query)
+ .sort({'created_at': -1})
+ .skip(offset)
+ .limit(limit)
+ .exec(function(err, media){
+ res.json(media || [])
+ })
},
create: function(req, res){
@@ -43,7 +49,7 @@ var media = {
upload.put("media", req.files.image, {
username: req.user.username,
unacceptable: function(err){
- res.json({ error: { errors: { avatar: { message: "Problem saving image: " + err } } } })
+ res.json({ error: { errors: { media: { message: "Problem saving image: " + err } } } })
},
success: function(url){
data.url = url
diff --git a/server/lib/api/profile.js b/server/lib/api/profile.js
index fdd1bde..d72a2c3 100644
--- a/server/lib/api/profile.js
+++ b/server/lib/api/profile.js
@@ -10,6 +10,8 @@ var _ = require('lodash'),
var profile = {
show: function(req, res){
User.findOne({ _id: req.user._id }, function(err, user){
+ user = user.toObject()
+ delete user.password
res.json(err || user)
})
},
@@ -30,6 +32,7 @@ var profile = {
delete data.old_password
delete data.new_password
delete data.isStaff
+ delete data.plan_level
data.updated_at = new Date ()
if (req.files.avatar) {
diff --git a/server/lib/api/projects.js b/server/lib/api/projects.js
index 61a6e10..50d3b49 100644
--- a/server/lib/api/projects.js
+++ b/server/lib/api/projects.js
@@ -34,13 +34,21 @@ var projects = {
data.user_id = req.user._id
data.name = util.sanitize(data.name)
- data.slug = util.slugify(data.name)
+ data.slug = util.slugify(data.name) + "-" + (+new Date)
data.description = util.sanitize(data.description)
- data.rooms = JSON.parse(data.rooms)
+ data.viewHeight = Number(data.viewHeight || 0)
+ if (data.shapes) {
+ data.shapes = JSON.parse(data.shapes)
+ }
+ else {
+ data.rooms = JSON.parse(data.rooms)
+ }
data.walls = JSON.parse(data.walls)
data.media = JSON.parse(data.media)
+ data.sculpture = JSON.parse(data.sculpture)
data.colors = JSON.parse(data.colors)
data.startPosition = JSON.parse(data.startPosition)
+ data.lastPosition = JSON.parse(data.lastPosition)
data.created_at = new Date ()
upload.put("projects", req.files.thumbnail, {
@@ -67,13 +75,7 @@ var projects = {
return docs.create(req, res)
}
- var data = util.cleanQuery(req.body)
-
- // data.user_id = req.user._id
- data.name = util.sanitize(data.name)
- data.slug = util.slugify(data.name)
- data.description = util.sanitize(data.description)
- data.updated_at = new Date ()
+ var data = util.cleanQuery(req.body)
if (req.files.thumbnail) {
upload.put("projects", req.files.thumbnail, {
@@ -93,13 +95,30 @@ var projects = {
function done() {
Project.findOne({ _id: _id }, function(err, doc){
if (err || ! doc) { return res.json({ error: err }) }
+
+ // data.user_id = req.user._id
+ data.name = util.sanitize(data.name)
+ if (data.name != doc.name) {
+ data.slug = util.slugify(data.name) + "-" + (+new Date)
+ }
+ data.description = util.sanitize(data.description)
+ data.viewHeight = Number(data.viewHeight || 0)
+ data.updated_at = new Date ()
+
_.extend(doc, data)
-
- doc.rooms = JSON.parse(data.rooms)
+
+ if (data.shapes) {
+ doc.shapes = JSON.parse(data.shapes)
+ }
+ else {
+ doc.rooms = JSON.parse(data.rooms)
+ }
doc.walls = JSON.parse(data.walls)
doc.colors = JSON.parse(data.colors)
doc.media = JSON.parse(data.media)
- doc.startPosition = JSON.parse(data.startPosition)
+ doc.sculpture = JSON.parse(data.sculpture)
+ doc.startPosition = JSON.parse(data.startPosition)
+ doc.lastPosition = JSON.parse(data.lastPosition)
doc.save(function(err, doc){
if (err || ! doc) { return res.json({ error: err }) }
diff --git a/server/lib/api/rooms.js b/server/lib/api/rooms.js
index c044309..2a1d2fe 100644
--- a/server/lib/api/rooms.js
+++ b/server/lib/api/rooms.js
@@ -6,6 +6,8 @@ var Clipper = require("../../../public/assets/javascripts/rectangles/engine/room
var Builder = require("../../../public/assets/javascripts/rectangles/engine/rooms/builder.js")
var Grouper = require("../../../public/assets/javascripts/rectangles/engine/rooms/grouper.js")
var Walls = require("../../../public/assets/javascripts/rectangles/engine/rooms/_walls.js")
+var shapes = require("../../../public/assets/javascripts/rectangles/engine/shapes/shapelist.js")
+var RegionList = require("../../../public/assets/javascripts/rectangles/engine/shapes/regionlist.js")
/* jshint node: true */
@@ -21,47 +23,106 @@ var rooms = module.exports = {
if (! doc) { res.json({ status: 404 }); return }
doc = doc.toObject()
- doc.rooms.forEach(function(data){
- var rect = new Rect(data.rect.x[0], data.rect.y[0], data.rect.x[1], data.rect.y[1])
- var room = new Room({
- id: data.id,
- rect: rect,
- height: data.height
- })
- Rooms.add(room)
- })
- Rooms.clipper.solve_rects()
- Rooms.builder.build()
-
- var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = []
- var collections = Rooms.grouper.collect()
- Rooms.grouper.cull(collections)
- Rooms.grouper.group(walls, collections, FRONT)
- Rooms.grouper.group(walls, collections, BACK)
- Rooms.grouper.group(walls, collections, LEFT)
- Rooms.grouper.group(walls, collections, RIGHT)
- walls.forEach(function(wall){
- wall.mx.forEach(function(mx){
- var data = mx.report()
- data.id = wall.id
- mx_walls.push(data)
- })
- })
-
- doc.mx_walls = mx_walls
- doc.mx_floor = mx_floor
- doc.mx_ceiling = mx_ceiling
-
- Rooms.forEach(function(room){
- room.mx_floor.forEach(function(mx){
- mx_floor.push( mx.report() )
- })
- room.mx_ceiling.forEach(function(mx){
- mx_ceiling.push( mx.report() )
- })
- })
+ if (doc.shapes.length) {
+ parseMxShapes(doc)
+ }
+ else {
+ parseMxRooms(doc)
+ }
res.json(doc)
})
}
}
+
+function parseMxShapes (doc) {
+ var viewHeight = doc.viewHeight
+ var wallHeight = doc.wallHeight
+
+ shapes.deserialize( doc.shapes )
+
+ var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = []
+ var regions = RegionList.build()
+
+ regions.forEach(function(region){
+ var room = new Room({
+ rect: region,
+ regions: [region],
+ height: wallHeight,
+ })
+
+ room.sides = region.sides
+ region.id = Rooms.uid("room_")
+ Rooms.list[ region.id ] = room
+ Rooms.builder.build_walls(region)
+ mx_floor.push( Rooms.builder.make_floor(room, region) )
+ mx_ceiling.push( Rooms.builder.make_ceiling(room, region) )
+ })
+
+ var collections = Rooms.grouper.collect()
+ Rooms.grouper.cull(collections)
+ Rooms.grouper.group(walls, collections, FRONT)
+ Rooms.grouper.group(walls, collections, BACK)
+ Rooms.grouper.group(walls, collections, LEFT)
+ Rooms.grouper.group(walls, collections, RIGHT)
+ walls.forEach(function(wall){
+ wall.mx.forEach(function(mx){
+ var data = mx.report()
+ data.id = wall.id
+ mx_walls.push(data)
+ })
+ })
+
+ doc.mx_walls = mx_walls
+ doc.mx_floor = mx_floor
+ doc.mx_ceiling = mx_ceiling
+
+ Rooms.forEach(function(room){
+ mx_floor.push( room.mx_floor )
+ room.mx_ceiling.forEach(function(mx){
+ mx_ceiling.push( mx.report() )
+ })
+ })
+}
+
+function parseMxRooms (doc) {
+ doc.rooms.forEach(function(data){
+ var rect = new Rect(data.rect.x[0], data.rect.y[0], data.rect.x[1], data.rect.y[1])
+ var room = new Room({
+ id: data.id,
+ rect: rect,
+ height: data.height
+ })
+ Rooms.add(room)
+ })
+ Rooms.clipper.solve_rects()
+ Rooms.builder.build()
+
+ var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = []
+ var collections = Rooms.grouper.collect()
+ Rooms.grouper.cull(collections)
+ Rooms.grouper.group(walls, collections, FRONT)
+ Rooms.grouper.group(walls, collections, BACK)
+ Rooms.grouper.group(walls, collections, LEFT)
+ Rooms.grouper.group(walls, collections, RIGHT)
+ walls.forEach(function(wall){
+ wall.mx.forEach(function(mx){
+ var data = mx.report()
+ data.id = wall.id
+ mx_walls.push(data)
+ })
+ })
+
+ doc.mx_walls = mx_walls
+ doc.mx_floor = mx_floor
+ doc.mx_ceiling = mx_ceiling
+
+ Rooms.forEach(function(room){
+ room.mx_floor.forEach(function(mx){
+ mx_floor.push( mx.report() )
+ })
+ room.mx_ceiling.forEach(function(mx){
+ mx_ceiling.push( mx.report() )
+ })
+ })
+} \ No newline at end of file
diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js
new file mode 100644
index 0000000..c2fff4c
--- /dev/null
+++ b/server/lib/api/subscription.js
@@ -0,0 +1,206 @@
+/* jshint node: true */
+
+var _ = require('lodash'),
+ util = require('../util'),
+ upload = require('../upload'),
+ config = require('../../../config.json'),
+ User = require('../schemas/User'),
+ Project = require('../schemas/Project'),
+ Layout = require('../schemas/Layout'),
+ Plan = require('../schemas/Plan');
+ Subscription = require('../schemas/Subscription'),
+ Recurly = require('node-recurly'),
+ recurly = new Recurly(require('../webhook/recurly-config'));
+
+var plan_levels = {
+ free: 0,
+ basic: 1,
+ pro: 2,
+ custom: 3,
+}
+
+var subscription = module.exports = {
+ middleware: {
+ ensureSubscription: function(req, res, next){
+ Subscription.findOne({ user_id: req.user._id }, function(err, data){
+ if (err) { return next() }
+ req.subscription = data
+ next()
+ })
+ },
+ ensurePlans: function(req, res, next){
+ Plan.find({}).sort({ 'level': 1 }).exec(function (err, plans) {
+ res.locals.plans = (plans || [])
+ next()
+ })
+ },
+ },
+
+ // synchronise an account with recurly..
+ // useful when testing locally (where webhooks cannot be received)
+ // parses the XML from the subscription API into something usable
+ sync: function(req, res){
+ var subscriber = req.subscription || new Subscription ()
+ var user = req.user
+ recurly.subscriptions.listByAccount(req.user._id, function(recurlyRes){
+ var data = recurlyRes.data
+ if (recurlyRes.description !== 200) {
+ res.json({ error: "no account" })
+ return
+ }
+ var subscriptions = data.subscriptions.subscription.length ? data.subscriptions.subscription : [data.subscriptions.subscription]
+ var is_active = subscriptions.some(function(subscription_data){
+ if (subscription_data.state == "active") {
+ set_active(subscription_data)
+ return true
+ }
+ return false
+ })
+ if (! is_active) {
+ set_cancelled()
+ }
+ })
+ function set_cancelled(){
+ user.plan_type = "free"
+ user.plan_level = plan_levels["free"]
+
+ return subscriber.remove(function(){
+ user.save(function(){
+ res.json({ error: "account cancelled" })
+ })
+ })
+ }
+ function set_active(data){
+ var plan = data.plan.plan_code.split("-")
+ var plan_type = plan[0]
+ var plan_period = plan[1]
+
+ user.plan_type = plan_type
+ user.plan_level = plan_levels[plan_type]
+
+ subscriber.uuid = data.uuid
+ subscriber.user_id = user._id
+ subscriber.plan_type = plan_type
+ subscriber.plan_period = plan_period
+ subscriber.plan_level = plan_levels[plan_type]
+
+ var add_ons = data.subscription_add_ons.subscription_add_on
+ if (add_ons) {
+ if (add_ons.add_on_code) {
+ add_ons = [ add_ons ]
+ }
+ // TODO: handle multiple add-ons.. presumably this will work
+ add_ons.forEach(function(add_on){
+ var add_on_type = add_on.add_on_code.split("-")[1]
+ if (add_on_type == "basic") {
+ subscriber.basic_layouts = parseInt( add_on.quantity._ )
+ }
+ if (add_on_type == "pro") {
+ subscriber.pro_layouts = parseInt( add_on.quantity._ )
+ }
+ })
+ }
+ else {
+ subscriber.basic_layouts = 0
+ subscriber.pro_layouts = 0
+ }
+ subscriber.save(function(){
+ user.save(function(){
+ res.json({
+ subscription: subscriber,
+ plans: res.locals.plans
+ })
+ })
+ })
+ }
+ },
+
+ show: function(req, res){
+ if (req.subscription) {
+ res.json({
+ subscription: req.subscription,
+ plans: res.locals.plans
+ })
+ }
+ else {
+ res.json({
+ error: "no subscription",
+ plans: res.locals.plans,
+ })
+ }
+ },
+
+ update: function(req, res){
+ if (! req.subscription ) {
+ return res.json({ error: "no subscription" })
+ }
+ if (! (req.body.plan_type in plan_levels)) {
+ return res.json({ error: "bad input" })
+ }
+ var subscriber = req.subscription
+ var user = req.user
+
+ var plan_type = req.body.plan_type
+ var basic_layouts = Math.max(0, parseInt(req.body.basic_layouts || 0, 10))
+ var pro_layouts = Math.max(0, parseInt(req.body.pro_layouts || 0, 10))
+ if (plan_type != "pro") { pro_layouts = 0 }
+
+ if (plan_type == subscription.plan_type
+ && basic_layouts == subscriber.basic_layouts
+ && pro_layouts == subscriber.pro_layouts) {
+ return res.json(subscriber)
+ }
+
+ var data = { subscription_add_ons: [] }
+ data.plan_code = plan_type + "-monthly"
+
+ if (plan_levels[plan_type] > 0 && basic_layouts > 0) {
+ data.subscription_add_ons.push({ add_on_code: "extra-basic-layout", quantity: basic_layouts })
+ }
+
+ if (plan_type == "pro" && pro_layouts > 0) {
+ data.subscription_add_ons.push({ add_on_code: "extra-pro-layout", quantity: pro_layouts })
+ }
+
+ // data.plan_code
+ // data.subscription_add_ons = []
+ // add_on.add_on_code
+ // add_on.quantity
+ console.log(data)
+ recurly.subscriptions.update(subscriber.uuid, data, function(err, data){
+ console.log("got response from RECURLY ...")
+ if (err) {
+ console.log("error updating recurly subscription", err)
+ return res.json({ error: err })
+ }
+ subscriber.plan_type = plan_type
+ subscriber.basic_layouts = basic_layouts
+ subscriber.pro_layouts = pro_layouts
+ subscriber.save(function(){
+ user.plan_level = plan_levels[plan_type]
+ user.plan_type = plan_type
+ user.save(function(){
+ return res.json(subscriber)
+ })
+ })
+ })
+ },
+
+ destroy: function(req, res){
+ if (! req.subscription ) {
+ return res.json({ error: "no subscription" })
+ }
+ var subscriber = req.subscription
+
+ recurly.subscriptions.terminate(subscriber.uuid, "partial", function(err, data){
+ subscriber.remove(function(){
+ req.user.plan_code = 0
+ req.user.plan_type = "free"
+ req.user.save(function(){
+ res.json({ status: "OK" })
+ })
+ })
+ })
+ },
+
+}; \ No newline at end of file
diff --git a/server/lib/auth/index.js b/server/lib/auth/index.js
index c2275ff..46bff21 100644
--- a/server/lib/auth/index.js
+++ b/server/lib/auth/index.js
@@ -30,17 +30,23 @@ var auth = {
callbackURL: 'http://' + config.host + '/auth/twitter/callback'
}, auth.insertTwitterUser));
- /*
passport.use(new FacebookStrategy({
clientID: process.env.VVALLS_FACEBOOK_KEY || '719828821410310',
clientSecret: process.env.VVALLS_FACEBOOK_SECRET || 'f9aba78e08f37f621eadb88b1409d48c',
callbackURL: 'http://' + config.host + '/auth/facebook/callback',
enableProof: false,
}, auth.insertFacebookUser));
- */
+
auth.mail.init()
},
-
+ initBasicAuth: function(app){
+ if (config.basicAuth) {
+ app.use(express.basicAuth(function(user, pass) {
+ return user === config.basicAuth.user &&
+ pass === config.basicAuth.pass
+ }))
+ }
+ },
initSockets: function (io, SessionStore) {
io.set('authorization', passportSocketIo.authorize({
cookieParser: express.cookieParser,
@@ -87,9 +93,9 @@ var auth = {
return res.redirect('/auth/usernameTaken');
}
if (! user.created_ip) {
- user.created_ip = util.ip2num( req.ip )
+ user.created_ip = util.ip2num( req.session.ip )
}
- user.last_ip = util.ip2num( req.ip )
+ user.last_ip = util.ip2num( req.session.ip )
user.save(function(err, data){ if (err) console.err('error setting ip for user') })
req.logIn(user, function(err) {
@@ -112,7 +118,7 @@ var auth = {
}
user.last_seen = new Date ()
- user.last_ip = util.ip2num( req.ip )
+ user.last_ip = util.ip2num( req.session.ip )
user.save(function(err, data){ if (err) console.err('error setting ip for user') })
req.logIn(user, function(err) {
@@ -136,12 +142,12 @@ var auth = {
deserializeUser: function (id, done) {
try {
var _id = mongoose.Types.ObjectId(id)
- User.findOne({ _id: _id }, "_id displayName username photo isStaff", function (err, user) {
+ User.findOne({ _id: _id }, "_id displayName username photo isStaff plan_level", function (err, user) {
done(err, user);
});
}
catch (e) {
- User.findOne({ twitter_id: id }, "_id displayName username photo isStaff", function (err, user) {
+ User.findOne({ twitter_id: id }, "_id displayName username photo isStaff plan_level", function (err, user) {
done(err, user);
});
}
@@ -172,8 +178,8 @@ var auth = {
displayName: username,
password: password,
email: email,
- created_ip: util.ip2num( req.ip ),
- last_ip: util.ip2num( req.ip ),
+ created_ip: util.ip2num( req.session.ip ),
+ last_ip: util.ip2num( req.session.ip ),
created_at: new Date (),
last_seen: new Date (),
}
@@ -241,7 +247,7 @@ var auth = {
facebookUrl: profile.username ? "https://facebook.com/" + profile.username : ""
};
- User.findOne({twitter_id: profile.id}, function(err, data){
+ User.findOne({facebook_id: profile.id}, function(err, data){
if (! err && data) {
return done(err, data);
}
diff --git a/server/lib/auth/mail.js b/server/lib/auth/mail.js
index 0ba6d5d..990b53f 100644
--- a/server/lib/auth/mail.js
+++ b/server/lib/auth/mail.js
@@ -6,7 +6,7 @@ var email = require("emailjs"),
var mail = {
- from: 'Vvalls <info@vvalls.com>',
+ from: 'VValls <hello@vvalls.com>',
templates: {},
init: function(){
@@ -40,7 +40,7 @@ var mail = {
text: mail.templates.welcome.text(user),
from: mail.from,
to: user.email,
- subject: "Welcome to Vvalls",
+ subject: "Welcome to VValls",
attachment: [
{ data: mail.templates.welcome.html(user), alternative: true },
]
diff --git a/server/lib/middleware.js b/server/lib/middleware.js
index 0bf16ce..0a0a9ce 100644
--- a/server/lib/middleware.js
+++ b/server/lib/middleware.js
@@ -6,11 +6,16 @@ var passport = require('passport'),
config = require('../../config.json'),
User = require('./schemas/User'),
Collaborator = require('./schemas/Collaborator'),
- Project = require('./schemas/Project');
+ Project = require('./schemas/Project'),
+ Layout = require('./schemas/Layout'),
+ Blueprint = require('./schemas/Blueprint'),
+ Plan = require('./schemas/Plan');
var middleware = {
+ plans: [],
+
enableCORS: function (req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
// TODO Check https vs. http
@@ -33,17 +38,54 @@ var middleware = {
}
next();
},
+
+ ensureIP: function (req, res, next) {
+ if (req.session.ip) {
+ req.ip = req.session.ip || "127.0.0.1"
+ }
+ else if (req.ips) {
+ req.ip = req.session.ip = req.ips[0]
+ req.session.save()
+ }
+ next()
+ },
ensureLocals: function (req, res, next) {
- res.locals.token = req.csrfToken();
+ res.locals.token = req.csrfToken()
res.locals.logged_in = req.isAuthenticated()
res.locals.user = req.user || { _id: undefined }
res.locals.config = config
res.locals.profile = null
+ res.locals.ogImage = "http://okfocus.s3.amazonaws.com/images/vvalls-fb.png"
+ res.locals.ogTitle = "VValls"
+ res.locals.ogUrl = "http://vvalls.com/"
+ res.locals.ogDescription = "3D gallery space, fully customizable"
+ res.locals.ogAuthor = "VValls"
+ res.locals.plans = middleware.plans
res.locals.opt = {}
next()
},
+ ensureUserProjectsCount: function(req, res, next){
+ var counts = { stock: 0, basic: 0, pro: 0 }
+ res.locals.projectCounts = counts
+ Project.count({ user_id: req.user._id }, function(err, count){
+ res.locals.projectCount = count || 0
+ next()
+ })
+ },
+
+ ensureUserLayoutsCount: function(req, res, next){
+ var counts = { basic: 0, pro: 0 }
+ res.locals.layoutCounts = counts
+ if (req.user.plan_level == 0) { return next() }
+
+ Layout.count({ user_id: req.user._id }, function(err, count){
+ res.locals.layoutCount = count || 0
+ next()
+ })
+ },
+
ensureProject: function (req, res, next) {
if (req.params.slug) {
Project.findOne({ slug: req.params.slug }, function(err, project){
@@ -59,13 +101,57 @@ var middleware = {
}
next()
})
- }
+ }
else {
req.project = null
next()
}
},
+ ensureLayout: function (req, res, next) {
+ if (req.params.slug) {
+ Layout.findOne({ slug: req.params.slug }, function(err, layout){
+ if (err) {
+ console.error(err)
+ req.layout = null
+ }
+ else if (! layout) {
+ req.layout = null
+ }
+ else {
+ req.layout = layout
+ }
+ next()
+ })
+ }
+ else {
+ req.layout = null
+ next()
+ }
+ },
+
+ ensureBlueprint: function (req, res, next) {
+ if (req.params.slug) {
+ Blueprint.findOne({ slug: req.params.slug }, function(err, blueprint){
+ if (err) {
+ console.error(err)
+ req.blueprint = null
+ }
+ else if (! blueprint) {
+ req.blueprint = null
+ }
+ else {
+ req.blueprint = blueprint
+ }
+ next()
+ })
+ }
+ else {
+ req.blueprint = null
+ next()
+ }
+ },
+
ensureIsCollaborator: function(req, res, next) {
req.isCollaborator = false
req.isOwner = false
@@ -90,6 +176,12 @@ var middleware = {
})
}
},
+
+ updatePlans: function(){
+ Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) {
+ middleware.plans = plans.map(function(plan){ return plan.toObject() })
+ })
+ },
}
diff --git a/server/lib/schemas/Blueprint.js b/server/lib/schemas/Blueprint.js
new file mode 100644
index 0000000..3c3b0cc
--- /dev/null
+++ b/server/lib/schemas/Blueprint.js
@@ -0,0 +1,66 @@
+/* jshint node: true */
+
+var mongoose = require('mongoose'),
+ _ = require('lodash'),
+ util = require('../util');
+
+var BlueprintSchema = new mongoose.Schema({
+ type: {
+ type: String,
+ required: true
+ },
+ url: {
+ type: String,
+ required: true,
+ },
+ token: {
+ type: String,
+ default: ""
+ },
+ thumbnail: {
+ type: String,
+ default: ""
+ },
+ width: {
+ type: Number,
+ default: 0
+ },
+ height: {
+ type: Number,
+ default: 0
+ },
+ name: {
+ type: String,
+ default: ""
+ },
+ slug: {
+ type: String,
+// required: true,
+ validate: [function (val){
+ val = util.sanitize(val || this.displayName || "")
+// if (! val.length) return false
+ return true
+ },"{PATH} name is required"]
+ },
+ description: {
+ type: String,
+ default: ""
+ },
+ tag: { type: String, default: "" },
+ scale: { type: Number, default: 1.0 },
+
+ widthDimension: { type: Number },
+ heightDimension: { type: Number },
+ wallHeight: { type: Number },
+ units: { type: String },
+ line: { type: String },
+
+ shapes: [mongoose.Schema.Types.Mixed],
+ startPosition: mongoose.Schema.Types.Mixed,
+
+ user_id: { type: mongoose.Schema.ObjectId, index: true },
+ created_at: { type: Date },
+});
+
+module.exports = exports = mongoose.model('blueprint', BlueprintSchema)
+exports.schema = BlueprintSchema;
diff --git a/server/lib/schemas/Layout.js b/server/lib/schemas/Layout.js
index e3f2616..e15e188 100644
--- a/server/lib/schemas/Layout.js
+++ b/server/lib/schemas/Layout.js
@@ -23,9 +23,12 @@ var LayoutSchema = new mongoose.Schema({
photo: {
type: String,
},
+ media: mongoose.Schema.Types.Mixed,
rooms: [mongoose.Schema.Types.Mixed],
startPosition: mongoose.Schema.Types.Mixed,
viewHeight: { type: Number },
+ is_stock: { type: Boolean, default: false },
+ is_pro: { type: Boolean, default: false },
user_id: { type: mongoose.Schema.ObjectId, index: true },
created_at: { type: Date },
updated_at: { type: Date },
diff --git a/server/lib/schemas/Media.js b/server/lib/schemas/Media.js
index 1de354d..f37fb12 100644
--- a/server/lib/schemas/Media.js
+++ b/server/lib/schemas/Media.js
@@ -37,11 +37,12 @@ var MediaSchema = new mongoose.Schema({
type: String,
default: ""
},
- autoplay: { type: Boolean, default: false },
- loop: { type: Boolean, default: false },
- mute: { type: Boolean, default: true },
+ autoplay: { type: Boolean, default: true },
+ loop: { type: Boolean, default: true },
+ mute: { type: Boolean, default: false },
keyframe: { type: Number, default: 0.0 },
tag: { type: String, default: "" },
+ scale: { type: Number, default: 1.0 },
widthDimension: { type: Number },
heightDimension: { type: Number },
diff --git a/server/lib/schemas/Plan.js b/server/lib/schemas/Plan.js
new file mode 100644
index 0000000..388ce69
--- /dev/null
+++ b/server/lib/schemas/Plan.js
@@ -0,0 +1,44 @@
+/* jshint node: true */
+
+var mongoose = require('mongoose'),
+ _ = require('lodash'),
+ crypto = require('crypto'),
+ config = require('../../../config.json'),
+ util = require('../util');
+
+var PlanSchema = new mongoose.Schema({
+ name: { type: String },
+ slug: { type: String },
+
+ level: { type: Number },
+
+ monthly_price: { type: Number },
+ yearly_price: { type: Number },
+
+ basic_layout_monthly_price: { type: Number },
+ basic_layout_yearly_price: { type: Number },
+
+ pro_layout_monthly_price: { type: Number },
+ pro_layout_yearly_price: { type: Number },
+
+ basic_layout_limit: { type: Number },
+ pro_layout_limit: { type: Number },
+
+ stock_project_limit: { type: Number },
+ basic_project_limit: { type: Number },
+ pro_project_limit: { type: Number },
+
+ permissions: {
+ basic_editor: { type: Boolean, default: false },
+ pro_editor: { type: Boolean, default: false },
+ sculpture: { type: Boolean, default: false },
+ collaborators: { type: Boolean, default: false },
+ no_logo: { type: Boolean, default: false },
+ },
+
+ created_at: { type: Date, default: Date.now },
+ updated_at: { type: Date, default: Date.now },
+})
+
+module.exports = exports = mongoose.model('plan', PlanSchema);
+exports.schema = PlanSchema;
diff --git a/server/lib/schemas/Project.js b/server/lib/schemas/Project.js
index abf34fb..687555d 100644
--- a/server/lib/schemas/Project.js
+++ b/server/lib/schemas/Project.js
@@ -28,13 +28,20 @@ var ProjectSchema = new mongoose.Schema({
type: String,
},
rooms: [mongoose.Schema.Types.Mixed],
+ shapes: [mongoose.Schema.Types.Mixed],
walls: [mongoose.Schema.Types.Mixed],
media: [mongoose.Schema.Types.Mixed],
+ sculpture: [mongoose.Schema.Types.Mixed],
colors: mongoose.Schema.Types.Mixed,
startPosition: mongoose.Schema.Types.Mixed,
+ lastPosition: mongoose.Schema.Types.Mixed,
+ viewHeight: { type: Number },
+ units: { type: String, default: "ft" },
user_id: { type: mongoose.Schema.ObjectId, index: true },
created_at: { type: Date },
updated_at: { type: Date },
+ featured: { type: Boolean, default: false },
+ layout_type: { type: Number, default: 0 },
});
module.exports = exports = mongoose.model('project', ProjectSchema);
diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js
new file mode 100644
index 0000000..bf43e8b
--- /dev/null
+++ b/server/lib/schemas/Subscription.js
@@ -0,0 +1,31 @@
+/* jshint node: true */
+
+var mongoose = require('mongoose'),
+ _ = require('lodash'),
+ crypto = require('crypto'),
+ config = require('../../../config.json'),
+ util = require('../util');
+
+var SubscriptionSchema = new mongoose.Schema({
+ user_id: { type: mongoose.Schema.ObjectId, index: true },
+
+ plan_code: { type: String, default: "" },
+ plan_type: { type: String, default: "free" },
+ plan_period: { type: String, default: "monthly" },
+
+ uuid: { type: String },
+ basic_layouts: { type: Number, default: 0 },
+ pro_layouts: { type: Number, default: 0 },
+
+ history: [{
+ action: { type: String },
+ data: { type: String },
+ created_at: { type: Date, default: Date.now },
+ }],
+
+ created_at: { type: Date, default: Date.now },
+ updated_at: { type: Date, default: Date.now },
+})
+
+module.exports = exports = mongoose.model('subscription', SubscriptionSchema);
+exports.schema = SubscriptionSchema;
diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js
index 180a140..829b360 100644
--- a/server/lib/schemas/User.js
+++ b/server/lib/schemas/User.js
@@ -54,7 +54,12 @@ var UserSchema = new mongoose.Schema({
type: String,
default: "",
},
-
+
+ plan_code: { type: String, default: "" },
+ plan_level: { type: Number, default: 0 },
+ plan_type: { type: String, default: "free" },
+ last_charged: { type: Date, default: null },
+
location: { type: String, default: "" },
photo: { type: String, default: "" },
bio: { type: String, default: "" },
@@ -62,6 +67,8 @@ var UserSchema = new mongoose.Schema({
twitterName: { type: String, default: "" },
facebookUrl: { type: String, default: "" },
isStaff: { type: Boolean, default: false },
+ isArtist: { type: Boolean, default: false },
+ subscription_id: { type: mongoose.Schema.ObjectId },
created_at: { type: Date },
updated_at: { type: Date },
last_seen: { type: Date },
diff --git a/server/lib/upload.js b/server/lib/upload.js
index e206f7c..f6e22da 100644
--- a/server/lib/upload.js
+++ b/server/lib/upload.js
@@ -41,7 +41,7 @@ module.exports.put = function (key, file, opt) {
err = "file too small"
}
else if (file.size > 2097152) { // 2mb limit
- err = "file too large"
+ err = "file too large. Uploads can be a maximum of 2 mb."
}
if (err) {
diff --git a/server/lib/util.js b/server/lib/util.js
index 791d3e2..86fbdcc 100644
--- a/server/lib/util.js
+++ b/server/lib/util.js
@@ -5,19 +5,24 @@ var whitespace = new RegExp('\\s', 'g')
var whitespaceHead = /^\s+/
var whitespaceTail = /\s+$/
var nonAlphanumerics = new RegExp('[^-_a-zA-Z0-9]', 'g')
+var nonNumerics = new RegExp('[^0-9]', 'g')
var consecutiveDashes = new RegExp("-+", 'g')
var entities = new RegExp("[<>&]", 'g')
var util = {}
-util.trim = function (s){ return (s || "").replace(whitespaceHead,"").replace(whitespaceTail,"") }
-
+util.trim = function (s){
+ return (s || "").replace(whitespaceHead,"").replace(whitespaceTail,"")
+}
util.slugify = function (s){
return (s || "").toLowerCase().replace(whitespace,"-").replace(nonAlphanumerics, '-').replace(consecutiveDashes,"-")
}
util.sanitize = function (s){
return (s || "").replace(entities, "")
}
+util.sanitizeNumber = function (s){
+ return (s || "").replace(nonNumerics, "")
+}
util.escape = function (s){
return (s || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
}
@@ -30,8 +35,9 @@ util.capitalizeWord = function (s) {
util.escapeRegExp = function (s) {
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
}
-
-
+util.htmlize = function(s) {
+ return s.replace(/\n/g,"<br>")
+}
util.cleanQuery = function (query) {
var update = _.extend({}, query);
delete update._id;
@@ -41,12 +47,10 @@ util.cleanQuery = function (query) {
delete update.created_by;
return update;
}
-
util.ip2num = function(dot) {
- var d = dot.split('.');
+ var d = (dot || "127.0.0.1").split('.');
return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
}
-
util.num2ip = function(num) {
if (! num) return ""
var d = num % 256;
diff --git a/server/lib/views/index.js b/server/lib/views/index.js
index 29b84d8..523f628 100644
--- a/server/lib/views/index.js
+++ b/server/lib/views/index.js
@@ -4,6 +4,7 @@ var User = require('../schemas/User'),
Project = require('../schemas/Project'),
Documentation = require('../schemas/Documentation'),
Collaborator = require('../schemas/Collaborator'),
+ Plan = require('../schemas/Plan'),
config = require('../../../config'),
marked = require('marked'),
util = require('../util'),
@@ -11,145 +12,273 @@ var User = require('../schemas/User'),
moment = require('moment');
marked.setOptions({
- renderer: new marked.Renderer(),
- gfm: true,
- sanitize: true,
- smartLists: true,
- smartypants: true,
+ renderer: new marked.Renderer(),
+ gfm: true,
+ sanitize: true,
+ smartLists: true,
+ smartypants: true,
});
-var views = {}
+var views = module.exports = {
-views.staff = require('./staff')
+ staff: require('./staff'),
-views.editor_new = function (req, res) {
- if (! req.user) {
- res.redirect('/')
- }
- else {
- res.render('editor')
- }
-}
+ editor_new: function (req, res) {
+ if (! req.user) {
+ res.redirect('/')
+ }
+ else {
+ res.locals.opt.editing = true
+ res.render('editor')
+ }
+ },
-views.editor = function (req, res) {
- if (! req.project) {
- res.redirect('/')
- }
- else if (req.isOwner || req.isCollaborator || req.isStaff) {
- res.render('editor')
- }
- else {
- views.reader(req, res)
- }
-}
+ editor: function (req, res) {
+ if (! req.project) {
+ res.redirect('/')
+ }
+ else if (req.user && (req.isOwner || req.isCollaborator || req.isStaff)) {
+ res.locals.opt.editing = true
+ res.render('editor', {
+ ogUrl: "http://vvalls.com/project/" + req.project.slug + "/",
+ })
+ }
+ else {
+ res.redirect("/project/" + req.project.slug + "/")
+ }
+ },
-views.reader = function (req, res) {
- if (! req.project) {
- res.redirect('/')
- return
- }
- User.findOne({ _id: req.project.user_id }, function(err, user) {
- if (err || ! user) {
- console.error(err)
+ reader: function (req, res) {
+ if (! req.project) {
res.redirect('/')
return
}
- res.render('reader', {
- name: util.sanitize(req.project.name),
- description: util.sanitize(req.project.description),
- date: moment(req.project.updated_at).format("M/DD/YYYY"),
- author: user.displayName,
- authorlink: "/profile/" + user.username,
- canEdit: req.isOwner || req.isCollaborator,
- editlink: "/project/" + req.project.slug + "/edit",
- noui: !! (req.query.noui === '1'),
+ User.findOne({ _id: req.project.user_id }, function(err, user) {
+ if (err || ! user) {
+ console.error(err)
+ res.redirect('/')
+ return
+ }
+ var ogImage
+ if (req.project.media.length && req.project.media[0].media.type == "image") {
+ ogImage = req.project.media[0].media.url
+ }
+ res.render('reader', {
+ name: util.sanitize(req.project.name),
+ description: util.sanitize(req.project.description),
+ date: moment(req.project.updated_at).format("M/DD/YYYY"),
+ author: user.displayName,
+ authorlink: "/profile/" + user.username,
+ authorpic: user.photo,
+ canEdit: req.isOwner || req.isCollaborator,
+ editlink: "/project/" + req.project.slug + "/edit",
+ noui: !! (req.query.noui === '1'),
+ ogTitle: req.project.name,
+ ogUrl: "http://vvalls.com/project/" + req.project.slug + "/",
+ ogImage: ogImage,
+ })
})
- })
-}
+ },
-views.builder = function (req, res) {
- res.render('builder')
-}
+ builder: function (req, res) {
+ res.render('builder')
+ },
-views.modal = function (req, res) {
- res.render('modal');
-};
+ blueprint: function (req, res) {
+ res.render('blueprint')
+ },
-views.home = function (req, res) {
- if (req.user) {
- Project.find({ privacy: false })
- .sort('-created_at')
- .limit(20)
- .exec(function(err, projects){
- res.render('home', { projects: projects || [] })
- })
- }
- else {
- res.send("<html></html>")
- }
-}
+ modal: function (req, res) {
+ res.render('modal');
+ },
-views.docs = function (req, res){
- var name = req.params.name || "index"
-
- if (name === "new") {
- res.render('docs', {
- doc: { name: "new" },
- content: null,
- isNew: true
- })
- return
- }
-
- Documentation.findOne({ name: name }, function(err, doc) {
- if (err || ! doc) {
- return res.render('docs', {
- doc: { name: util.sanitize(name) },
+ home: function (req, res) {
+ views_middleware.ensurePlans(req, res, function(err){
+ views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){
+ res.render('home', {
+ projects: projects || [],
+ })
+ })
+ })
+ },
+
+ demoHome: function (req, res) {
+ views_middleware.ensurePlans(req, res, function(err){
+ views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){
+ res.render('home', {
+ projects: projects || [],
+ })
+ })
+ })
+ },
+
+ partials: {
+ plans: function (req, res){
+ views_middleware.ensurePlans(req, res, function(){
+ res.render('about/_plans', { logged_in: res.locals.logged_in || false })
+ })
+ },
+ },
+
+ docs: function (req, res){
+ var name = req.params.name || "about"
+
+ if (name == "howto") {
+ res.render('about/' + name)
+ return
+ }
+ if (name == "brochure" || name == "plans") {
+ // TODO: fetch plans
+ views_middleware.ensurePlans(req, res, function(){
+ res.render('about/' + name)
+ })
+ return
+ }
+ if (name == "about" || name == "index") {
+ res.render('about/' + name)
+ return
+ }
+
+ if (name === "new") {
+ res.render('docs', {
+ doc: { name: "new" },
content: null,
isNew: true
})
+ return
}
- res.render('docs', {
- doc: doc,
- content: marked(doc.body),
- isNew: false
- })
- })
-}
-views.profile = function (req, res) {
- var username = req.params.username || (req.user && req.user.username)
- if (username) {
- User.findOne({ username: username }, function (err, user) {
- user ? next(user) : done(err, {}, [])
+ Documentation.findOne({ name: name }, function(err, doc) {
+ if (err || ! doc) {
+ return res.render('docs', {
+ doc: { name: util.sanitize(name) },
+ content: null,
+ isNew: true
+ })
+ }
+ res.render('docs', {
+ doc: doc,
+ content: util.htmlize(doc.body),
+ isNew: false
+ })
})
- }
- else {
- done()
- }
-
- function next(user){
- var criteria = { user_id: user._id }
- if ( ! (req.user && req.user._id && req.user._id == user._id) ) {
- criteria.privacy = false
+ },
+
+ profile: function (req, res) {
+ var username = req.params.username || (req.user && req.user.username)
+ var user, isOwnProfile = false
+ if (username) {
+ User.findOne({ username: username }, function (err, profileUser) {
+ if (profileUser) {
+ user = profileUser
+ isOwnProfile = (String(user._id) == (req.user && String(req.user._id)))
+ next()
+ }
+ else {
+ done(err, [])
+ }
+ })
+ }
+ else {
+ done()
}
- Project.find(criteria, function(err, projects){
- projects = projects.map(function(project){
- project = project.toObject()
- project.date = moment(project.updated_at).format("M/DD/YYYY")
- return project
+
+ function next(){
+ var criteria = { user_id: user._id }
+ if ( ! isOwnProfile ) {
+ criteria.privacy = false
+ }
+ views_middleware.fetchProjects(criteria, null, null, function(err, projects){
+ views_middleware.fetchUserProjectCount(criteria, function(projectCount){
+ done(err, projects, projectCount)
+ })
})
- done(err, user, projects)
- })
- }
+ }
+
+ function done(err, projects, projectCount){
+ if (! user) { return res.redirect('/') }
+ res.render('profile', {
+ isOwnProfile: isOwnProfile,
+ profile: user,
+ projects: projects || [],
+ projectCount: projectCount,
+ ogTitle: "VValls: Profile of " + user.displayName,
+ ogUrl: "http://vvalls.com/profile/" + user.username + "/",
+ ogImage: user.photo,
+ })
+ }
+ },
- function done(err, user, projects){
- if (! user) { return res.redirect('/') }
- res.render('profile', {
- profile: user,
- projects: projects || [],
- })
- }
+ projectsPaginate: function(req, res) {
+ var criteria = {}
+ var offset = Number(req.query.offset || 0)
+ var user_id, isOwnProfile
+
+ if (req.query.home) {
+ criteria.featured = true
+ criteria.privacy = false
+ }
+ else if (req.query.user_id) {
+ user_id = req.query.user_id
+ isOwnProfile = (String(user_id) == (req.user && String(req.user._id)))
+
+ criteria.user_id = user_id
+ if ( ! isOwnProfile ) {
+ criteria.privacy = false
+ }
+ }
+ else {
+ res.end("")
+ return
+ }
+
+ views_middleware.fetchProjects(criteria, null, offset, function(err, projects){
+ res.render('projects/list-projects', {
+ projects: projects || []
+ })
+ })
+ },
+
}
-module.exports = views
+var views_middleware = {
+ ensurePlans: function(req, res, next){
+ Plan.find(function (err, plans) {
+ res.locals.plans = {}
+ plans.forEach(function(plan){
+ res.locals.plans[ plan.slug ] = plan
+ "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price pro_layout_monthly_price pro_layout_yearly_price".split(" ").forEach(function(key){
+ plan[key] = (plan[key]/100).toFixed(2)+""
+ })
+ })
+ next()
+ })
+ },
+
+ fetchProjects: function (criteria, limit, offset, next) {
+ limit = limit || 7
+ offset = offset || 0
+ Project.find(criteria)
+ .sort('-created_at')
+ .skip(offset)
+ .limit(limit)
+ .exec(function(err, projects){
+ projects = projects.map(function(project){
+ project = project.toObject()
+ project.date = moment(project.updated_at).format("M/D/YYYY")
+ if (! project.colors || project.colors.wall && project.colors.wall[0] == project.colors.wall[1] && project.colors.wall[1] == project.colors.wall[2] && project.colors.wall[2] > 238) {
+ project.color = [238,238,238]
+ } else {
+ project.color = project.colors.wall
+ }
+ return project
+ })
+ next(err, projects)
+ })
+ },
+ fetchUserProjectCount: function(criteria, next){
+ Project.count(criteria, function(err, count){
+ next(count || 0)
+ })
+ },
+}
diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js
deleted file mode 100644
index ffacee2..0000000
--- a/server/lib/views/staff.js
+++ /dev/null
@@ -1,530 +0,0 @@
-/* jshint node: true */
-
-var User = require('../schemas/User'),
- Project = require('../schemas/Project'),
- Media = require('../schemas/Media'),
- Collaborator = require('../schemas/Collaborator'),
- config = require('../../../config'),
- middleware = require('../middleware'),
- util = require('../util'),
- _ = require('lodash'),
- moment = require('moment');
-
-
-var staff = module.exports = {
-
- fields: {
- user: "_id username displayName photo created_at updated_at last_seen created_ip last_ip",
- project: "_id name slug user_id privacy created_at updated_at",
- },
-
- defaults: {
- user: {
- _id: "", username: "", displayName: "",
- created_at: "", updated_at: "", created_ip: "", last_ip: "",
- },
- },
-
- middleware: {
-
- ensureUsers: function(req, res, next){
- var paginationInfo = res.locals.pagination = {}
- var criteria = req.criteria || {}
- var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
- var offset = paginationInfo.offset = Number(req.query.offset) || 0
- var sort
- paginationInfo.sort = req.query.sort
- paginationInfo.sortOptions = ["date", "last_seen", "username"]
- switch (req.query.sort) {
- case 'date':
- sort = {'created_at': -1}
- break
- case 'last_seen':
- sort = {'last_seen': -1}
- break
- case 'username':
- default:
- sort = {'username': 1}
- paginationInfo.sort = "username"
- break
- }
- User.find(criteria)
- .select(staff.fields.user)
- .sort(sort)
- .skip(offset)
- .limit(limit)
- .exec(function (err, users) {
- res.locals.users = users.map(staff.helpers.user)
- next()
- })
- },
-
- ensureRecentUsers: function(req, res, next){
- var dreq = { query: { sort: 'last_seen', limit: 20, offset: 0 } }
- staff.middleware.ensureUsers(dreq, res, next)
- },
-
- ensureProjects: function(req, res, next){
- var paginationInfo = res.locals.pagination = {}
- var criteria = req.criteria || {}
- var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
- var offset = paginationInfo.offset = Number(req.query.offset) || 0
- var sort
- paginationInfo.sort = req.query.sort
- paginationInfo.sortOptions = ["date", "name"]
- switch (req.query.sort) {
- case 'date':
- sort = {'created_at': -1}
- break
- case 'name':
- default:
- paginationInfo.sort = "name"
- sort = {'slug': 1}
- break
- }
- Project.find(criteria)
- .select(staff.fields.project)
- .sort(sort)
- .skip(offset)
- .limit(limit)
- .exec(function (err, projects) {
- res.locals.projects = projects.map(staff.helpers.project)
- next()
- })
- },
-
- ensureMedia: function(req, res, next){
- var paginationInfo = res.locals.pagination = {}
- var criteria = req.criteria || {}
- var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
- var offset = paginationInfo.offset = Number(req.query.offset) || 0
- var sort
- paginationInfo.sort = req.query.sort
- paginationInfo.sortOptions = ["date"]
- switch (req.query.sort) {
- default:
- case 'date':
- paginationInfo.sort = "date"
- sort = {'created_at': -1}
- break
- }
- Media.find(criteria)
- // .select(staff.fields.media)
- .sort(sort)
- .skip(offset)
- .limit(limit)
- .exec(function (err, media) {
- res.locals.media = media.map(staff.helpers.media)
- next()
- })
- },
-
- ensureRecentProjects: function(req, res, next){
- var dreq = { params: { sort: 'created_at', limit: 20, offset: 0 } }
- staff.middleware.ensureProjects(dreq, res, next)
- },
-
- ensureProjectsUsers: function(req, res, next){
- if (! res.locals.projects || ! res.locals.projects.length) { return next() }
- staff.middleware.ensureObjectsUsers(res.locals.projects, next)
- },
-
- ensureMediaUsers: function(req, res, next){
- if (! res.locals.media || ! res.locals.media.length) { return next() }
- staff.middleware.ensureObjectsUsers(res.locals.media, next)
- },
-
- ensureMediaUser: function(req, res, next){
- if (! res.locals.media) { return next() }
- staff.middleware.ensureObjectsUsers([ res.locals.media ], function(){
- res.locals.mediaUser = res.locals.media.User
- next()
- })
- },
-
- ensureObjectsUsers: function(objects, next){
- if (! objects) { return next () }
- var dedupe = {}, user_ids
- objects.forEach(function(obj){
- dedupe[ obj.user_id ] = dedupe[ obj.user_id ] || []
- dedupe[ obj.user_id ].push(obj)
- })
- user_ids = _.keys(dedupe)
- User.find({ _id: user_ids })
- .select(staff.fields.user)
- .exec(function (err, users) {
- if (! users) { return next () }
- users.forEach(function(user){
- dedupe[user._id].forEach(function(obj){
- obj.user = user
- })
- })
- next()
- })
- },
-
- ensureProfile: function(req, res, next){
- var username = req.params.username
- if (username) {
- User.findOne({ username: username }, function (err, user) {
- if (user) {
- res.locals.profile = req.method == "GET" ? staff.helpers.user(user) : user
- }
- else {
- res.locals.profile = null
- }
- next()
- })
- }
- else {
- res.locals.profile = null
- next()
- }
- },
-
- ensureSingleMedia: function(req, res, next){
- var id = req.params.id
- if (id) {
- Media.findOne({ _id: id }, function (err, media) {
- if (media) {
- res.locals.media = req.method == "GET" ? staff.helpers.media(media) : media
- }
- else {
- res.locals.media = null
- }
- next()
- })
- }
- else {
- res.locals.media = null
- next()
- }
- },
-
- ensureUsersCount: function(req, res, next){
- User.count({}, function(err, count){
- res.locals.userCount = count || 0
- next()
- })
- },
-
- ensureProjectsCount: function(req, res, next){
- Project.count({}, function(err, count){
- res.locals.projectCount = count || 0
- next()
- })
- },
-
- ensureMediaCount: function(req, res, next){
- Media.count({}, function(err, count){
- res.locals.mediaCount = count || 0
- next()
- })
- },
-
- ensureProfileProjectCount: function(req, res, next){
- if (! res.locals.profile) { return next() }
- Project.count({ user_id: res.locals.profile._id}, function(err, count){
- res.locals.profile.projectCount = count || 0
- next()
- })
- },
-
- ensureProfileMediaCount: function(req, res, next){
- if (! res.locals.profile) { return next() }
- Media.count({ user_id: res.locals.profile._id}, function(err, count){
- res.locals.profile.mediaCount = count || 0
- next()
- })
- },
-
- ensureProfileProjects: function(req, res, next){
- if (! res.locals.profile) { return next() }
- Project.find({ user_id: res.locals.profile._id }, staff.fields.project, function(err, projects){
- res.locals.projects = projects.map(staff.helpers.project)
- next()
- })
- },
-
- ensureProfileMedia: function(req, res, next){
- if (! res.locals.profile) { return next() }
- req.criteria = { user_id: res.locals.profile._id }
- staff.middleware.ensureMedia(req, res, next)
- },
-
- ensureProject: function(req, res, next){
- res.locals.project = req.project
- next()
- },
-
- ensureProjectUser: function(req, res, next){
- if (! res.locals.project) { return next() }
- User.findOne({ _id: res.locals.project.user_id }, staff.fields.user, function(err, user){
- res.locals.projectUser = staff.helpers.user(user) || staff.defaults.user
- next()
- })
- },
-
- ensureProjectCollaborators: function(req, res, next){
- if (! res.locals.project) {
- res.locals.collaborators = []
- return next()
- }
- Collaborator.find({ project_id: res.locals.project._id}, function(err, collaborators){
- res.locals.collaborators = collaborators || []
- next()
- })
- },
- },
-
- helpers: {
- user: function(user){
- user = user.toObject()
- user.last_seen = moment( user.last_seen || user.updated_at || user.created_at ).fromNow()
- user.created_ip = util.num2ip( user.created_ip )
- user.last_ip = util.num2ip( user.last_ip )
- return user
- },
-
- project: function(project){
- project = project.toObject()
- project.date = moment( project.updated_at || project.created_at ).format("M/DD/YYYY H:MM")
- project.user = {}
- return project
- },
-
- media: function(media){
- media = media.toObject()
- media.date = moment( media.updated_at || media.created_at ).format("M/DD/YYYY H:MM")
- media.user = {}
- media.shortUrl = media.url.replace(/^http.:\/\//,"")
- return media
- }
- },
-
- route: function(app){
- app.get('/staff',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureRecentUsers,
- staff.middleware.ensureUsersCount,
- staff.middleware.ensureProjectsCount,
- staff.middleware.ensureMediaCount,
-
- staff.index
- );
-
- //
- // users
-
- app.get('/staff/users',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureUsersCount,
- staff.middleware.ensureUsers,
-
- staff.users.index
- );
- app.get('/staff/users/:username',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureProfile,
- staff.middleware.ensureProfileProjectCount,
- staff.middleware.ensureProfileMediaCount,
- staff.middleware.ensureProfileProjects,
-
- staff.users.show
- );
- app.get('/staff/users/:username/media',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureProfile,
- staff.middleware.ensureProfileMedia,
- staff.middleware.ensureProfileMediaCount,
-
- staff.users.media
- );
- app.put('/staff/users/:username/bless',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureProfile,
-
- staff.users.bless
- );
-
- if (app.get('env') === 'development') {
- app.get('/staff/authorize',
- middleware.ensureAuthenticated,
- staff.users.blessSelf
- );
- }
-
- //
- // projects
-
- app.get('/staff/projects',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureProjectsCount,
-
- staff.middleware.ensureProjects,
- staff.middleware.ensureProjectsUsers,
-
- staff.projects.index
- );
- app.get('/staff/projects/:slug',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- middleware.ensureProject,
- staff.middleware.ensureProject,
- staff.middleware.ensureProjectUser,
- staff.middleware.ensureProjectCollaborators,
-
- staff.projects.show
- );
-
- //
- // media
-
- app.get('/staff/media',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureMediaCount,
-
- staff.middleware.ensureMedia,
- staff.middleware.ensureMediaUsers,
-
- staff.media.index
- );
- app.get('/staff/media/:id',
- middleware.ensureAuthenticated,
- middleware.ensureIsStaff,
-
- staff.middleware.ensureSingleMedia,
- staff.middleware.ensureMediaUser,
-
- staff.media.show
- );
-
- },
-
- paginate: function(req, res){
- var info = res.locals.pagination
- info.query = "sort=" + info.sort + "&limit=" + info.limit
- info.first_page = 0
- info.last_page = Math.max(0, info.max - info.limit)
- info.sortOptions = info.sortOptions
- if (info.offset > 0) {
- info.prev_page = Math.max(0, info.offset - info.limit)
- }
- else {
- info.prev_page = -1
- }
- if (info.count == info.limit && info.offset + info.limit < info.max) {
- info.next_page = info.offset + info.limit
- }
- else {
- info.next_page = -1
- }
- },
-
- index: function(req, res){
- res.render('staff/index')
- },
-
- // /staff/users/
- // /staff/users/:username
- users: {
- index: function(req, res){
- res.locals.pagination.count = res.locals.users.length
- res.locals.pagination.max = res.locals.userCount
- staff.paginate(req, res)
- res.render('staff/users/index')
- },
- show: function(req, res){
- if (res.locals.profile) {
- res.render('staff/users/show', {
- profileJSON: util.escape( JSON.stringify( res.locals.profile ) )
- })
- }
- else {
- res.render('staff/users/show_404')
- }
- },
- media: function(req, res){
- if (res.locals.profile) {
- res.locals.pagination.count = res.locals.media.length
- res.locals.pagination.max = res.locals.profile.mediaCount
- staff.paginate(req, res)
- res.render('staff/users/media')
- }
- else {
- res.render('staff/users/show_404')
- }
- },
- blessSelf: function(req, res){
- req.user.isStaff = true
- req.user.save(function(err, user){
- res.json({ state: user.isStaff })
- })
- },
- bless: function(req, res){
- res.locals.profile.isStaff = req.body.state == "true"
- res.locals.profile.save(function(err, user){
- res.json({ state: user.isStaff })
- })
- },
- },
-
- // /staff/projects/
- // /staff/projects/:name
- projects: {
- index: function(req, res){
- res.locals.pagination.count = res.locals.projects.length
- res.locals.pagination.max = res.locals.projectCount
- staff.paginate(req, res)
- res.render('staff/projects/index')
- },
- show: function(req, res){
- if (res.locals.project) {
- res.render('staff/projects/show', {
- projectJSON: util.escape( JSON.stringify( res.locals.project ) ),
- projectUserJSON: util.escape( JSON.stringify( res.locals.projectUser ) ),
- collaboratorsJSON: util.escape( JSON.stringify( res.locals.collaborators ) ),
- })
- }
- else {
- res.render('staff/projects/show_404')
- }
- },
- },
-
- media: {
- index: function(req, res){
- res.locals.pagination.count = res.locals.media.length
- res.locals.pagination.max = res.locals.mediaCount
- staff.paginate(req, res)
- res.render('staff/media/index')
- },
- show: function(req, res){
- if (res.locals.media) {
- res.render('staff/media/show', {
- mediaJSON: util.escape( JSON.stringify( res.locals.media ) ),
- mediaUserJSON: util.escape( JSON.stringify( res.locals.mediaUser ) ),
- })
- }
- else {
- res.render('staff/media/show_404')
- }
- },
- }
-
-} \ No newline at end of file
diff --git a/server/lib/views/staff/defaults.js b/server/lib/views/staff/defaults.js
new file mode 100644
index 0000000..4d86c41
--- /dev/null
+++ b/server/lib/views/staff/defaults.js
@@ -0,0 +1,6 @@
+module.exports = {
+ user: {
+ _id: "", username: "", displayName: "",
+ created_at: "", updated_at: "", created_ip: "", last_ip: "",
+ },
+}
diff --git a/server/lib/views/staff/fields.js b/server/lib/views/staff/fields.js
new file mode 100644
index 0000000..84c1efa
--- /dev/null
+++ b/server/lib/views/staff/fields.js
@@ -0,0 +1,10 @@
+module.exports = {
+ user: "_id username displayName photo created_at updated_at last_seen created_ip last_ip",
+ project: "_id name slug user_id privacy layout_type created_at updated_at",
+ layout: "_id name slug user_id layout_type is_stock created_at updated_at",
+ blueprint: "_id name slug user_id created_at updated_at",
+ plans: "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price " +
+ "pro_layout_monthly_price pro_layout_yearly_price " +
+ "basic_layout_limit pro_layout_limit stock_project_limit basic_project_limit pro_project_limit",
+ plans_permissions: "basic_editor pro_editor sculpture collaborators no_logo",
+}
diff --git a/server/lib/views/staff/helpers.js b/server/lib/views/staff/helpers.js
new file mode 100644
index 0000000..ff4065a
--- /dev/null
+++ b/server/lib/views/staff/helpers.js
@@ -0,0 +1,59 @@
+
+var util = require('../../util'),
+ _ = require('lodash'),
+ moment = require('moment');
+
+module.exports = {
+ user: function(user){
+ var last_seen = moment( user.last_seen || user.updated_at || user.created_at )
+ user = user.toObject()
+ user.last_seen = last_seen.format("YYYY/MM/DD HH:MM") + " " + last_seen.fromNow()
+ user.last_charged = user.last_charged && moment( user.last_charged ).format("YYYY/MM/DD HH:MM")
+ user.created_ip = util.num2ip( user.created_ip )
+ user.last_ip = util.num2ip( user.last_ip )
+ return user
+ },
+
+ project: function(project){
+ project = project.toObject()
+ project.date = moment( project.updated_at || project.created_at ).format("M/DD/YYYY hh:mm a")
+ project.user = {}
+ return project
+ },
+
+ layout: function(layout){
+ layout = layout.toObject()
+ layout.date = moment( layout.updated_at || layout.created_at ).format("M/DD/YYYY hh:mm a")
+ layout.user = {}
+ return layout
+ },
+
+ blueprint: function(blueprint){
+ blueprint = blueprint.toObject()
+ blueprint.date = moment( blueprint.updated_at || blueprint.created_at ).format("M/DD/YYYY hh:mm a")
+ blueprint.user = {}
+ return blueprint
+ },
+
+ media: function(media){
+ media = media.toObject()
+ media.date = moment( media.updated_at || media.created_at ).format("M/DD/YYYY hh:mm a")
+ media.user = {}
+ media.shortUrl = media.url.replace(/^http.?:\/\//,"")
+ return media
+ },
+
+ plan: function(plan){
+ plan = plan.toObject()
+ plan.date = moment( plan.updated_at || plan.created_at ).format("M/DD/YYYY hh:mm a")
+ plan.user = {}
+ return plan
+ },
+
+ subscription: function(subscription){
+ subscription = subscription.toObject()
+ subscription.date = moment( subscription.updated_at || subscription.created_at ).format("M/DD/YYYY hh:mm a")
+ subscription.user = {}
+ return subscription
+ },
+}
diff --git a/server/lib/views/staff/index.js b/server/lib/views/staff/index.js
new file mode 100644
index 0000000..49a0384
--- /dev/null
+++ b/server/lib/views/staff/index.js
@@ -0,0 +1,511 @@
+/* jshint node: true */
+
+var User = require('../../schemas/User'),
+ Project = require('../../schemas/Project'),
+ Media = require('../../schemas/Media'),
+ Collaborator = require('../../schemas/Collaborator'),
+ Plan = require('../../schemas/Plan'),
+ Subscription = require('../../schemas/Subscription'),
+ Layout = require('../../schemas/Layout'),
+ Blueprint = require('../../schemas/Blueprint'),
+ config = require('../../../../config'),
+ middleware = require('../../middleware'),
+ util = require('../../util'),
+ _ = require('lodash'),
+ moment = require('moment');
+
+
+var staff = module.exports = {
+
+ fields: require('./fields'),
+ defaults: require('./defaults'),
+ middleware: require('./middleware'),
+ helpers: require('./helpers'),
+
+ route: function(app){
+ app.get('/staff',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureRecentUsers,
+ staff.middleware.ensureUsersCount,
+ staff.middleware.ensureProjectsCount,
+ staff.middleware.ensureMediaCount,
+
+ staff.index
+ );
+
+ //
+ // users
+
+ app.get('/staff/users',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureUsersCount,
+ staff.middleware.ensureUsers,
+
+ staff.users.index
+ );
+ app.get('/staff/users/:username',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProfile,
+ staff.middleware.ensureProfileProjectCount,
+ staff.middleware.ensureProfileMediaCount,
+ staff.middleware.ensureProfileProjects,
+
+ staff.users.show
+ );
+ app.get('/staff/users/:username/media',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProfile,
+ staff.middleware.ensureProfileMedia,
+ staff.middleware.ensureProfileMediaCount,
+
+ staff.users.media
+ );
+ app.put('/staff/users/:username/bless',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProfile,
+
+ staff.users.bless
+ );
+ app.put('/staff/users/:username/artist',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProfile,
+
+ staff.users.make_artist
+ );
+
+ if (app.get('env') === 'development') {
+ app.get('/staff/authorize',
+ middleware.ensureAuthenticated,
+ staff.users.blessSelf
+ );
+ }
+
+ //
+ // projects
+
+ app.get('/staff/projects',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureProjectsCount,
+
+ staff.middleware.ensureProjects,
+ staff.middleware.ensureProjectsUsers,
+
+ staff.projects.index
+ );
+ app.get('/staff/projects/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureProject,
+ staff.middleware.ensureProject,
+ staff.middleware.ensureProjectUser,
+ staff.middleware.ensureProjectCollaborators,
+
+ staff.projects.show
+ );
+ app.put('/staff/projects/:slug/feature',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureProject,
+ staff.middleware.ensureProject,
+
+ staff.projects.feature
+ );
+
+ //
+ // layouts
+
+ app.get('/staff/layouts',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureLayoutsCount,
+
+ staff.middleware.ensureLayouts,
+ staff.middleware.ensureLayoutsUsers,
+
+ staff.layouts.index
+ );
+ app.get('/staff/layouts/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureLayout,
+ staff.middleware.ensureLayout,
+ staff.middleware.ensureLayoutUser,
+
+ staff.layouts.show
+ );
+ app.put('/staff/layouts/:slug/stock',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureLayout,
+ staff.middleware.ensureLayout,
+
+ staff.layouts.make_stock
+ );
+
+ //
+ // blueprints
+
+ app.get('/staff/blueprints',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureBlueprintsCount,
+
+ staff.middleware.ensureBlueprints,
+ staff.middleware.ensureBlueprintsUsers,
+
+ staff.blueprints.index
+ );
+ app.get('/staff/blueprints/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ middleware.ensureBlueprint,
+ staff.middleware.ensureBlueprint,
+ staff.middleware.ensureBlueprintUser,
+
+ staff.blueprints.show
+ );
+
+ //
+ // media
+
+ app.get('/staff/media',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureMediaCount,
+
+ staff.middleware.ensureMedia,
+ staff.middleware.ensureMediaUsers,
+
+ staff.media.index
+ );
+ app.get('/staff/media/:id',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureSingleMedia,
+ staff.middleware.ensureMediaUser,
+
+ staff.media.show
+ );
+
+ //
+ // plans
+
+ app.get('/staff/plans',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensurePlans,
+
+ staff.plans.index
+ );
+ app.get('/staff/plans/new',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.plans.new
+ );
+ app.post('/staff/plans/new',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.plans.create
+ );
+ app.get('/staff/plans/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensurePlan,
+
+ staff.plans.edit
+ );
+ app.post('/staff/plans/:slug',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensurePlan,
+
+ staff.plans.update
+ );
+
+ //
+ // subscriptions
+ app.get('/staff/subscriptions',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureSubscriptions,
+ staff.middleware.ensureSubscriptionsUsers,
+
+ staff.subscriptions.index
+ );
+ app.get('/staff/subscriptions/:id',
+ middleware.ensureAuthenticated,
+ middleware.ensureIsStaff,
+
+ staff.middleware.ensureSubscription,
+ staff.middleware.ensureSubscriptionUser,
+
+ staff.subscriptions.show
+ );
+ },
+
+ paginate: function(req, res){
+ var info = res.locals.pagination
+ info.query = "sort=" + info.sort + "&limit=" + info.limit
+ info.first_page = 0
+ info.last_page = Math.max(0, info.max - info.limit)
+ info.sortOptions = info.sortOptions
+ if (info.offset > 0) {
+ info.prev_page = Math.max(0, info.offset - info.limit)
+ }
+ else {
+ info.prev_page = -1
+ }
+ if (info.count == info.limit && info.offset + info.limit < info.max) {
+ info.next_page = info.offset + info.limit
+ }
+ else {
+ info.next_page = -1
+ }
+ },
+
+ index: function(req, res){
+ res.render('staff/index')
+ },
+
+ // /staff/users/
+ // /staff/users/:username
+ users: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.users.length
+ res.locals.pagination.max = res.locals.userCount
+ staff.paginate(req, res)
+ res.render('staff/users/index')
+ },
+ show: function(req, res){
+ if (res.locals.profile) {
+ res.render('staff/users/show', {
+ profileJSON: util.escape( JSON.stringify( res.locals.profile ) )
+ })
+ }
+ else {
+ res.render('staff/users/show_404')
+ }
+ },
+ media: function(req, res){
+ if (res.locals.profile) {
+ res.locals.pagination.count = res.locals.media.length
+ res.locals.pagination.max = res.locals.profile.mediaCount
+ staff.paginate(req, res)
+ res.render('staff/users/media')
+ }
+ else {
+ res.render('staff/users/show_404')
+ }
+ },
+ blessSelf: function(req, res){
+ req.user.isStaff = true
+ req.user.save(function(err, user){
+ res.json({ state: user.isStaff })
+ })
+ },
+ bless: function(req, res){
+ res.locals.profile.isStaff = req.body.state == "true"
+ res.locals.profile.save(function(err, user){
+ res.json({ state: user.isStaff })
+ })
+ },
+ make_artist: function(req, res){
+ res.locals.profile.isArtist = req.body.state == "true"
+ res.locals.profile.save(function(err, user){
+ res.json({ state: user.isArtist })
+ })
+ },
+ },
+
+ // /staff/projects/
+ // /staff/projects/:slug
+ projects: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.projects.length
+ res.locals.pagination.max = res.locals.projectCount
+ staff.paginate(req, res)
+ res.render('staff/projects/index')
+ },
+ show: function(req, res){
+ if (res.locals.project) {
+ res.render('staff/projects/show', {
+ projectJSON: util.escape( JSON.stringify( res.locals.project ) ),
+ projectUserJSON: util.escape( JSON.stringify( res.locals.projectUser ) ),
+ collaboratorsJSON: util.escape( JSON.stringify( res.locals.collaborators ) ),
+ })
+ }
+ else {
+ res.render('staff/projects/show_404')
+ }
+ },
+ feature: function(req, res){
+ res.locals.project.featured = req.body.state == "true"
+ res.locals.project.save(function(err, project){
+ res.json({ state: project.featured })
+ })
+ },
+ },
+
+ // /staff/layouts/
+ // /staff/layouts/:slug
+ layouts: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.layouts.length
+ res.locals.pagination.max = res.locals.layoutCount
+ staff.paginate(req, res)
+ res.render('staff/layouts/index')
+ },
+ show: function(req, res){
+ if (res.locals.layout) {
+ res.render('staff/layouts/show', {
+ })
+ }
+ else {
+ res.render('staff/layouts/show_404')
+ }
+ },
+ make_stock: function(req, res){
+ res.locals.layout.is_stock = req.body.state == "true"
+ res.locals.layout.save(function(err, layout){
+ res.json({ state: layout.is_stock })
+ })
+ },
+ },
+
+ // /staff/blueprints/
+ // /staff/blueprints/:slug
+ blueprints: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.blueprints.length
+ res.locals.pagination.max = res.locals.blueprintCount
+ staff.paginate(req, res)
+ res.render('staff/blueprints/index')
+ },
+ show: function(req, res){
+ if (res.locals.blueprint) {
+ res.render('staff/blueprints/show', {
+ })
+ }
+ else {
+ res.render('staff/blueprints/show_404')
+ }
+ },
+ },
+
+ media: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.media.length
+ res.locals.pagination.max = res.locals.mediaCount
+ staff.paginate(req, res)
+ res.render('staff/media/index')
+ },
+ show: function(req, res){
+ if (res.locals.media) {
+ res.render('staff/media/show', {
+ mediaJSON: util.escape( JSON.stringify( res.locals.media ) ),
+ mediaUserJSON: util.escape( JSON.stringify( res.locals.mediaUser ) ),
+ })
+ }
+ else {
+ res.render('staff/media/show_404')
+ }
+ },
+ },
+
+ plans: {
+ index: function(req, res){
+ res.locals.fields = staff.fields.plans.split(" ")
+ res.locals.permissions = staff.fields.plans_permissions.split(" ")
+ res.render('staff/plans/index')
+ },
+ new: function(req, res){
+ res.locals.plan = new Plan ()
+ res.render('staff/plans/new')
+ },
+ edit: function(req, res){
+ res.locals.plan = req.plan
+ res.render('staff/plans/edit')
+ },
+ create: function(req, res){
+ var plan = new Plan ()
+ var fields = staff.fields.plans.split(" ")
+ var permissions = staff.fields.plans_permissions.split(" ")
+
+ var data = util.cleanQuery(req.body)
+ data.name = util.sanitize(data.name)
+ data.slug = util.sanitize(data.slug.toLowerCase())
+
+ data.permissions = {}
+ permissions.forEach(function(field){
+ data.permissions[field] = data["permissions_" + field].length == 2
+ })
+
+ new Plan (data).save(function(err, doc){
+ if (err || ! doc) { return res.json({ error: err }) }
+ middleware.updatePlans()
+ res.redirect("/staff/plans/")
+ })
+ },
+ update: function(req, res){
+ var fields = staff.fields.plans.split(" ")
+ var permissions = staff.fields.plans_permissions.split(" ")
+
+ var data = util.cleanQuery(req.body)
+ data.name = util.sanitize(data.name)
+ data.slug = util.sanitize(data.slug.toLowerCase())
+
+ _.extend(req.plan, data)
+ permissions.forEach(function(field){
+ req.plan.permissions[field] = data["permissions_" + field].length == 2
+ })
+
+ req.plan.save(function(err, doc){
+ if (err || ! doc) { return res.json({ error: err }) }
+ middleware.updatePlans()
+ res.redirect("/staff/plans/")
+ })
+ },
+ },
+
+ subscriptions: {
+ index: function(req, res){
+ res.locals.pagination.count = res.locals.subscriptions.length
+ res.locals.pagination.max = res.locals.subscriptionCount
+ staff.paginate(req, res)
+ res.render('staff/subscriptions/index')
+ },
+ show: function(req, res){
+ res.render('staff/subscriptions/show')
+ },
+ },
+
+}
diff --git a/server/lib/views/staff/middleware.js b/server/lib/views/staff/middleware.js
new file mode 100644
index 0000000..03fda2e
--- /dev/null
+++ b/server/lib/views/staff/middleware.js
@@ -0,0 +1,476 @@
+
+var User = require('../../schemas/User'),
+ Project = require('../../schemas/Project'),
+ Media = require('../../schemas/Media'),
+ Collaborator = require('../../schemas/Collaborator'),
+ Plan = require('../../schemas/Plan'),
+ Subscription = require('../../schemas/Subscription'),
+ Layout = require('../../schemas/Layout'),
+ Blueprint = require('../../schemas/Blueprint'),
+ util = require('../../util'),
+ fields = require('./fields'),
+ helpers = require('./helpers'),
+ defaults = require('./defaults'),
+ _ = require('lodash'),
+ moment = require('moment');
+
+
+var middleware = module.exports = {
+
+ ensureUsers: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var initial = util.sanitize(req.query.initial)
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "last_seen", "username"]
+ switch (req.query.sort) {
+ case 'date':
+ sort = {'created_at': -1}
+ break
+ case 'last_seen':
+ sort = {'last_seen': -1}
+ break
+ case 'username':
+ default:
+ sort = {'username': 1}
+ paginationInfo.sort = "username"
+ break
+ }
+ if (initial) {
+ if (initial == "?") {
+ criteria.username = new RegExp('^[^a-zA-Z]', "i")
+ }
+ else {
+ criteria.username = new RegExp('^' + initial, "i")
+ }
+ }
+ User.find(criteria)
+ .select(fields.user)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, users) {
+ res.locals.users = users.map(helpers.user)
+ if (! res.locals.users.length) {
+ if (initial) {
+ res.locals.opt.error = "No users found starting with <b>" + initial.toUpperCase() + "</b>"
+ }
+ else {
+ res.locals.opt.error = "No users found"
+ }
+ }
+ next()
+ })
+ },
+
+ ensureRecentUsers: function(req, res, next){
+ var dreq = { query: { sort: 'last_seen', limit: 20, offset: 0 } }
+ middleware.ensureUsers(dreq, res, next)
+ },
+
+ ensureProjects: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "name"]
+ switch (req.query.sort) {
+ default:
+ case 'date':
+ sort = {'updated_at': -1}
+ break
+ case 'name':
+ paginationInfo.sort = "name"
+ sort = {'slug': 1}
+ break
+ }
+ Project.find(criteria)
+ .select(fields.project)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, projects) {
+ res.locals.projects = projects.map(helpers.project)
+ next()
+ })
+ },
+
+ ensureLayouts: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "name"]
+ switch (req.query.sort) {
+ default:
+ case 'date':
+ sort = {'updated_at': -1}
+ break
+ case 'name':
+ paginationInfo.sort = "name"
+ sort = {'slug': 1}
+ break
+ }
+ Layout.find(criteria)
+ .select(fields.layout)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, layouts) {
+ res.locals.layouts = layouts.map(helpers.layout)
+ next()
+ })
+ },
+
+ ensureBlueprints: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "name"]
+ switch (req.query.sort) {
+ default:
+ case 'date':
+ sort = {'updated_at': -1}
+ break
+ case 'name':
+ paginationInfo.sort = "name"
+ sort = {'slug': 1}
+ break
+ }
+ Blueprint.find(criteria)
+ .select(fields.blueprint)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, blueprints) {
+ res.locals.blueprints = blueprints.map(helpers.blueprint)
+ next()
+ })
+ },
+
+ ensureMedia: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date"]
+ switch (req.query.sort) {
+ default:
+ case 'date':
+ paginationInfo.sort = "date"
+ sort = {'created_at': -1}
+ break
+ }
+ Media.find(criteria)
+ // .select(fields.media)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, media) {
+ res.locals.media = media.map(helpers.media)
+ next()
+ })
+ },
+
+ ensureSubscriptions: function(req, res, next){
+ var paginationInfo = res.locals.pagination = {}
+ var criteria = req.criteria || {}
+ var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 )
+ var offset = paginationInfo.offset = Number(req.query.offset) || 0
+ var sort
+ paginationInfo.sort = req.query.sort
+ paginationInfo.sortOptions = ["date", "name"]
+ switch (req.query.sort) {
+ case 'created':
+ sort = {'created_at': -1}
+ break
+ default:
+ case 'date':
+ sort = {'updated_at': -1}
+ break
+ }
+ Subscription.find(criteria)
+ .select(fields.project)
+ .sort(sort)
+ .skip(offset)
+ .limit(limit)
+ .exec(function (err, subscriptions) {
+ res.locals.subscriptions = subscriptions.map(helpers.subscription)
+ next()
+ })
+ },
+
+ ensurePlans: function(req, res, next){
+ Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) {
+ res.locals.plans = (plans || []).map(helpers.plan)
+ res.locals.plans.sort(function(a,b){ return a.monthly_price })
+ next()
+ })
+ },
+ ensurePlan: function (req, res, next) {
+ if (req.params.slug) {
+ Plan.findOne({ slug: req.params.slug }, function(err, plan){
+ if (err || ! plan) {
+ console.error(err)
+ res.redirect("/staff/plans/")
+ }
+ else {
+ req.plan = plan
+ next()
+ }
+ })
+ }
+ else {
+ res.redirect("/staff/plans/")
+ }
+ },
+
+ ensureSubscription: function (req, res, next) {
+ if (req.params.id) {
+ Subscription.findOne({ _id: req.params.id }, function(err, subscription){
+ if (err || ! subscription) {
+ console.error(err)
+ res.redirect("/staff/subscriptions/")
+ }
+ else {
+ req.subscription = subscription
+ next()
+ }
+ })
+ }
+ else {
+ res.redirect("/staff/subscriptions/")
+ }
+ },
+
+ ensureRecentProjects: function(req, res, next){
+ var dreq = { params: { sort: 'created_at', limit: 20, offset: 0 } }
+ middleware.ensureProjects(dreq, res, next)
+ },
+
+ ensureProjectsUsers: function(req, res, next){
+ if (! res.locals.projects || ! res.locals.projects.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.projects, next)
+ },
+
+ ensureLayoutsUsers: function(req, res, next){
+ if (! res.locals.layouts || ! res.locals.layouts.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.layouts, next)
+ },
+
+ ensureBlueprintsUsers: function(req, res, next){
+ if (! res.locals.blueprints || ! res.locals.blueprints.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.blueprints, next)
+ },
+
+ ensureSubscriptionsUsers: function(req, res, next){
+ if (! res.locals.subscriptions || ! res.locals.subscriptions.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.subscriptions, next)
+ },
+
+ ensureMediaUsers: function(req, res, next){
+ if (! res.locals.media || ! res.locals.media.length) { return next() }
+ middleware.ensureObjectsUsers(res.locals.media, next)
+ },
+
+ ensureSubscriptionUser: function(req, res, next){
+ if (! res.locals.subscription) { return next() }
+ middleware.ensureObjectsUsers([ res.locals.subscription ], function(){
+ next()
+ })
+ },
+
+ ensureMediaUser: function(req, res, next){
+ if (! res.locals.media) { return next() }
+ middleware.ensureObjectsUsers([ res.locals.media ], function(){
+ res.locals.mediaUser = res.locals.media.User
+ next()
+ })
+ },
+
+ ensureObjectsUsers: function(objects, next){
+ if (! objects) { return next () }
+ var dedupe = {}, user_ids
+ objects.forEach(function(obj){
+ dedupe[ obj.user_id ] = dedupe[ obj.user_id ] || []
+ dedupe[ obj.user_id ].push(obj)
+ })
+ user_ids = _.keys(dedupe)
+ User.find({ _id: { $in: user_ids } })
+ .select(fields.user)
+ .exec(function (err, users) {
+ if (! users) { return next () }
+ users.forEach(function(user){
+ dedupe[user._id].forEach(function(obj){
+ obj.user = user
+ })
+ })
+ next()
+ })
+ },
+
+ ensureProfile: function(req, res, next){
+ var username = req.params.username
+ if (username) {
+ User.findOne({ username: username }, function (err, user) {
+ if (user) {
+ res.locals.profile = req.method == "GET" ? helpers.user(user) : user
+ }
+ else {
+ res.locals.profile = null
+ }
+ next()
+ })
+ }
+ else {
+ res.locals.profile = null
+ next()
+ }
+ },
+
+ ensureSingleMedia: function(req, res, next){
+ var id = req.params.id
+ if (id) {
+ Media.findOne({ _id: id }, function (err, media) {
+ if (media) {
+ res.locals.media = req.method == "GET" ? helpers.media(media) : media
+ }
+ else {
+ res.locals.media = null
+ }
+ next()
+ })
+ }
+ else {
+ res.locals.media = null
+ next()
+ }
+ },
+
+ ensureUsersCount: function(req, res, next){
+ User.count({}, function(err, count){
+ res.locals.userCount = count || 0
+ next()
+ })
+ },
+
+ ensureProjectsCount: function(req, res, next){
+ Project.count({}, function(err, count){
+ res.locals.projectCount = count || 0
+ next()
+ })
+ },
+
+ ensureLayoutsCount: function(req, res, next){
+ Layout.count({}, function(err, count){
+ res.locals.layoutCount = count || 0
+ next()
+ })
+ },
+
+ ensureBlueprintsCount: function(req, res, next){
+ Blueprint.count({}, function(err, count){
+ res.locals.blueprintCount = count || 0
+ next()
+ })
+ },
+
+ ensureMediaCount: function(req, res, next){
+ Media.count({}, function(err, count){
+ res.locals.mediaCount = count || 0
+ next()
+ })
+ },
+
+ ensureProfileProjectCount: function(req, res, next){
+ if (! res.locals.profile) { return next() }
+ Project.count({ user_id: res.locals.profile._id}, function(err, count){
+ res.locals.profile.projectCount = count || 0
+ next()
+ })
+ },
+
+ ensureProfileMediaCount: function(req, res, next){
+ if (! res.locals.profile) { return next() }
+ Media.count({ user_id: res.locals.profile._id}, function(err, count){
+ res.locals.profile.mediaCount = count || 0
+ next()
+ })
+ },
+
+ ensureProfileProjects: function(req, res, next){
+ if (! res.locals.profile) { return next() }
+ Project.find({ user_id: res.locals.profile._id }, fields.project, function(err, projects){
+ res.locals.projects = projects.map(helpers.project)
+ next()
+ })
+ },
+
+ ensureProfileMedia: function(req, res, next){
+ if (! res.locals.profile) { return next() }
+ req.criteria = { user_id: res.locals.profile._id }
+ middleware.ensureMedia(req, res, next)
+ },
+
+ ensureProject: function(req, res, next){
+ res.locals.project = req.project
+ next()
+ },
+
+ ensureProjectUser: function(req, res, next){
+ if (! res.locals.project) { return next() }
+ User.findOne({ _id: res.locals.project.user_id }, fields.user, function(err, user){
+ res.locals.projectUser = helpers.user(user) || defaults.user
+ next()
+ })
+ },
+
+ ensureProjectCollaborators: function(req, res, next){
+ if (! res.locals.project) {
+ res.locals.collaborators = []
+ return next()
+ }
+ Collaborator.find({ project_id: res.locals.project._id}, function(err, collaborators){
+ res.locals.collaborators = collaborators || []
+ next()
+ })
+ },
+
+ ensureLayout: function(req, res, next){
+ res.locals.layout = req.layout
+ next()
+ },
+ ensureLayoutUser: function(req, res, next){
+ if (! res.locals.layout) { return next() }
+ User.findOne({ _id: res.locals.layout.user_id }, fields.user, function(err, user){
+ res.locals.layoutUser = helpers.user(user) || defaults.user
+ next()
+ })
+ },
+
+ ensureBlueprint: function(req, res, next){
+ res.locals.blueprint = req.blueprint
+ next()
+ },
+ ensureBlueprintUser: function(req, res, next){
+ if (! res.locals.blueprint) { return next() }
+ User.findOne({ _id: res.locals.blueprint.user_id }, fields.user, function(err, user){
+ res.locals.blueprintUser = helpers.user(user) || defaults.user
+ next()
+ })
+ },
+
+
+} \ No newline at end of file
diff --git a/server/lib/webhook/index.js b/server/lib/webhook/index.js
new file mode 100644
index 0000000..a5f23ac
--- /dev/null
+++ b/server/lib/webhook/index.js
@@ -0,0 +1,44 @@
+var config = require('../../../config.json'),
+ http = require('http'),
+ express = require('express'),
+ bodyParser = require('body-parser'),
+ mongoose = require('mongoose');
+
+var http = require('http'),
+ express = require('express'),
+ bodyParser = require('body-parser'),
+ multer = require('multer'),
+ MongoStore = require('connect-mongo')(express),
+ passport = require('passport'),
+ path = require('path'),
+ mongoose = require('mongoose');
+
+var webhook = require('./webhook');
+
+var app = express()
+var server
+var DATABASE_URI = process.env.MONGOLAB_URI || ('mongodb://' + config.databaseHost + '/vvalls')
+
+var site = {}
+
+site.init = function(){
+ mongoose.connect(DATABASE_URI, {}, site.ready);
+}
+
+site.ready = function(){
+ app.set('port', config.webhookPort);
+ // app.use(bodyParser());
+ app.use(express.query());
+ app.set('env', config.env.production ? "production" : "development")
+ app.get('env') === 'development' && app.use(express.errorHandler());
+
+ server = http.createServer(app)
+ server.listen(app.get('port'), function () {
+ console.log('Webhook server listening on port ' + app.get('port'));
+ });
+
+ app.get('/', function(req,res){ res.send('hello@vvalls.com') })
+ webhook.route(app)
+}
+
+site.init()
diff --git a/server/lib/webhook/recurly-config.js b/server/lib/webhook/recurly-config.js
new file mode 100644
index 0000000..3d7e1c5
--- /dev/null
+++ b/server/lib/webhook/recurly-config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ API_KEY: process.env['VVALLS_RECURLY_SECRET'],
+ SUBDOMAIN: 'vvalls',
+ ENVIRONMENT: 'sandbox',
+ DEBUG: true,
+};
diff --git a/server/lib/webhook/webhook.js b/server/lib/webhook/webhook.js
new file mode 100644
index 0000000..896d836
--- /dev/null
+++ b/server/lib/webhook/webhook.js
@@ -0,0 +1,178 @@
+// // where should this live?
+
+/*
+app.use(express.basicAuth(function(user, pass, callback) {
+ var result = (user === 'testUser' && pass === 'testPass');
+ callback(null, result);
+}));
+*/
+
+
+/* jshint node: true */
+
+var User = require('../schemas/User'),
+ Subscription = require('../schemas/Subscription'),
+ config = require('../../../config'),
+ middleware = require('../middleware'),
+ util = require('../util'),
+ _ = require('lodash'),
+ moment = require('moment'),
+ xml2js = require('xml2js'),
+ Recurly = require('node-recurly'),
+ recurly = new Recurly(require('./recurly-config'));
+
+var xml_bodyparser = require('express-xml-bodyparser');
+
+var parser = new xml2js.Parser();
+
+var subscribe = module.exports = {
+ plan_levels: {
+ free: 0,
+ basic: 1,
+ pro: 2,
+ custom: 3,
+ artist: 4,
+ },
+
+ callbacks: {
+/*
+ // accounts
+ new_account_notification: function(data, user){
+ // fires on successful signup
+ },
+ canceled_account_notification: function(data, user){
+ },
+ billing_info_updated_notification: function(data, user){
+ },
+ reactivated_account_notification: function(data, user){
+ },
+
+ // invoices
+ new_invoice_notification: function(data, user){
+ },
+ closed_invoice_notification: function(data, user){
+ },
+ past_due_invoice_notification: function(data, user){
+ },
+*/
+
+ // subscriptions
+ new_subscription_notification: function(data, user){
+ var account = data.account[0].account_code[0]
+ var subscrip = data.subscription[0]
+ var uuid = subscrip.uuid[0]
+ Subscription.findOne({ "uuid": uuid }, function(err, old_subscriber){
+ // if (err) return;
+
+ var plan, plan_type, plan_code
+ var plan_code = subscrip.plan[0].plan_code[0]
+
+ if (plan_code.indexOf("-") !== -1) {
+ plan = plan_code.split("-")
+ plan_type = plan[0]
+ plan_period = plan[1]
+ }
+ else {
+ plan_type = "custom"
+ plan_period = "monthly"
+ }
+
+ user.plan_code = plan_code
+ user.plan_type = plan_type
+ user.plan_level = subscribe.plan_levels[plan_type]
+
+ var subscriber = old_subscriber || new Subscription ()
+ subscriber.uuid = uuid
+ subscriber.user_id = user._id
+ subscriber.plan_code = plan_code
+ subscriber.plan_type = plan_type
+ subscriber.plan_period = plan_period
+ subscriber.plan_level = subscribe.plan_levels[plan_type]
+ subscriber.add_ons = []
+ var add_ons = subscrip.subscription_add_ons[0].subscription_add_on
+ if (add_ons) {
+ add_ons.forEach(function(add_on){
+ switch (add_on.add_on_code[0]) {
+ case 'extra-basic-layout':
+ subscriber.basic_layouts = parseInt(add_on.quantity[0]._, 10) || 0
+ break
+ case 'extra-pro-layout':
+ subscriber.pro_layouts = parseInt(add_on.quantity[0]._, 10) || 0
+ break
+ }
+ })
+ }
+ subscriber.save(function(err, data){
+ if (err) return;
+ user.save(function(err){
+ // saved!
+ })
+ })
+ })
+ },
+
+/*
+ updated_subscription_notification: function(data, user){
+ },
+ canceled_subscription_notification: function(data, user){
+ },
+ expired_subscription_notification: function(data, user){
+ },
+ renewed_subscription_notification: function(data, user){
+ },
+*/
+ // payments
+ successful_payment_notification: function(data, user){
+ var account = data.account[0]
+ user.last_charged = new Date(data.transaction[0].date[0]._)
+ user.save(function(){
+ })
+ },
+/*
+ failed_payment_notification: function(data, user){
+ },
+ successful_refund_notification: function(data, user){
+ },
+ void_payment_notification: function(data, user){
+ },
+*/
+ },
+
+ execute: function(action, data){
+ User.findOne({ _id: data.account[0].account_code[0] }, function(err, user){
+ if (err) { return }
+ subscribe.callbacks[action](data, user)
+ })
+ },
+
+ // then calls to get appropriate info from the recurly api
+ handle: function(req, res){
+ console.log(req.body)
+ // parser.parseString(req.body, function (err, result) {
+ var result = req.body
+ for (var action in result) {
+ if (subscribe.callbacks[action]) {
+ subscribe.execute(action, result[action]);
+ }
+ }
+ return res.status(200).end()
+ },
+
+ list: function(req, res){
+ recurly.subscriptions.listByAccount(req.params.id, function(data){
+ if (data.data != 404) {
+ res.json(data)
+ return
+ }
+ else {
+ res.json(data)
+ return
+ }
+ })
+ },
+
+ route: function(app){
+ app.post('/subscribe/webhook', xml_bodyparser(), subscribe.handle);
+ app.get('/subscribe/list/:id', subscribe.list);
+ },
+}
diff --git a/server/repl.js b/server/repl.js
new file mode 100644
index 0000000..353d8c5
--- /dev/null
+++ b/server/repl.js
@@ -0,0 +1,19 @@
+var DB_HOST = 'localhost'
+var mongoose = require('mongoose')
+mongoose.connect('mongodb://' + DB_HOST + '/vvalls', {}, function(){
+ console.log("vvalls: connected to", DB_HOST)
+ var repl = require("repl").start({});
+ [ "./lib/schemas/User",
+ "./lib/schemas/Collaborator",
+ "./lib/schemas/Documentation",
+ "./lib/schemas/Layout",
+ "./lib/schemas/Media",
+ "./lib/schemas/Project",
+ "./lib/schemas/Plan",
+ "./lib/schemas/Subscription",
+ ].forEach(function(modName){
+ // console.log(name, modName)
+ var namez = modName.split("/"), name = namez[namez.length-1];
+ repl.context[name] = require(modName);
+ });
+});
diff --git a/views/about/_blank.ejs b/views/about/_blank.ejs
new file mode 100644
index 0000000..732ea3f
--- /dev/null
+++ b/views/about/_blank.ejs
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+ <title>VValls</title>
+ [[ include ../partials/meta ]]
+</head>
+<body class="loading">
+ <div class="rapper page home">
+ [[ include ../partials/header ]]
+
+ <h1 class="leader">Hallo</h1>
+ <!-- put stuff here -->
+
+
+
+ [[ include ../partials/confirm-modal ]]
+ [[ include ../projects/layouts-modal ]]
+ [[ include ../partials/sign-in ]]
+ [[ include ../partials/footer ]]
+
+ </div>
+</body>
+[[ include ../partials/scripts ]]
+</html>
diff --git a/views/about/_old_plans.ejs b/views/about/_old_plans.ejs
new file mode 100644
index 0000000..e4b07be
--- /dev/null
+++ b/views/about/_old_plans.ejs
@@ -0,0 +1,63 @@
+ <div class="about_plan planbox free_plan_info">
+ <h3>[[- plans.free.name ]]</h3>
+ <ul>
+ <li> [[- plans.free.stock_project_limit ]] exhibition with pre-designed template floor plan
+ </ul>
+ </div>
+
+ <div class="about_plan planbox">
+ <h3>[[- plans.basic.name ]]</h3>
+ <ul>
+ <li> $[[- plans.basic.monthly_price ]]/mo or $[[- plans.basic.yearly_price ]]/year
+ <li> Comes with [[- plans.basic.basic_layout_limit ]] basic floor plan and [[- plans.basic.basic_project_limit ]] exhibitions
+ <li> Each new basic floor plan costs $[[- plans.basic.basic_layout_monthly_price ]]/mo
+ or $[[- plans.basic.basic_layout_yearly_price ]]/year, minimum 3 months
+ <li> Each new floor plan can have up to [[- plans.basic.basic_project_limit ]] exhibitions
+ <li> VValls logo appears when embedding an exhibition on a web page
+ <li>
+ [[ if (! logged_in) { ]]
+ <button data-role="show-signup-modal">Sign Up</button>
+ [[ } else if (! user.plan_level) { ]]
+ <a href="https://vvalls.recurly.com/subscribe/basic-monthly/[[- user._id ]]/[[- user.username ]]"><button>Buy Now</button></a>
+ [[ } else if (user.plan_level == plans.basic.level) { ]]
+ Current Level
+ [[ } ]]
+ </ul>
+ </div>
+
+ <div class="about_plan planbox">
+ <h3>[[- plans.pro.name ]]</h3>
+ <ul>
+ <li> $[[- plans.pro.monthly_price ]]/mo or $[[- plans.pro.yearly_price ]]/year
+ <li> Comes with [[- plans.pro.pro_layout_limit ]] pro floor plan and [[- plans.pro.pro_project_limit ]] exhibitions
+ <li> Each new pro floor plan costs $[[- plans.pro.pro_layout_monthly_price ]]/mo
+ or $[[- plans.pro.pro_layout_yearly_price ]]/year, minimum 3 months
+ <li> Each new pro floor plan can have up to [[- plans.pro.pro_project_limit ]] exhibitions
+ <li> Includes planning for 3D objects in the room
+ <li> No VValls logo on embed
+ <li>
+ [[ if (! logged_in) { ]]
+ <button data-role="show-signup-modal">Sign Up</button>
+ [[ } else if (! user.plan_level) { ]]
+ <a href="https://vvalls.recurly.com/subscribe/pro-monthly/[[- user._id ]]/[[- user.username ]]"><button>Buy Now</button></a>
+ [[ } else if (user.plan_level == plans.pro.level) { ]]
+ Current Level
+ [[ } else if (user.plan_level < plans.pro.level) { ]]
+ <a href="/profile/billing"><button>Upgrade Now</button></a>
+ [[ } ]]
+ </ul>
+ </div>
+
+ <div class="about_custom planbox miscbox">
+ <ul>
+ <li> Buying any extra floor plan unlocks collaboration.<br>Invite an artist or curator to work on the exhibition with you.
+ <li> Basic Floor plan: Rectangle-based design of any dimension.
+ <li> Pro Floor plan: Trace an arbitrary floor plan from image.
+ </ul>
+ </div>
+
+ <div class="about_custom custombox planbox">
+ <h3>Want Something Custom?</h3>
+ <li> We offer customized white-label options for business and educational uses.
+ <li> <a href="mailto:hello@vvalls.com">Contact us</a> for more information.
+ </div>
diff --git a/views/about/_plans.ejs b/views/about/_plans.ejs
new file mode 100644
index 0000000..95b8d2f
--- /dev/null
+++ b/views/about/_plans.ejs
@@ -0,0 +1,121 @@
+<ul id="plans">
+ <li class="most-popular">
+ <div class="top">
+ <h2>[[- plans.pro.name ]]</h2>
+ <h3><span class="dollar">$</span><span class="price large">[[- plans.pro.monthly_price ]]</span> <span class="month large">/ mo </span></h3>
+ <h4>Ideal for large galleries<br>and small businesses.</h4>
+ </div>
+ <ul>
+ <li>
+ [[- plans.pro.pro_layout_limit ]] Pro Floor Plans and [[- plans.pro.pro_project_limit ]] Exhibitions
+ </li>
+ <li>
+ Trace a Floor Plan from a Drawing
+ </li>
+ <li>
+ Image Hosting For Artworks
+ </li>
+ <li>
+ Planning for 3D Objects
+ </li>
+ <li>
+ Everything the Medium Plan Contains
+ </li>
+ <li>
+ No Branding!
+ </li>
+ </ul>
+ <div class="signup">
+ [[ if (! logged_in) { ]]
+ <a class="button" href="#" data-role="show-signup-modal">Sign Up for [[- plans.pro.name ]]</a>
+ [[ } else if (! user.plan_level || user.plan_level < plans.pro.level) { ]]
+ <a class="button" href="https://vvalls.recurly.com/subscribe/pro-monthly/[[- user._id ]]/[[- user.username ]]">Sign Up for [[- plans.pro.name ]]</a>
+ [[ } else if (user.plan_level == plans.pro.level) { ]]
+ <div class="current">Current Level</div>
+ [[ } ]]
+ </div>
+ </li>
+ <li>
+ <div class="top">
+ <h2>[[- plans.basic.name ]]</h2>
+ <h3><span class="dollar">$</span><span class="price medium">[[- plans.basic.monthly_price ]]</span> <span class="month medium">/ mo </span></h3>
+ <h4>Great for small galleries<br>and art projects.</h4>
+ </div>
+ <ul>
+ <li>
+ [[- plans.basic.basic_layout_limit ]] Basic Floor Plan and [[- plans.basic.basic_project_limit ]] Exhibitions
+ </li>
+ <li>
+ Add More Basic Floor Plans for $[[- plans.basic.basic_layout_monthly_price ]]/mo
+ </li>
+ <li>
+ Invite Artists to Collaborate
+ </li>
+ <li>
+ Prepay a Year and Get Two Months Free
+ </li>
+ <li>
+ Everything the Small Plan Contains
+ </li>
+ <li>
+ VValls Branding
+ </li>
+ </ul>
+ <div class="signup">
+ [[ if (! logged_in) { ]]
+ <a class="button" href="#" data-role="show-signup-modal">Sign Up for [[- plans.basic.name ]]</a>
+ [[ } else if (! user.plan_level || user.plan_level < plans.basic.level) { ]]
+ <a class="button" href="https://vvalls.recurly.com/subscribe/basic-monthly/[[- user._id ]]/[[- user.username ]]">Sign Up for [[- plans.basic.name ]]</a>
+ [[ } else if (user.plan_level == plans.basic.level) { ]]
+ <div class="current">Current Level</div>
+ [[ } else { ]]
+ <div class="current">&nbsp;</div>
+ [[ } ]]
+ </div>
+ </li>
+ <li>
+ <div class="top">
+ <h2>[[- plans.free.name ]]</h2>
+ <h3><span class="dollar">$</span><span class="price small">0</span> <span class="month small">/ mo </span></h3>
+ <h4>Free forever.</h4>
+ </div>
+ <ul>
+ <li>
+ [[- plans.free.stock_project_limit ]] Basic Exhibition
+ </li>
+ <li>
+ Use Any of our Built-In Floor Plans
+ </li>
+ <li>
+ Embed Images and Videos in your Room
+ </li>
+ <li>
+ Custom Color and Wallpaper
+ </li>
+ <li>
+ Embed Room on Your Website
+ </li>
+ <li>
+ VValls Branding
+ </li>
+ </ul>
+
+ <div class="signup">
+ [[ if (! logged_in) { ]]
+ <a class="button" href="#" data-role="show-signup-modal">Sign Up for Small</a>
+ [[ } else if (! user.plan_level || user.plan_level == plans.free.level) { ]]
+ <div class="current">Current Level</div>
+ [[ } else { ]]
+ <div class="current">&nbsp;</div>
+ [[ } ]]
+ </div>
+ </li>
+</ul>
+
+<br>
+<div class="about_custom custombox planbox">
+ <h3>Want Something Custom?</h3>
+ <li> We offer customized white-label options for business and educational uses.
+ <br>
+ <a href="mailto:hello@vvalls.com">Contact us</a> for more information.
+</div>
diff --git a/views/about/about.ejs b/views/about/about.ejs
new file mode 100644
index 0000000..6d5f011
--- /dev/null
+++ b/views/about/about.ejs
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+<head>
+ <title>About VValls</title>
+ [[ include ../partials/meta ]]
+</head>
+<body class="loading">
+ <div class="rapper page">
+ [[ include ../partials/header ]]
+
+ <h1 class="leader">About VValls</h1>
+
+ <div class="projectList about aboutintro">
+ <div class="inner">
+ VValls is a platform for creating and sharing immersive web based 3D exhibitions. With VValls users can draw floor plans, and then apply media to the surfaces of the virtual space. VValls is the ideal solution for anyone creating immersive presentations of content, curators looking to plan shows, and artists looking to visualize their work in 3D space. VValls is completely HTML5 based – mobile and desktop compatible.
+ <br><br>
+ Contact us with inquiries at <a href="mailto:hello@vvalls.com">hello@vvalls.com</a>.<br>
+ We are based in New York City.
+ </div>
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://vvalls.s3.amazonaws.com/static/larisa.jpg)">
+ </span>
+ <span>
+ <h3>Dot Dash 3</h3>
+ <words>VValls was conceived and prototyped by Larisa Leventon, Ph.D., MBA, founder of Dot Dash 3 and an M.I.T. + Brown University-trained visualization algorithm specialist.</words>
+ </span>
+ </div>
+ </div>
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://vvalls.s3.amazonaws.com/static/okf.jpg)">
+ </span>
+ <span>
+ <h3>OKFocus</h3>
+ <words>VValls was developed and designed by OKFocus, a forward thinking NYC based creative agency. The technology was spearheaded by Jules LaPlace, CTO, and the design by Ryder Ripps, ECD.</words>
+ </span>
+ </div>
+ </div>
+ </div>
+
+ [[ include ../partials/confirm-modal ]]
+ [[ include ../projects/layouts-modal ]]
+ [[ include ../partials/sign-in ]]
+ [[ include ../partials/footer ]]
+
+ </div>
+</body>
+[[ include ../partials/scripts ]]
+</html>
diff --git a/views/about/brochure.ejs b/views/about/brochure.ejs
new file mode 100644
index 0000000..e34d3d3
--- /dev/null
+++ b/views/about/brochure.ejs
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+<head>
+ <title>VValls Subscriptions</title>
+ [[ include ../partials/meta ]]
+</head>
+<body class="loading">
+ <div class="rapper page">
+ [[ include ../partials/header ]]
+
+ <h1 class="leader">Subscriptions</h1>
+
+ <div class="projectList about aboutintro">
+ [[ include _plans ]]
+ </div>
+
+ [[ include ../partials/confirm-modal ]]
+ [[ include ../projects/layouts-modal ]]
+ [[ include ../partials/sign-in ]]
+ [[ include ../partials/footer ]]
+
+ </div>
+</body>
+[[ include ../partials/scripts ]]
+</html>
diff --git a/views/about/howto.ejs b/views/about/howto.ejs
new file mode 100644
index 0000000..914c3b3
--- /dev/null
+++ b/views/about/howto.ejs
@@ -0,0 +1,128 @@
+<!doctype html>
+<html>
+<head>
+ <title>How to Use VValls</title>
+ [[ include ../partials/meta ]]
+</head>
+<body class="loading">
+ <div class="rapper page">
+ [[ include ../partials/header ]]
+
+ <div class="hero" style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls/construction.jpg);">
+ <div class="holder">
+ </div>
+ </div>
+ <h1>How To Use VValls</h1>
+
+ <div class="projectList about howto">
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls/newproject.jpg)">
+ </span>
+ <span>
+ <h3>1. Define Your Space.</h3>
+ <words>Choose from one of our existing floor plan templates or create your own.</words>
+ </span>
+ </div>
+ </div>
+
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls/addmedia.gif)">
+ </span>
+ <span>
+ <h3>2. Add Your Media Files.</h3>
+ <words>Upload media files or choose media from our pre-loaded image/video stream. Position media on the walls.</words>
+ </span>
+ </div>
+ </div>
+
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls/wallpaper3.gif)">
+ </span>
+ <span>
+ <h3>3. Customize.</h3>
+ <words>Use color or wallpaper features to customize the look of your space.</words>
+ </span>
+ </div>
+ </div>
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls/colab.png)">
+ </span>
+ <span>
+ <h3>4. Collaborate.</h3>
+ <words>You can invite others to collaborate on your project.</words>
+ </span>
+ </div>
+ </div>
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls/thumbsup.gif)">
+ </span>
+ <span>
+ <h3>5. Publish + Share.</h3>
+ <words>Share a link to your creation on social media or embed your 3D space directly into your own web page. When on the go, make sure to show off your project on your phone.</words>
+ </span>
+ </div>
+ </div>
+
+ <h1 style="text-align:center; background: white; border-bottom: 1px solid black; margin: 60px 0 40px;">Keyboard Shortcuts</h1>
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://okfocus.s3.amazonaws.com/random/keyboard.gif); background-position: 15%;"></span>
+ <span style="padding: 0 50px;margin-bottom: 60px;">
+ <words>
+ <h3>Getting around VValls is easier with the keyboard.</h3>
+
+ If you play video games, you should be familiar with using WASD to move -- left hand on the keyboard, right hand on the mouse.
+ We have added a few keys for pivoting and looking up and down.
+ </words>
+ </span>
+ <br clear="both">
+
+ <table border="0" class="keyboard first-keyboard">
+ <tr><td>W</td><td>Move forward</td></tr>
+ <tr><td>A</td><td>Strafe left</td></tr>
+ <tr><td>S</td><td>Move backward</td></tr>
+ <tr><td>D</td><td>Strafe right</td></tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>Q</td><td>Turn left</td></tr>
+ <tr><td>E</td><td>Turn right</td></tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>R</td><td>Look up</td></tr>
+ <tr><td>F</td><td>Look down</td></tr>
+ </table>
+ <table border="0" class="keyboard">
+ <tr><td>Cmd-Z</td><td>Undo</td></tr>
+ <tr><td>Shift-Cmd-Z</td><td>Redo</td></tr>
+ <tr><td>Cmd-\</td><td>Noclip mode</td></tr>
+ <tr><td>Esc</td><td>Cancel</td></tr>
+ <tr><td>Backspace</td><td>Delete currently selected media</td></tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>Mousewheel</td><td>Move forward/back</td></tr>
+ <tr><td>Shift-Mousewheel</td><td>Turn left/right</td></tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>Spacebar</td><td>Jump</td></tr>
+ </table>
+ </span>
+ </div>
+ </div>
+</div>
+
+
+ [[ include ../partials/confirm-modal ]]
+ [[ include ../projects/layouts-modal ]]
+ [[ include ../partials/sign-in ]]
+ [[ include ../partials/footer ]]
+
+ </div>
+</body>
+[[ include ../partials/scripts ]]
+</html>
diff --git a/views/blueprint.ejs b/views/blueprint.ejs
new file mode 100644
index 0000000..13e8182
--- /dev/null
+++ b/views/blueprint.ejs
@@ -0,0 +1,30 @@
+<!doctype html>
+<html>
+<head>
+ <title>VValls</title>
+ [[ include partials/meta ]]
+</head>
+<body class="editing loading">
+
+ <div id="scene"></div>
+
+ <div class="rapper">
+ [[ include partials/header ]]
+
+ <div id="builderView">
+ [[ include controls/blueprint/info ]]
+ [[ include controls/blueprint/toolbar ]]
+ [[ include controls/blueprint/settings ]]
+ [[ include controls/blueprint/editor ]]
+ [[ include controls/blueprint/scaler ]]
+ [[ include controls/blueprint/notice ]]
+ </div>
+ </div>
+
+ [[ include partials/confirm-modal ]]
+ [[ include projects/layouts-modal ]]
+ [[ include partials/sign-in ]]
+
+</body>
+[[ include partials/scripts ]]
+</html>
diff --git a/views/builder.ejs b/views/builder.ejs
index afb8c66..6a31e22 100644
--- a/views/builder.ejs
+++ b/views/builder.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="editing loading">
@@ -17,22 +17,6 @@
[[ include controls/builder/settings ]]
</div>
- <!--
- <div id="minimap" class="vvbox">
- <span class="el"></span>
- </div>
-
- <select id="palette">
- <option>colors</option>
- <option>redblue</option>
- <option>gray</option>
- <option selected>bone</option>
- <option>alpha</option>
- <option>white</option>
- <option>black</option>
- </select>
- -->
-
<div id="hud">
<div id="map" style="display: block">
</div>
diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs
new file mode 100644
index 0000000..0dbac8e
--- /dev/null
+++ b/views/controls/blueprint/editor.ejs
@@ -0,0 +1,36 @@
+<style type="text/css">
+#perspective,
+#perspective .mx-scene {
+ position: absolute;
+ left:0%;
+ top:0px;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+}
+#orthographic {
+ position: absolute;
+ left:50%;
+ top:0px
+}
+.blueprintInfo {
+ bottom: 14px;
+ left: 10px;
+ width: 270px;
+ font-size: 13px;
+ font-weight: 300;
+ padding: 10px;
+}
+.blueprintInfo .setting {
+ margin-bottom: 20px;
+}
+.blueprintInfo .setting.number input[type=text] {
+ width: 100px;
+ font-size: 16px;
+}
+</style>
+
+<div id="blueprintView">
+ <div id="perspective"></div>
+ <div id="orthographic"></div>
+</div>
+
diff --git a/views/controls/blueprint/info.ejs b/views/controls/blueprint/info.ejs
new file mode 100644
index 0000000..a86481b
--- /dev/null
+++ b/views/controls/blueprint/info.ejs
@@ -0,0 +1,30 @@
+<div class="vvbox settings info" id="blueprintInfo">
+ <h4>Blueprint Editor</h4>
+
+ <div class="setting number twoline">
+ <label for="room-height">ceiling height</label>
+ <input type="text" class="units" name="height" id="room-height">
+ </div>
+
+ <div class="setting number twoline">
+ <label for="viewHeight">camera height</label>
+ <input type="text" class="units" name="viewHeight" id="viewHeight">
+ </div>
+
+ <div class="setting number twoline">
+ <label for="builder-units">units</label>
+ <select id="builder-units" name="units">
+ <option value="px">pixels</option>
+ <option value="ft">feet</option>
+ <option value="m">meters</option>
+ </select>
+ </div>
+
+ <div class="setting number scale">
+ <label>scale</label>
+ <span id="blueprintScaleDisplay"></span>
+ px/<span class="units"></span>
+ <span class="openScaler">[edit scale]</span>
+ </div>
+
+</div>
diff --git a/views/controls/blueprint/notice.ejs b/views/controls/blueprint/notice.ejs
new file mode 100644
index 0000000..bf1a310
--- /dev/null
+++ b/views/controls/blueprint/notice.ejs
@@ -0,0 +1,4 @@
+<div class="vvbox settings" id="blueprintNotice">
+ <div class="notice"></div>
+ <span class="next">Next</span>
+</div>
diff --git a/views/controls/blueprint/scaler.ejs b/views/controls/blueprint/scaler.ejs
new file mode 100644
index 0000000..82fd2b2
--- /dev/null
+++ b/views/controls/blueprint/scaler.ejs
@@ -0,0 +1,48 @@
+<div class="mediaDrawer fixed animate active blueprintScaler">
+ <div class="box">
+
+ <div class="blueprintUploader">
+ <h2>Upload your Blueprint</h2>
+ <p>
+ Upload an image which you will trace to make a floor plan.
+ Images should be at least 1000x1000.
+ </p>
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <input type="text" class="url" placeholder="Enter an image URL or...">
+ <div class="wallpaperUpload toolButton">
+ <form>
+ <span class="ion-ios-upload-outline upload-icon"></span>
+ <label>Upload a File</label>
+ <input type="file" accept="image/*" multiple>
+ </form>
+ </div>
+ <div class="blueprints">
+ <h5>Your uploaded blueprints</h5>
+ </div>
+ </div>
+
+ <div class="blueprintInfo vvbox">
+ Please tell us the scale of your blueprint.
+ Click two corners of a wall, and then enter how long the wall is.
+ <br><br>
+ You can also <span class="uploadNewBlueprint">upload another blueprint</span>.
+ <br><br>
+
+ <form>
+ <div class="setting number">
+ <label for="blueprint-dimensions">length</label>
+ <input type="text" class="units" name="blueprint-dimensions" id="blueprint-dimensions">
+ <select id="blueprint-units" name="blueprint-units">
+ <option value="ft">feet</option>
+ <option value="m">meters</option>
+ </select>
+ </div>
+ <button id="saveBlueprint">Save</button>
+ </form>
+ </div>
+
+ <div id="blueprintMap">
+ </div>
+
+ </div>
+</div> \ No newline at end of file
diff --git a/views/controls/blueprint/settings.ejs b/views/controls/blueprint/settings.ejs
new file mode 100644
index 0000000..9c615ea
--- /dev/null
+++ b/views/controls/blueprint/settings.ejs
@@ -0,0 +1,18 @@
+<div class="vvbox settings active" id="blueprintSettings">
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <input type="hidden" name="_id" value="new">
+
+ <div class="setting">
+ <input type="text" name="name" placeholder="Blueprint name">
+ </div>
+
+ <div class="setting">
+ <button data-role="save-layout">Save</button>
+ </div>
+
+ <div class="setting subButtons">
+ <a href="#" data-role="clear-layout">Clear</a>
+ <a href="#" data-role="destroy-layout">Delete</a>
+ </div>
+
+</div>
diff --git a/views/controls/blueprint/toolbar.ejs b/views/controls/blueprint/toolbar.ejs
new file mode 100644
index 0000000..ba795e3
--- /dev/null
+++ b/views/controls/blueprint/toolbar.ejs
@@ -0,0 +1,42 @@
+<div class="edit menu vvbox" id="blueprintToolbar">
+
+ <span
+ data-role='upload-floorplan'
+ data-info="upload a new floorplan"
+ class="ion-ios-upload-outline"></span>
+
+ <span
+ data-role='toggle-orbit-mode'
+ data-info="toggle 3D mode"
+ class="ion-ios-photos-outline"></span>
+
+ <span
+ data-role="arrow-mode"
+ data-info="move endpoints"
+ class="ion-navigate mode"></span>
+<!--
+ <span
+ data-role="polyline-mode"
+ data-info="draw walls"
+ class="ion-ios-pulse mode"></span>
+-->
+ <span
+ data-role="ortho-polyline-mode"
+ data-info="draw right-angled walls"
+ class="ion-ios-grid-view-outline mode"></span>
+
+ <span
+ data-role="eraser-mode"
+ data-info="remove walls"
+ class="ion-scissors mode"></span>
+
+ <span
+ data-role="start-position-mode"
+ data-info="set starting position"
+ class="ion-ios-home-outline mode"></span>
+
+ <span
+ data-role='toggle-layout-settings'
+ data-info="save blueprint"
+ class="ion-ios-compose-outline"></span>
+</div>
diff --git a/views/controls/builder/info.ejs b/views/controls/builder/info.ejs
index d92d34c..11e995a 100644
--- a/views/controls/builder/info.ejs
+++ b/views/controls/builder/info.ejs
@@ -1,4 +1,14 @@
-<div class="vvbox active settings info active" id="builderInfo">
+<div class="vvbox settings info" id="builderInfo">
+ <h4>Map Editor</h4>
+
+ <div class="no-selection">
+ Click and drag to make a new room.
+ Click a room to select, move or resize it.
+ <br><br>
+ Press ESC to toggle the map.
+ </div>
+
+
<div class="setting number">
<label for="room-width">width</label>
<input type="text" class="units" name="width" id="room-width">
@@ -10,6 +20,8 @@
<div class="setting number twoline">
<label for="room-height">ceiling height</label>
<input type="text" class="units" name="height" id="room-height">
+ <label for="room-height-global" id="room-height-global-label">global?</label>
+ <input type="checkbox" name="heightGlobal" id="room-height-global">
</div>
<div class="setting number halflines">
<label for="room-x">x</label>
@@ -22,8 +34,8 @@
<label for="builder-units">units</label>
<select id="builder-units" name="units">
<option value="px">pixels</option>
- <option value="ft">foot</option>
- <option value="m">meter</option>
+ <option value="ft">feet</option>
+ <option value="m">meters</option>
</select>
</div>
@@ -32,4 +44,8 @@
<input type="text" class="units" name="viewHeight" id="viewHeight">
</div>
+ <div class="setting">
+ <a href="#" class="warn btn" data-role="destroy-room">remove this room</a>
+ </div>
+
</div>
diff --git a/views/controls/builder/settings.ejs b/views/controls/builder/settings.ejs
index dd2496b..f7642ae 100644
--- a/views/controls/builder/settings.ejs
+++ b/views/controls/builder/settings.ejs
@@ -4,7 +4,7 @@
<div class="setting">
<a href="#" id="startpoint">
- <span class="icon-ios7-navigate-outline"></span>
+ <span class="ion-ios-navigate-outline"></span>
<span id="startText">Select Startpoint</span>
<span id="moveText">Move to Desired Point</span></a>
</div>
diff --git a/views/controls/builder/toolbar.ejs b/views/controls/builder/toolbar.ejs
index a00249c..ad51f0e 100644
--- a/views/controls/builder/toolbar.ejs
+++ b/views/controls/builder/toolbar.ejs
@@ -2,33 +2,33 @@
<span
data-role='toggle-map-view'
data-info="toggle map view"
- class="icon-ios7-photos-outline"></span>
+ class="ion-ios-photos-outline"></span>
<!--
<span
data-role='create-mode'
data-info="draw"
- class="icon-plus"></span>
+ class="ion-plus"></span>
<span
data-role='move-mode'
data-info="move"
- class="icon-arrow-move"></span>
+ class="ion-arrow-move"></span>
<span
data-role='resize-mode'
data-info="resize"
- class="icon-arrow-resize"></span>
+ class="ion-arrow-resize"></span>
-->
<span
data-role='destroy-mode'
data-info="delete"
- class="icon-ios7-trash-outline"></span>
+ class="ion-ios-trash-outline"></span>
<!--
<span
data-role='undo'
data-info="undo"
- class="icon-reply"></span>
+ class="ion-reply"></span>
-->
<span
data-role='toggle-layout-settings'
data-info="save layout"
- class="icon-ios7-compose-outline"></span>
+ class="ion-ios-compose-outline"></span>
</div>
diff --git a/views/controls/editor/collaborators.ejs b/views/controls/editor/collaborators.ejs
index 69e5b64..5de7d25 100644
--- a/views/controls/editor/collaborators.ejs
+++ b/views/controls/editor/collaborators.ejs
@@ -1,29 +1,31 @@
<div class="collaborators fixed mediaDrawer animate">
<span class="close">X</span>
-
- <div>
- <h2>Collaborators</h2>
- <p>
- To invite others to contribute to this project, submit their email address below. They'll receive an email with instructions to join this blog and register if they're not a Vvalls user yet.
- </p>
+ <div class="rap">
+ <div class="holder">
+ <div class="inner vvbox">
+ <h2>Collaborators</h2>
- <form>
- <input type="text" id="collaborator-email" name="email">
- <input type="submit" id="collaborator-invite" value="Invite to this project">
- </form>
+ <p>
+ To invite others to contribute to this project, submit their email address below. They'll receive an email with instructions to join this project and register if they're not a VValls user yet.
+ </p>
- <div id="collaborator-url-rapper">
- We've sent a link to join this project to <span id="collaborator-dummy-email"></span>.
- You can also send this link yourself:
- <input type="text" id="collaborator-url">
- </div>
+ <form>
+ <input type="text" id="collaborator-email" name="email">
+ <input type="submit" id="collaborator-invite" value="Invite to this project">
+ </form>
- <ul id="collaborator-list">
- </ul>
+ <div id="collaborator-url-rapper">
+ We've sent a link to join this project to <span id="collaborator-dummy-email"></span>.
+ You can also send this link yourself:
+ <input type="text" id="collaborator-url">
+ </div>
+ <ul id="collaborator-list">
+ </ul>
+ </div>
+ </div>
</div>
-
</div>
<script type="text/html" id="collaborator-template">
@@ -36,26 +38,3 @@
<span class="role">owner</span>
</li>
</script>
-
-<style>
-#collaborator-url-rapper {
- display: none;
- background: #fff;
- border: 1px solid;
- box-shadow: -3px 3px 0;
- padding: 10px;
- font-weight: 300;
- font-size: 14px;
- margin: 10px 0;
-}
-#collaborator-url {
- font-size: 16px;
- width: 500px;
- border: 1px solid;
- font-size: 14px;
- padding: 5px;
- font-weight: 300;
- margin-top: 5px;
- display: block;
-}
-</style>
diff --git a/views/controls/editor/color-control.ejs b/views/controls/editor/color-control.ejs
new file mode 100644
index 0000000..c035e24
--- /dev/null
+++ b/views/controls/editor/color-control.ejs
@@ -0,0 +1,27 @@
+<div class="vvbox colorcontrol">
+ <h4>Edit Room Colors</h4>
+
+ <div class="colors">
+ </div>
+
+ <div class="color-picker">
+ </div>
+
+ <div class="slider">
+ </div>
+
+ <div class="color-swatches">
+ <span>
+ <div class="swatch" id="wall-color" data-mode="wall"></div><label>wall</label>
+ </span>
+ <span class="active">
+ <div class="swatch" id="floor-color" data-mode="floor"></div><label>floor</label>
+ </span>
+ <span>
+ <div class="swatch" id="ceiling-color" data-mode="ceiling"></div><label>ceiling</label>
+ </span>
+ <span>
+ <div class="swatch" id="outline-color" data-mode="outline"></div><label>outlines</label>
+ </span>
+ </div>
+</div>
diff --git a/views/controls/editor/light-control.ejs b/views/controls/editor/light-control.ejs
deleted file mode 100644
index 8b133a5..0000000
--- a/views/controls/editor/light-control.ejs
+++ /dev/null
@@ -1,40 +0,0 @@
-<div class="vvbox lightcontrol">
- <div id="color-picker">
- </div>
-
- <div class="slider">
- <h4>Brightness Control</h4>
- <input type="range" min="0" max="110" value="0" id="brightness-control" />
- </div>
-
- <div class="color-swatches">
- <span>
- <div class="swatch" id="wall-color" data-mode="wall"></div><label>wall</label>
- </span>
- <span class="active">
- <div class="swatch" id="floor-color" data-mode="floor"></div><label>floor</label>
- </span>
- <span>
- <div class="swatch" id="ceiling-color" data-mode="ceiling"></div><label>ceiling</label>
- </span>
- <span>
- <div class="swatch" id="outline-color" data-mode="outline"></div><label>outlines</label>
- </span>
- <span>
- </div>
-
-<!--
- <div class="slider">
- <input type="range" min="0" max="100" value="100" id="wall-hue" />
- <h4>Wall Hue</h4>
- </div>
- <div class="slider">
- <input type="range" min="0" max="100" value="0" id="brightness-control" />
- <h4>Brightness</h4>
- </div>
- <div class="slider">
- <input type="range" min="0" max="100" value="0" id="shadow-control" />
- <h4>Shadow</h4>
- </div>
--->
-</div>
diff --git a/views/controls/editor/media-drawer.ejs b/views/controls/editor/media-drawer.ejs
index d73a3ef..8070941 100644
--- a/views/controls/editor/media-drawer.ejs
+++ b/views/controls/editor/media-drawer.ejs
@@ -1,62 +1,54 @@
-<span class="fileUpload">
- <input type="hidden" name="_csrf" value="[[- token ]]">
- <form>
- <span class="icon-ios7-upload-outline upload-icon"></span><br>
- Upload File
- <input type="file" accept="image/*" class="file" multiple>
- </form>
- <small>~ or ~</small><br>
- <input type="text" placeholder="Enter Vimeo or YouTube Link" class="url">
-</span>
-
<div class="ants">
<div class="leftborder"></div>
<img class="floatingImg">
</div>
<div class="mediaDrawer fixed animate mediaViewer">
- <span class="close">X</span>
- <h2><a href="#" class="userToggle active">Your Media</a> – <a href="#" class="foundToggle">Found Media</a></h2><br>
- <h3 class="editBtn warn" id="deleteMedia">delete media?</h3>
+ <h2>
+ <a href="#" class="userToggle active">Your Media</a>
+ – <a href="#" class="foundToggle">Found Media</a>
+<!--
+ – <a href="#" class="wallpaperToggle">Wallpaper</a>
+ -->
+ </h2><br>
+ <h3 class="editBtn warn" id="deleteMedia"></h3>
+ <h3 class="editBtn" id="randomize">Click here<br>to automatically place<br>images on walls!</h3>
+
<div class="myMedia">
+ <div class="noMedia">You have no media yet. Upload some!</div>
+ <span class="container"></span>
+ <a href="#" class="viewMore btn">view more</a>
</div>
-
+
<div class="foundMedia">
- <span class="mediaContainer">
- <img src="https://d1ycxz9plii3tb.cloudfront.net/post_images/52ec0e20c9dc24f1d8000067/large.jpg">
- </span>
- <span class="mediaContainer">
- <img src="https://d1ycxz9plii3tb.cloudfront.net/additional_images/4e6bf67bc23f490001004579/1/tall.jpg">
- </span>
- <span class="mediaContainer">
- <img src="https://d1ycxz9plii3tb.cloudfront.net/additional_images/52dcca28139b2135030002a8/tall.jpg">
- </span>
- <span class="mediaContainer">
- <img src="https://d1ycxz9plii3tb.cloudfront.net/additional_images/52927bb2b202a3669d000704/larger.jpg">
- </span>
- <span class="mediaContainer">
- <img src="https://d1ycxz9plii3tb.cloudfront.net/additional_images/4f9f3a3ce262e60001000fb3/large.jpg">
- </span>
- <span class="mediaContainer">
- <img src="http://2.bp.blogspot.com/-GD6IxUvsdOo/UdrcMFLVYNI/AAAAAAAAF2E/kbRfxMxiUlQ/s1600/okeeffe.jpg">
- </span>
- <span class="mediaContainer">
- <img src="http://www.bobkessel.com/wordpress/wp-content/uploads/2009/10/moma-bob-kessel-410.jpg">
- </span>
- <span class="mediaContainer">
- <img src="http://static1.artsy.net/partner_show_images/52f28f348b3b81f2fc000364/large.jpg">
- </span>
- <span class="mediaContainer">
- <img src="http://static3.artsy.net/partner_show_images/52e83674c9dc24397f0000d8/large.jpg">
- </span>
- <span class="mediaContainer">
- <img src="http://static0.artsy.net/partner_show_images/52d96d484b84801ef0000273/large.jpg">
- </span>
- <span class="mediaContainer">
- <img src="http://static1.artsy.net/partner_show_images/52778616275b24f95c00011d/1/large.jpg">
- </span>
- <span class="mediaContainer">
- <img src="http://static1.artsy.net/partner_show_images/52dc65311a1e86be6b000205/large.jpg">
- </span>
- </div>
-</div> \ No newline at end of file
+ <span class="container"></span>
+ </div>
+
+ <div class="wallpaperMedia">
+ <span class="container"></span>
+ </div>
+
+</div>
+
+<span class="fileUpload" id="fileUpload">
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <form>
+ <span class="ion-ios-upload-outline upload-icon"></span><br>
+ Upload File
+ <input type="file" accept="image/*" multiple>
+ </form>
+ <small>~ or ~</small><br>
+ <input type="text" placeholder="Enter Vimeo or YouTube or image link" class="url">
+</span>
+
+<span class="fileUpload" id="tumblrUpload">
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <input type="text" class="url" placeholder="Enter a Tumblr URL to add images from it!">
+ <br>
+ <span class="exampleTumblrs">
+ or try one of these:
+ <a href="#" class="exampleTumblr">risingtensions</a>
+ <a href="#" class="exampleTumblr">fixoid</a>
+ <a href="#" class="exampleTumblr">nopattern</a>
+ </span>
+</span>
diff --git a/views/controls/editor/media-editor.ejs b/views/controls/editor/media-editor.ejs
index 000e8db..225bdc8 100644
--- a/views/controls/editor/media-editor.ejs
+++ b/views/controls/editor/media-editor.ejs
@@ -1,4 +1,5 @@
<div class="vvbox settings" id="mediaEditor">
+ <h4>Media Settings</h4>
<input type="hidden" name="_csrf" value="[[- token ]]">
<input type="hidden" name="_id" value="new">
@@ -10,25 +11,27 @@
<textarea name="description" placeholder="short description"></textarea>
</div>
- <div class="video setting">
+ <div class="video audio setting">
<span class="playButton" data-role="play-media">
- <span class="on icon-play"></span>
- <span class="off icon-pause"></span>
+ <span class="on ion-ios-play-outline"></span>
+ <span class="off ion-ios-pause-outline"></span>
</span>
<!--
ion-volume-high
ion-volume-mute
-->
</div>
- <div class="video setting">
+ <div class="video audio setting">
<input type="checkbox" name="autoplay" value="1" id="video_autoplay">
<label for="video_autoplay">Autoplay</label>
<input type="checkbox" name="loop" value="1" id="video_loop">
<label for="video_loop">Loop</label>
+ <span class="video">
<input type="checkbox" name="mute" value="1" id="video_mute">
<label for="video_mute">Mute</label>
+ </span>
</div>
- <div class="video setting">
+ <div class="video audio setting">
<label for="video-keyframe">Initial Still</label>
<br>
<input type="range" min="0" max="1" value="0" step="0.01" name="keyframe" id="video-keyframe">
@@ -42,15 +45,16 @@
<label for="scenery-height">height</label>
<input type="text" class="units" name="height" id="scenery-height">
</div>
+ <!--
<div class="setting number">
<select id="builder-units" name="units">
<option value="px">pixels</option>
- <option value="ft">foot</option>
- <option value="m">meter</option>
+ <option value="ft">feet</option>
+ <option value="m">meters</option>
</select>
</div>
-
+ -->
<div class="setting">
- <a href="#" class="warn btn" data-role="destroy-media">delete this media</a>
+ <a href="#" class="warn btn" data-role="destroy-media">remove from wall</a>
</div>
</div>
diff --git a/views/controls/editor/presets.ejs b/views/controls/editor/presets.ejs
new file mode 100644
index 0000000..04b1cf1
--- /dev/null
+++ b/views/controls/editor/presets.ejs
@@ -0,0 +1,5 @@
+<div class="vvbox" id="presets">
+ <h4>Preset Styles</h4>
+ <div class="presets">
+ </div>
+</div>
diff --git a/views/controls/editor/sculpture.ejs b/views/controls/editor/sculpture.ejs
new file mode 100644
index 0000000..dfe917f
--- /dev/null
+++ b/views/controls/editor/sculpture.ejs
@@ -0,0 +1,42 @@
+<div class="vvbox settings" id="sculptureEditor">
+ <h4>3D Object</h4>
+
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <input type="hidden" name="_id" value="new">
+
+ <div class="setting">
+ <input type="text" name="name" placeholder="media title">
+ </div>
+
+ <div class="setting">
+ <textarea name="description" placeholder="short description"></textarea>
+ </div>
+
+ <div class="setting">
+ <input type="checkbox" name="outline" value="1" id="sculpture-outline">
+ <label for="sculpture-outline">Show outline?</label>
+ <input type="color" name="outlineColor" value="#000000">
+ </div>
+
+ <div class="setting">
+ <input type="checkbox" name="billboard" value="1" id="sculpture-billboard">
+ <label for="sculpture-billboard">Billboard?</label>
+ </div>
+
+ <div class="setting number">
+ <label for="sculpture-width">width</label>
+ <input type="text" class="units" name="width" id="sculpture-width">
+ </div>
+ <div class="setting number">
+ <label for="sculpture-height">height</label>
+ <input type="text" class="units" name="height" id="sculpture-height">
+ </div>
+ <div class="setting number">
+ <label for="sculpture-height">depth</label>
+ <input type="text" class="units" name="depth" id="sculpture-depth">
+ </div>
+ <div class="setting">
+ <a href="#" class="warn btn" data-role="destroy-sculpture">remove object</a>
+ </div>
+
+</div>
diff --git a/views/controls/editor/settings.ejs b/views/controls/editor/settings.ejs
index ed587fa..0ee00de 100644
--- a/views/controls/editor/settings.ejs
+++ b/views/controls/editor/settings.ejs
@@ -1,20 +1,40 @@
+<span id="helpCursor"></span>
+
<div class="vvbox settings" id="editorSettings">
+ <h4>Room Settings</h4>
<input type="hidden" name="_csrf" value="[[- token ]]">
<input type="hidden" name="_id" value="new">
- <div class="setting">
- <a href="#" class="modalLink" id="startpoint">
- <span class="icon-ios7-navigate-outline"></span>
- <span id="startText">Select Startpoint</span>
- <span id="moveText">Move to Desired Point</span></a>
+ <div class="setting" id="startpoint">
+ <a href="#" class="modalLink">
+ <span class="ion-ios-navigate-outline"></span>
+ <span id="startText">Set Startpoint</span>
+ <span id="moveText">Move to Desired Point <span class="done">done</span></span>
+ <span id="confirmText">Set Startpoint</span>
+ </a>
+ <a href="#" class="modalLink" id="goText"><span><u>view current</u></span></span>
</div>
+
<div class="setting">
<a href="#" class="modalLink" data-role='show-collaborators'>
- <span class="icon-ios7-plus-outline"></span>
+ <span class="ion-ios-plus-outline"></span>
Add Collaborators
</a>
</div>
+
+ <div class="setting">
+ <a href="#" class="modalLink" data-role='toggle-map'>
+ <span class="ion-map"></span>
+ Edit map
+ </a>
+
+ <a href="#" class="modalLink" data-role='view-project' style="margin-left: 40px;">
+ <span class="ion-ios-search-strong"></span>
+ View project
+ </a>
+ </div>
+
<div class="setting">
<input type="text" name="name" placeholder="room name">
</div>
diff --git a/views/controls/editor/share.ejs b/views/controls/editor/share.ejs
new file mode 100644
index 0000000..7e7ad3c
--- /dev/null
+++ b/views/controls/editor/share.ejs
@@ -0,0 +1,16 @@
+<div class="vvbox settings share">
+ <h4>Project Saved</h4>
+
+ <div class="setting">
+ <h2>Share on–</h2>
+ <a id="share_facebook">Facebook</a>
+ <a id="share_twitter">Twitter</a>
+ <a id="share_embed">Embed</a>
+ </div>
+
+ <div class="setting">
+ Send people this link:
+ <input type="text" id="share_link">
+ </div>
+
+</div>
diff --git a/views/controls/editor/signed-out.ejs b/views/controls/editor/signed-out.ejs
index 20e3715..118fb7c 100644
--- a/views/controls/editor/signed-out.ejs
+++ b/views/controls/editor/signed-out.ejs
@@ -8,7 +8,7 @@
</div>
<div class="share">
- <h2>Share this on–</h2>
+ <h2>Share on–</h2>
<a href="#">Facebook</a>
<a href="#">Twitter</a>
</div>
diff --git a/views/controls/editor/text-editor.ejs b/views/controls/editor/text-editor.ejs
new file mode 100644
index 0000000..baf9239
--- /dev/null
+++ b/views/controls/editor/text-editor.ejs
@@ -0,0 +1,76 @@
+<div class="vvbox settings" id="textEditor">
+ <h4>Edit Text</h4>
+
+ <div class="no-text">
+ Click a wall to add text.
+ </div>
+
+ <div class="setting text-setting">
+ <select name="font-family">
+ <option>Baskerville</option>
+ <option>Brush Script</option>
+ <option>Chicago</option>
+ <option>Comic Sans</option>
+ <option>Cooper</option>
+ <option>Courier New</option>
+ <option>Didot</option>
+ <option>Futura</option>
+ <option>Georgia</option>
+ <option>Gill Sans</option>
+ <option>Helvetica</option>
+ <option>Lato</option>
+ <option>Lucida Grande</option>
+ <option>Menlo</option>
+ <option>Palatino</option>
+ <option>Papyrus</option>
+ <option>Tahoma</option>
+ <option>Times New Roman</option>
+ <option>Zapfino</option>
+ </select>
+ <select name="font-size">
+ <option value="6">6pt</option>
+ <option value="8">8pt</option>
+ <option value="9">9pt</option>
+ <option value="10">10pt</option>
+ <option value="12">12pt</option>
+ <option value="16">16pt</option>
+ <option value="24">24pt</option>
+ <option value="36">36pt</option>
+ <option value="48">48pt</option>
+ <option value="72">72pt</option>
+ <option value="96">96pt</option>
+ </select>
+ <select name="text-align">
+ <option value="left">Left</option>
+ <option value="center">Center</option>
+ <option value="right">Right</option>
+ <option value="justify">Justify</option>
+ </select>
+ <div class="swatch"></div>
+ </div>
+
+ <div class="setting text-setting">
+ <textarea name="text-body"></textarea>
+ </div>
+
+ <div class="setting text-setting">
+ <a href="#" class="btn left" data-role="hide-text-editor">done</a>
+ <a href="#" class="warn btn right" data-role="destroy-text">remove from wall</a>
+ </div>
+
+ <div class="setting color-setting">
+ <a href="#" class="btn" data-role="hide-color-picker">done</a><br><br>
+
+ <div class="colors">
+ </div>
+
+ <div class="color-picker">
+ </div>
+
+ <div class="slider">
+ </div>
+ </div>
+</div>
+
+<style>
+</style> \ No newline at end of file
diff --git a/views/controls/editor/toolbar.ejs b/views/controls/editor/toolbar.ejs
index 4abf780..1a3e2d7 100644
--- a/views/controls/editor/toolbar.ejs
+++ b/views/controls/editor/toolbar.ejs
@@ -1,30 +1,49 @@
-<div class="edit menu vvbox" id="editorToolbar">
+
+<div class="edit menu vvbox" id="editorToolbar" data-intro="This is the main toolbar. Add and select media, Apply wallpaper, change room name etc." data-position="left">
+<!--
+ <span
+ data-role='undo'
+ data-info="undo"
+ class="ion-reply"></span>
+ -->
<span
data-role='open-media-viewer'
data-info="add media"
- class="icon-ios7-photos-outline"></span>
+ class="ion-ios-photos-outline"></span>
+ <span
+ data-role='toggle-presets'
+ data-info="preset styles"
+ class="ion-ios-briefcase-outline"></span>
+<!--
<span
data-role='resize-media'
data-info="resize media"
- class="icon-arrow-resize"></span>
+ class="ion-arrow-resize"></span>
<span
data-role='destroy-media'
data-info="delete media"
- class="icon-ios7-trash-outline"></span>
+ class="ion-ios-trash-outline"></span>
+ -->
<span
data-role='toggle-wallpaper-panel'
data-info="add wallpaper"
- class="icon-ios7-keypad-outline"></span>
+ class="ion-ios-keypad-outline"></span>
<span
- data-role='toggle-light-control'
+ data-role='toggle-color-control'
data-info="edit room colors"
- class="icon-ios7-sunny-outline"></span>
+ class="ion-ios-sunny-outline"></span>
+ <span
+ data-role='toggle-text-editor'
+ data-info="add text to wall"
+ class="ion-ios-compose-outline"></span>
+<!--
<span
- data-role='edit-wall-text'
- data-info="edit wall text"
- class="icon-ios7-compose-outline"></span>
+ data-role='toggle-map-view'
+ data-info="toggle map view"
+ class="ion-ios-world-outline"></span>
+ -->
<span
data-role='toggle-project-settings'
data-info="room settings"
- class="icon-key"></span>
+ class="ion-key"></span>
</div>
diff --git a/views/controls/editor/wallpaper.ejs b/views/controls/editor/wallpaper.ejs
index 208dfff..a53f462 100644
--- a/views/controls/editor/wallpaper.ejs
+++ b/views/controls/editor/wallpaper.ejs
@@ -1,25 +1,39 @@
<div class="vvbox wallpaper">
-
+ <h4>Add Wallpaper</h4>
<!-- IF NO WALL PAPER -->
- <span class="txt">Add custom wallpaper to walls. Begin by uploading a pattern. Or try this one -> </span>
+ <span class="txt" style="margin-bottom:7px">Add custom wallpaper to walls. Begin by uploading a pattern. Or try one of these -> </span>
- <div class="swatches"></div>
+ <span class="swatches">
+ <span class="swatch" style="background-image:url(/assets/img/offbeatrepeat.jpg)"></span>
+ <span class="swatch" style="background-image:url(/assets/img/plainpattern3.png)"></span>
+ <span class="swatch" style="background-image:url(/assets/img/plainpattern.png)"></span>
+ <span class="swatch" style="background-image:url(/assets/img/plainpattern2.png)"></span>
+ </span>
+
+ <input type="text" class="url" placeholder="Enter image URL">
- <div class="wallpaperUpload">
- <form>
+ <div class="wallpaperRemove toolButton">
+ <span class="ion-scissors"></span>
+ <label>Remove</label>
+ </div>
- <span class="icon-ios7-upload-outline upload-icon"></span>
- <label>Upload wallpaper</label>
- <input type="file" accept="image/*" class="file" multiple>
+ <div class="wallpaperUpload toolButton">
+ <form>
+ <span class="ion-ios-upload-outline upload-icon"></span>
+ <label>Upload</label>
+ <input type="file" accept="image/*" multiple>
</form>
-<!--
- <input type="text" placeholder="Enter Image URL" class="url">
- -->
</div>
- <div class="wallpaperRemove">
- <img src="/assets/img/scissors.png">
- <label>Remove Wallpaper</label>
+
+ <div class="wallpaperResizeControls">
+ <span data-role="wallpaper-position" class="ion-arrow-expand"></span>
+ <input data-role="wallpaper-scale" type="range" min="-4" max="4" step="0.01" value="0.0">
+ </div>
+
+ <div class="floodMessage">
+ Hit Enter to Flood the room!
</div>
+
</div>
<div class="floatingSwatch"></div>
diff --git a/views/controls/reader/about-room.ejs b/views/controls/reader/about-room.ejs
index e13f363..a9ef738 100644
--- a/views/controls/reader/about-room.ejs
+++ b/views/controls/reader/about-room.ejs
@@ -1,21 +1,28 @@
<div class="aboutRoom vvbox">
<h1>
- [[- name ]],
- <a href="[[- authorlink ]]">[[- author ]]</a>
+ <span class="roomName">[[- name ]]</span>
+ <br>
+ [[ if (authorpic) { ]]
+ <a href="[[- authorlink ]]" class="authorName"><div class="profilePic" style="background-image:url([[- authorpic ]])"></div></a>
+ [[ } else { ]]
+ <a href="[[- authorlink ]]" class="authorName"><span class="ion-ios-person-outline"></span></a>
+ [[ } ]]
+ <a href="[[- authorlink ]]" class="authorName">[[- author ]]</a>
</h1>
[[ if (description) { ]]
- <span class="txt">[[- description ]]</span>
+ <span class="txt description">[[- description ]]</span>
[[ } ]]
- <h2>
- Last modified [[- date ]]
+
+ <span class="txt">Last modified [[- date ]]</span>
+
+ <div class="share">
+ <h2>Share on–</h2>
+ <a id="share_facebook">Facebook</a>
+ <a id="share_twitter">Twitter</a>
+ <a id="share_embed">Embed</a>
+ </div>
+
[[ if (canEdit) { ]]
- <a href="[[- editlink ]]" class="btn warn marg">Edit Room</a>
+ <a href="[[- editlink ]]" class="btn warn marg" id="edit-room-link">Edit Room</a>
[[ } ]]
- </h2>
-</div>
-
-<div class="share">
- <h2>Share this on–</h2>
- <a href="#">Facebook</a>
- <a href="#">Twitter</a>
</div>
diff --git a/views/controls/reader/embed.ejs b/views/controls/reader/embed.ejs
new file mode 100644
index 0000000..814644d
--- /dev/null
+++ b/views/controls/reader/embed.ejs
@@ -0,0 +1,26 @@
+<div class="embedView fixed mediaDrawer animate">
+ <span class="close">X</span>
+
+ <div class="rap">
+ <div class="holder">
+ <div class="inner vvbox">
+ <h2>Embed VValls</h2>
+
+ <p>
+ This code generates an iframe which will embed this room in your website or blog.
+ </p>
+ <textarea id="embedCode"></textarea>
+
+ dimensions: <input type="text" name="width">x<input type="text" name="height">
+ <input type="checkbox" name="mute" id="mute" checked><label for="mute">mute</label>
+ <input type="checkbox" name="interactive" id="interactive" checked><label for="interactive">interactive</label>
+<!--
+ <input type="checkbox" id=""> <label for=""></label>
+ <input type="checkbox" id=""> <label for=""></label>
+ <input type="checkbox" id=""> <label for=""></label>
+ -->
+ <span id="testEmbed">test</span>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/views/controls/reader/media-player.ejs b/views/controls/reader/media-player.ejs
index ca03ec8..cac9992 100644
--- a/views/controls/reader/media-player.ejs
+++ b/views/controls/reader/media-player.ejs
@@ -1,19 +1,19 @@
<div class="vvbox settings" id="mediaPlayer">
- <span class="playButton video" data-role="play-media">
- <span class="on icon-play"></span>
- <span class="off icon-pause"></span>
+ <span class="playButton video audio" data-role="play-media">
+ <span class="on ion-play"></span>
+ <span class="off ion-pause"></span>
</span>
<span class="muteButton video" data-role="mute-media">
- <span class="on icon-volume-high"></span>
- <span class="off icon-volume-mute"></span>
+ <span class="on ion-volume-high"></span>
+ <span class="off ion-volume-mute"></span>
</span>
<span class="name"></span>
<div class="author"></div>
- <div class="description"></div>
+ <div class="txt description"></div>
<div class="dimensions"></div>
</div>
diff --git a/views/docs.ejs b/views/docs.ejs
index 5662133..a1f081f 100644
--- a/views/docs.ejs
+++ b/views/docs.ejs
@@ -1,19 +1,17 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="loading">
-<div class="rapper page docs">
+<div class="rapper page docs about">
[[ include partials/header ]]
- <br clear="all">
-
[[ if (! isNew) { ]]
<h1>[[- doc.displayName ]]</h1>
- <div class="content">
+ <div class="content doc-[[- doc.name]]">
[[- content ]]
</div>
diff --git a/views/editor.ejs b/views/editor.ejs
index 9950878..08959a0 100755
--- a/views/editor.ejs
+++ b/views/editor.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="editing loading">
@@ -13,15 +13,21 @@
<div id="editorView">
[[ include controls/editor/toolbar ]]
+ [[ include controls/builder/info ]]
[[ include controls/editor/media-drawer ]]
[[ include controls/editor/media-editor ]]
+ [[ include controls/editor/sculpture ]]
[[ include controls/editor/wallpaper ]]
- [[ include controls/editor/light-control ]]
+ [[ include controls/editor/color-control ]]
+ [[ include controls/editor/text-editor ]]
[[ include controls/editor/collaborators ]]
+ [[ include controls/editor/share ]]
+ [[ include controls/reader/embed ]]
[[ include controls/editor/settings ]]
+ [[ include controls/editor/presets ]]
</div>
- <div id="minimap" class="vvbox">
+ <div id="minimap" class="vvbox" data-intro="Mini-map shows your position and orientation in a room. Navigate with WASD keys or drag here." data-position="top">
<span class="el"></span>
</div>
@@ -29,6 +35,9 @@
<div id="map" style="display: block">
</div>
</div>
+
+
+ <img src="/assets/img/keys.png" id="keyhint">
</div>
diff --git a/views/home.ejs b/views/home.ejs
index e49dc4a..e3303ed 100755
--- a/views/home.ejs
+++ b/views/home.ejs
@@ -1,40 +1,84 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
- <script>
- window.addEventListener("load",function() {
- window.scrollTo(0,0)
- }, false);
- </script>
</head>
<body class="loading">
- <div class="rapper page">
+ <div class="rapper page home">
[[ include partials/header ]]
- <div class="hero" style="background-image:url(https://s3.amazonaws.com/luckyplop/6450f5b88c5c043a4551eff8902b1728f813bd66.jpg)">
+ <div class="hero" style="background-image:url(http://okfocus.s3.amazonaws.com/images/vvalls-video-still2.jpg)">
<div class="holder">
<span class="circle">
<span class="videoTitle">Create 3D Rooms</span><br>
- <span class="icon-ios7-play"></span><br>
+ <span class="ion-ios-play"></span><br>
<span class="videoTitle">Watch video.</span>
</span>
</div>
</div>
+
+ <h1>What's VValls For?</h1>
- <h1>Room Showcase</h1>
+ <div class="projectList about">
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://okfocus.s3.amazonaws.com/images/hangart1.gif)">
+ </span>
+ <span>
+ <h3>Plan Your Art Show</h3>
+ <words>Whether you're an artist or curator, VValls makes visualizing art within a physical space much easier. With VValls you can build 3D rooms and add art to the walls. Map out how your next gallery show will look without having to nail into sheetrock.</words>
+ </span>
+ </div>
+ </div>
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://dump.fm/images/20100904/1283618382861-dumpfm-timb-paperrad.paranoia.gif)">
+ </span>
+ <span>
+ <h3>Defy The Status Quo</h3>
+ <words>There is no platform on the Internet quite like VValls. VValls opens up the possibilities of expression online. Go crazy, make otherworldly rooms.</words>
+ </span>
+ </div>
+ </div>
+
+ <div class="item">
+ <div class="rap">
+ <span style="background-image:url(http://33.media.tumblr.com/tumblr_m0an31XPpF1qbhp9xo1_1280.jpg)">
+ </span>
+ <span>
+ <h3>Make Cutting Edge Presentations</h3>
+ <words>There's no cooler way than VValls for displaying your images online. Take your pix out of that drab Tumblr theme and present them in the freshest way online!</words>
+ </span>
+ </div>
+ </div>
+
+ <a href="/about/howto" class="greenbtn learn">Read Tutorial</a>
+</div>
+ <h1>Room Showcase</h1>
+
[[ include projects/list-projects ]]
-
- <a href="#loadmore" class="viewMore btn">View More</a>
+ [[ if (! logged_in) { ]]
+ <div class="projectList about makeAccountSingleton">
+ <a href="/about/howto" class="greenbtn learn">Make an Account</a>
+ </div>
+ [[ } ]]
+
[[ include partials/confirm-modal ]]
[[ include projects/layouts-modal ]]
[[ include partials/sign-in ]]
[[ include partials/footer ]]
</div>
+<div class="videoModal">
+<span class="ion-ios-close-empty"></span>
+<div class="holder">
+<div class="video" style="width: 960px; margin: 0 auto; height: 540px; overflow: hidden; position: relative;"><iframe frameborder="0" scrolling="no" seamless="seamless" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen" id="okplayer" src="http://player.vimeo.com/video/109947131?api=1&player_id=okplayer" width="960" height="540" style="width: 960px; height: 800px; margin-top: -130px;"></iframe></div>
+</div>
+</div>
</body>
[[ include partials/scripts ]]
</html>
diff --git a/views/mail/collaborator.html.ejs b/views/mail/collaborator.html.ejs
index 2a08a1c..c4832d1 100644
--- a/views/mail/collaborator.html.ejs
+++ b/views/mail/collaborator.html.ejs
@@ -7,7 +7,7 @@
<p>
<a href="http://vvalls.com/profile/[[- username ]]">[[- username ]]</a> has invited you to join the project
- <a href="http://vvalls.com/project/[[- projectSlug ]]">[[- projectName ]]</a> on Vvalls.
+ <a href="http://vvalls.com/project/[[- projectSlug ]]">[[- projectName ]]</a> on VValls.
</p>
<p>
diff --git a/views/mail/collaborator.text.ejs b/views/mail/collaborator.text.ejs
index 52d39b6..2de78ad 100644
--- a/views/mail/collaborator.text.ejs
+++ b/views/mail/collaborator.text.ejs
@@ -1,5 +1,5 @@
-[[- username ]] has invited you to join the project [[- projectName ]] on Vvalls.
+[[- username ]] has invited you to join the project [[- projectName ]] on VValls.
Accept the invitation below:
diff --git a/views/mail/welcome.html.ejs b/views/mail/welcome.html.ejs
index b2c329f..1d45faf 100644
--- a/views/mail/welcome.html.ejs
+++ b/views/mail/welcome.html.ejs
@@ -6,7 +6,7 @@
</p>
<p>
- Welcome to Vvalls, [[- username ]]
+ Welcome to VValls, [[- username ]]
</p>
<p>
diff --git a/views/mail/welcome.text.ejs b/views/mail/welcome.text.ejs
index 02b449b..5c0b51d 100644
--- a/views/mail/welcome.text.ejs
+++ b/views/mail/welcome.text.ejs
@@ -1,4 +1,4 @@
-Welcome to Vvalls, [[- username ]]
+Welcome to VValls, [[- username ]]
http://www.vvalls.com
diff --git a/views/modal.ejs b/views/modal.ejs
index 7ca869c..dfc5573 100644
--- a/views/modal.ejs
+++ b/views/modal.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
<body class="loading">
@@ -10,7 +10,7 @@
<div style="height: 70%; clear: both;" id="content"></div>
- [[ include partials/confirm-modal ]]
+ [[ include partials/confirm-modal ]]
[[ include partials/sign-in ]]
[[ include projects/layouts-modal ]]
[[ include projects/edit-project ]]
diff --git a/views/partials/confirm-modal.ejs b/views/partials/confirm-modal.ejs
index 60fbd31..5b2ff46 100644
--- a/views/partials/confirm-modal.ejs
+++ b/views/partials/confirm-modal.ejs
@@ -1,5 +1,4 @@
<div class="mediaDrawer fixed animate alert">
- <span class="close">X</span>
<div class="box">
<form>
<span class="message"></span>
diff --git a/views/partials/edit-profile.ejs b/views/partials/edit-profile.ejs
index a39f856..5720bc8 100644
--- a/views/partials/edit-profile.ejs
+++ b/views/partials/edit-profile.ejs
@@ -59,11 +59,10 @@
<br>
<br><img id="load_avatar">
</li>
-
<li class="section_break">
- <h3 class="link">Change Password</h3>
+ <h3 class="link" data-role="changePasswordToggle">Change Password</h3>
</li>
- <div class="hidden">
+ <div class="hidden" data-role="changePasswordFields">
<li>
<label class="description" for="profile_old_password">Old Password:</label>
<div>
@@ -84,7 +83,7 @@
</li>
</div>
<li class="buttons">
- <input id="saveForm" class="button_text" type="submit" value="Submit" />
+ <input id="saveForm" class="button_text" type="submit" value="Save Changes">
</li>
<div class="errors">
<div>There was a problem with your submission:</div>
diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs
new file mode 100644
index 0000000..f3c3589
--- /dev/null
+++ b/views/partials/edit-subscription.ejs
@@ -0,0 +1,78 @@
+<div class="mediaDrawer fixed animate editSubscription">
+ <span class="close">X</span>
+ <div id="form_container">
+ <form>
+ <input type="hidden" name="_csrf" value="[[- token ]]">
+ <ul>
+ <li class="section_break">
+ <h3>Edit Subscription</h3>
+ </li>
+ <li class="freePlan">
+ You are currently using the free version of VValls. For access to all of VValls features,
+ consider upgrading to a paid plan.
+ <br><br>
+ <div class="planList"></div>
+ <br><br><br>
+ </li>
+ <li class="paidPlan">
+ <div class="currentPlanLevel">
+ Your current plan level is <span data-role="planName"></span>
+ </div>
+ <div class="planMenu">
+ <h3>Select desired plan:</h3>
+ <div>
+ <input type="radio" id="chooseBasicPlan" data-role="basicPlanInput" name="planRadio" value="basic">
+ <label for="chooseBasicPlan" data-role="basicPlanName"></label>
+ $<span data-role="basicPlanCost"></span>/<span data-role="billingInterval"></span>
+ </div>
+ <div>
+ <input type="radio" id="chooseProPlan" data-role="proPlanInput" name="planRadio" value="pro">
+ <label for="chooseProPlan" data-role="proPlanName"></label>
+ $<span data-role="proPlanCost"></span>/<span data-role="billingInterval"></span>
+ </div>
+ </div>
+ <table class="planInfo">
+ <tr class="planRow">
+ <th><span data-role="planName"></span></th>
+ <td></td>
+ <td></td>
+ <td>$<span data-role="planCost"></span>/<span data-role="billingInterval"></span></td>
+ </tr>
+ <tr class="basicLayoutRow">
+ <th>Basic layouts</th>
+ <td><input type="number" min="0" max="100" step="1" data-role="basicLayoutInput"><span data-role="basicLayoutQuantity"></span></td>
+ <td>each $<span data-role="basicLayoutCost"></span>/<span data-role="billingInterval"></span></td>
+ <td>$<span data-role="basicLayoutTotal"></span>/<span data-role="billingInterval"></span></td>
+ </tr>
+ <tr class="proLayoutRow">
+ <th>Pro layouts</th>
+ <td><input type="number" min="0" max="100" data-role="proLayoutInput"><span data-role="proLayoutQuantity"></span></td>
+ <td>each $<span data-role="proLayoutCost"></span>/<span data-role="billingInterval"></span></td>
+ <td>$<span data-role="proLayoutTotal"></span>/<span data-role="billingInterval"></span></td>
+ </tr>
+ <tr class="totalRow">
+ <td></td>
+ <td></td>
+ <th>Total</th>
+ <td>$<span data-role="planTotal"></span>/<span data-role="billingInterval"></span></td>
+ </tr>
+ </table>
+ <div class="billingMenu">
+ <button data-role="showEditMenu">Edit Your Plan</button><br>
+ <button data-role="cancelSubscription">Cancel your subscription</button>
+ </div>
+ <div class="editMenu">
+ <div class="fineprint">
+ Your credit card will be charged the difference of XXXX for this month.
+ Your subscription will renew at XXXX at the start of your next billing cycle.
+ We thank you for your support!
+ </div>
+ <button data-role="saveChanges">Save Subscription</button>
+ <button data-role="closeMenu">Cancel</button>
+ </div>
+ </li>
+ <div class="gear"><span class="ion-gear-a"></span></div>
+ </ul>
+ </form>
+ </div>
+</div>
diff --git a/views/partials/footer.ejs b/views/partials/footer.ejs
index 3f816f0..2d9fb59 100644
--- a/views/partials/footer.ejs
+++ b/views/partials/footer.ejs
@@ -1,18 +1,9 @@
<div class="footer">
- <a href="/about">About</a>
- <a href="/about/faq">FAQ</a>
- <a href="/about/terms">Terms</a>
- <a href="/about/privacy">Privacy</a>
-
- <span>©2014 VVALLS Inc.</span>
-
[[ if (logged_in) { ]]
- <br><br>
-
<span>
- you are signed in as &rarr;
- <a href="/profile/[[- user.username ]]">[[- user.displayName ]]</a>
+ signed in as
+ <a href="/profile/[[- user.username ]]"><b>[[- user.displayName ]]</b></a>
[[ if (user.isStaff) { ]]
<a href="/staff">Staff Area</a>
[[ } ]]
@@ -20,4 +11,21 @@
</span>
[[ } ]]
+ <br><br>
+
+ <a href="/about">About</a>
+ <a href="/about/howto">How To</a>
+
+ [[ if (logged_in && user.plan_level > 0) { ]]
+ <a href="/profile/billing">Billing</a>
+ [[ } else { ]]
+ <a href="/about/brochure">Subscribe</a>
+ [[ } ]]
+ <a href="/about/terms">Terms</a>
+ <a href="/about/privacy">Privacy</a>
+ <a href="mailto:hello@vvalls.com">Contact</a>
+ <br><br>
+ <span>&copy; 2016 Dot Dash 3, Inc.</span>
+ <a href="http://okfoc.us/">Site by OKFocus</a>
+
</div>
diff --git a/views/partials/header.ejs b/views/partials/header.ejs
index a48c5e1..ce9ffae 100644
--- a/views/partials/header.ejs
+++ b/views/partials/header.ejs
@@ -1,4 +1,51 @@
-<a href="/" class="logo"><img src="/assets/img/logo4.svg"></a>
+<div id="header">
+<a href="/" class="logo">
+ <svg version="1.1"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ x="0px" y="0px" width="117px" height="44px" viewBox="-0.896 -0.441 117 44"
+ overflow="visible" enable-background="new -0.896 -0.441 117 44" xml:space="preserve">
+ <defs>
+ </defs>
+ <path d="M0.54,38.759c0-1.44,0.66-3.72,1.56-6.18c1.38-3.84,3.42-8.22,4.5-11.16c0.48-1.32,0.78-2.34,0.78-2.88
+ c0-0.72-0.24-1.02-0.72-1.02c-1.38,0-4.74,5.16-5.4,6.24c-0.36,0.6-0.48,0.78-0.78,0.78c-0.3,0-0.48-0.06-0.48-0.36
+ c0-0.18,0.18-0.84,0.66-1.62c0.9-1.44,2.22-3.6,3.9-5.28c1.44-1.5,3.12-2.64,4.74-2.64c1.38,0,1.92,1.32,1.92,2.7
+ c0,1.02-0.42,2.58-1.02,4.32c-1.26,3.72-3.359,8.521-4.68,12.18c-0.66,1.92-1.14,3.54-1.14,4.62c0,1.38,0.48,2.459,1.979,2.459
+ c6.48,0,13.56-14.639,13.56-17.759c0-1.2-0.3-1.92-0.6-2.58c-0.42-0.9-0.9-1.62-0.9-3.18c0-1.86,0.84-2.76,1.8-2.76
+ c0.9,0,1.98,1.08,1.98,3.66c0,9.179-9.6,24.66-17.58,24.66c-2.82,0-4.08-1.561-4.08-4.141V38.759z"/>
+ <path d="M23.879,38.759c0-1.44,0.66-3.72,1.56-6.18c1.38-3.84,3.42-8.22,4.5-11.16c0.48-1.32,0.78-2.34,0.78-2.88
+ c0-0.72-0.24-1.02-0.72-1.02c-1.38,0-4.74,5.16-5.4,6.24c-0.36,0.6-0.48,0.78-0.78,0.78c-0.3,0-0.48-0.06-0.48-0.36
+ c0-0.18,0.18-0.84,0.66-1.62c0.9-1.44,2.22-3.6,3.9-5.28c1.44-1.5,3.12-2.64,4.74-2.64c1.38,0,1.92,1.32,1.92,2.7
+ c0,1.02-0.42,2.58-1.02,4.32c-1.26,3.72-3.36,8.521-4.68,12.18c-0.66,1.92-1.14,3.54-1.14,4.62c0,1.38,0.48,2.459,1.98,2.459
+ c6.479,0,13.559-14.639,13.559-17.759c0-1.2-0.3-1.92-0.6-2.58c-0.42-0.9-0.9-1.62-0.9-3.18c0-1.86,0.84-2.76,1.8-2.76
+ c0.9,0,1.979,1.08,1.979,3.66c0,9.179-9.6,24.66-17.579,24.66c-2.82,0-4.08-1.561-4.08-4.141V38.759z"/>
+ <path d="M44.339,37.799c0-5.22,2.76-10.92,6.36-15.299c3.66-4.44,8.159-7.5,11.759-7.5c2.7,0,3.78,1.44,3.9,1.44
+ s0.48-0.96,0.66-1.44c0.18-0.48,0.3-0.6,1.02-0.6h1.74c0.359,0,0.6,0.06,0.6,0.42c0,0.18-0.119,0.6-0.24,0.9
+ c-1.919,5.82-3.839,11.64-5.819,17.519c-1.14,3.48-1.26,4.381-1.26,5.041c0,0.659,0.3,0.84,0.66,0.84c0.54,0,1.68-1.141,3.72-4.26
+ c1.5-2.28,1.26-2.94,1.86-2.94c0.3,0,0.42,0.181,0.42,0.479c0,0.84-1.38,3.541-3.24,6c-1.8,2.52-4.14,4.8-6.12,4.8
+ c-1.38,0-1.62-0.96-1.62-2.159c0-0.961,0.24-2.101,0.72-3.66c0.54-1.98,1.5-4.62,2.82-8.52l-0.12-0.12
+ c-2.16,3.3-9.36,14.459-14.1,14.459c-2.76,0-3.72-2.159-3.72-5.339V37.799z M65.338,18.839c0-1.8-1.08-2.76-2.76-2.76
+ c-3,0-6.6,3.72-9.48,8.22c-2.82,4.5-4.919,9.839-4.919,13.019c0,1.561,0.54,2.641,1.86,2.641c2.22,0,6.06-4.26,9.3-9
+ c3.3-4.74,6-10.02,6-12.06V18.839z"/>
+ <path d="M72.178,39.839c0-1.08,0.479-3.479,1.2-6.479c1.74-7.02,4.979-17.52,6.6-23.64c0.66-2.46,1.08-4.2,1.08-4.8
+ c0-0.78-0.24-1.32-1.62-1.44c-1.14-0.12-1.38-0.3-1.38-0.78c0.061-0.42,0.779-0.66,1.8-0.66c2.58,0,4.2-0.78,5.16-1.38
+ c0.6-0.36,0.96-0.66,1.14-0.66c0.3,0,0.42,0.12,0.42,0.48c0,0.3-0.6,1.56-1.14,3.479c-5.04,17.759-7.38,25.799-8.46,29.698
+ c-0.84,3.061-0.96,3.84-0.96,4.681c0,0.6,0.3,1.02,0.78,1.02c0.84,0,1.619-0.659,3.479-3.72c1.08-1.74,1.92-4.199,2.46-4.199
+ c0.301,0,0.42,0.239,0.42,0.539c0,0.42-0.84,2.521-2.16,4.74c-1.739,3-4.319,6.24-6.719,6.24c-1.681,0-2.101-1.32-2.101-3.061
+ V39.839z"/>
+ <path d="M85.497,39.839c0-1.08,0.48-3.479,1.2-6.479c1.739-7.02,4.979-17.52,6.6-23.64c0.66-2.46,1.08-4.2,1.08-4.8
+ c0-0.78-0.24-1.32-1.62-1.44c-1.14-0.12-1.38-0.3-1.38-0.78c0.06-0.42,0.78-0.66,1.8-0.66c2.58,0,4.2-0.78,5.16-1.38
+ c0.6-0.36,0.96-0.66,1.14-0.66c0.3,0,0.42,0.12,0.42,0.48c0,0.3-0.6,1.56-1.14,3.479c-5.04,17.759-7.38,25.799-8.46,29.698
+ c-0.84,3.061-0.96,3.84-0.96,4.681c0,0.6,0.301,1.02,0.78,1.02c0.84,0,1.62-0.659,3.479-3.72c1.08-1.74,1.92-4.199,2.46-4.199
+ c0.3,0,0.42,0.239,0.42,0.539c0,0.42-0.84,2.521-2.159,4.74c-1.74,3-4.32,6.24-6.721,6.24c-1.68,0-2.1-1.32-2.1-3.061V39.839z"/>
+ <path d="M111.416,34.619c0,2.34-0.96,4.439-2.46,5.939c-1.68,1.68-4.02,2.64-6.479,2.64c-1.86,0-3.84-0.78-5.04-1.56
+ c-0.6-0.42-1.02-0.84-1.02-1.2c0-0.96,0.359-3.12,0.959-5.819c0.42-1.98,0.48-2.34,1.08-2.34c0.541,0,0.601,0.359,0.601,2.16
+ c0,3.84,1.2,7.319,4.92,7.319c2.34,0,4.2-2.46,4.2-4.74c0-2.819-1.561-4.979-3.24-6.96c-1.68-1.979-3.24-4.08-3.24-6.899
+ c0-4.38,3.24-8.76,7.859-8.76c3,0,5.82,1.38,5.82,2.1c0,1.14-0.301,2.4-0.66,3.9c-0.72,2.76-0.779,3.06-1.38,3.06
+ c-0.899,0-0.78-1.92-1.08-3.84c-0.3-1.86-1.08-3.78-3.6-3.78c-2.34,0-4.08,2.04-4.08,4.439s1.62,4.44,3.24,6.6
+ c1.8,2.34,3.6,4.68,3.6,7.68V34.619z"/>
+ </svg>
+
+</a>
<div id="minotaur">
<span class="label"></span>
@@ -6,21 +53,33 @@
<span class="topLinks">
[[ if (logged_in) { ]]
-
[[ if (user.isStaff) { ]]
<a href="/layout" data-role="show-layouts-modal" class="topLink">Layouts</a>
[[ } ]]
- <a href="/project" data-role="show-projects-modal" class="topLink">Projects</a>
+ <!--<a href="/project" data-role="show-projects-modal" class="topLink">Projects</a>-->
+
+ <a href="#" data-role="new-project-modal">New Project</a>
+
[[ if (profile && String(user._id) == String(profile._id)) { ]]
<a href="/profile" data-role="edit-profile-modal" class="topLink editProfile">Settings</a>
+<!--
+ <a href="/profile" data-role="edit-subscription-modal" class="topLink editSubscription">Subscription</a>
+ -->
[[ } else if (! profile) { ]]
- <a href="/profile" class="topLink">Profile</a>
+ <a href="/profile" class="topLink profileLink">Profile</a>
[[ } ]]
-
+
+ [[ if (opt.editing) { ]]
+ <a href="#" class="ion-help-circled" id="help-button"></a>
+ [[ } ]]
+
[[ } else { ]]
<a href="/signup" data-role="show-signup-modal" class="signUp topLink">Sign Up</a>
- <a href="/login" data-role="show-signin-modal" class="signIn topLink">Sign In</a>
+ <a href="/signin" data-role="show-signin-modal" class="signIn topLink">Sign In</a>
[[ } ]]
</span>
+</div>
+
+<span class="close" id="fixed_close">X</span> \ No newline at end of file
diff --git a/views/partials/meta.ejs b/views/partials/meta.ejs
index 9916b34..673ab64 100644
--- a/views/partials/meta.ejs
+++ b/views/partials/meta.ejs
@@ -17,19 +17,19 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
- <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
- <meta name="keywords" content=""/>
- <meta name="description" content="" />
- <meta name="author" content="" />
- <link rel="shortcut icon" href="/favicon.ico"/>
- <meta property="og:title" content=""/>
- <meta property="og:type" content="website"/>
- <meta property="og:image" content="" />
- <link rel="image_src" href=""/>
- <meta property="og:url" content=""/>
- <meta property="og:site_name" content="" />
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable = no">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <meta name="description" content="[[- ogDescription ]]" />
+ <meta name="author" content="[[- ogAuthor ]]" />
+ <link rel="shortcut icon" href="/favicon.ico" />
+ <meta property="og:title" content="[[- ogTitle ]]" />
+ <meta property="og:type" content="website" />
+ <meta property="og:image" content="[[- ogImage ]]" />
+ <meta property="og:url" content="[[- ogUrl ]]" />
+ <meta property="og:site_name" content="vvalls" />
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+ <link href='http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic' rel='stylesheet' type='text/css'>
<link href='/assets/stylesheets/ionicons.css' rel='stylesheet' type='text/css'>
<link href='/assets/stylesheets/app.css' rel='stylesheet' type='text/css'>
<!--[if lt IE 9]>
diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs
index 7d56b2e..da3f0ba 100644
--- a/views/partials/scripts.ejs
+++ b/views/partials/scripts.ejs
@@ -1,44 +1,64 @@
+[[ if (config.env.production) { ]]
+<script type="text/javascript" src="/assets/javascripts/app.min.js"></script>
+[[ } else { ]]
<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script>
-<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js"></script>
+<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/lodash/lodash.min.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script>
+<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js"></script>
+<!-- <script type="text/javascript" src="/assets/javascripts/vendor/bower_components/prefixfree/prefixfree.min.js"></script> -->
+<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/marked/lib/marked.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/tube.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/loader.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/polyfill.js"></script>
+<!-- <script type="text/javascript" src="/assets/javascripts/vendor/wow.js"></script> -->
+<!-- <script type="text/javascript" src="/assets/javascripts/vendor/chardinjs.min.js"></script> -->
<script type="text/javascript" src="/assets/javascripts/vendor/sha1.js"></script>
<script type="text/javascript" src="/assets/javascripts/vendor/dataUriToBlob.js"></script>
+<script type="text/javascript" src="/assets/javascripts/vendor/froogaloop.js"></script>
<script type="text/javascript" src="/assets/javascripts/util.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/mx.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/mx/extensions/mx.scene.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/extensions/mx.movements.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/extensions/mx.movementsMobile.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/extensions/mx.orbitCamera.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.image.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.text.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.video.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.youtube.js"></script>
<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.vimeo.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.soundcloud.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.grid.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.point.js"></script>
+<script type="text/javascript" src="/assets/javascripts/mx/primitives/mx.polyline.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/_env.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/rectangles/util/constants.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/util/colors.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/util/coords.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/util/debug.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/util/permissions.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/util/keys.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/util/measurement.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/util/minotaur.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/util/mouse.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/util/permissions.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/util/sort.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/util/uid.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/util/wheel.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/util/mouse.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/util/keys.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/util/undostack.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/util/minotaur.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/util/wheel.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/rectangles/models/vec2.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/vec3.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/models/mat4.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/rect.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/surface.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/tree.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/room.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/wall.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/models/floor.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/rooms/_rooms.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/rooms/_walls.js"></script>
@@ -50,34 +70,64 @@
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/_scenery.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/move.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/resize.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/randomize.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/sound.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/undo.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/_object.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/audio.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/image.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/text.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/video.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/_sculpture.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/move.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/resize.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/types/_object.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/sculpture/types/image.js"></script>
+
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/shapes/polyline.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/shapes/ortho.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/shapes/shapelist.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/shapes/regionlist.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/_map.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui_editor.js"></script>
-<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui_minimap.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/draw.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui/editor.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui/minimap.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/line.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/eraser.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/ortho.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/polyline.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/position.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/tools/start.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/View.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/Router.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/ModalView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/FormView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/UploadView.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/lib/AnimatedView.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/lib/ToggleableView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/AlertModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/ConfirmModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/ErrorModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/lib/Parser.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/lib/LabColorPicker.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/SignInModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/SignUpModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/UsernameTaken.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/PasswordForgot.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/PasswordReset.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/site/LayoutsIndex.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/LayoutsModal.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/site/NewProjectModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/EditProjectModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/EditProfileModal.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/site/EditSubscriptionModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/DocumentModal.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/site/HomeView.js"></script>
@@ -89,24 +139,41 @@
<script type="text/javascript" src="/assets/javascripts/ui/builder/BuilderToolbar.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/builder/BuilderInfo.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintView.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintInfo.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintSettings.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintEditor.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintScaler.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintToolbar.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintUploader.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/blueprint/BlueprintNotice.js"></script>
+
<script type="text/javascript" src="/assets/javascripts/ui/editor/EditorView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/EditorSettings.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/EditorToolbar.js"></script>
-<script type="text/javascript" src="/assets/javascripts/ui/editor/LightControl.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/editor/HelpCursor.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/editor/ColorControl.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/Collaborators.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/MediaEditor.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/editor/MediaTumblr.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/MediaUpload.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/MediaViewer.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/editor/Presets.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/editor/SculptureEditor.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/editor/TextEditor.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/editor/WallpaperPicker.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/reader/ReaderView.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/reader/ShareView.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/reader/EmbedView.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/reader/MediaPlayer.js"></script>
+<script type="text/javascript" src="/assets/javascripts/ui/reader/Tracker.js"></script>
<script type="text/javascript" src="/assets/javascripts/ui/_router.js"></script>
<script type="text/javascript" src="/assets/javascripts/app.js"></script>
<script type="text/javascript" src="/assets/javascripts/defaults.js"></script>
+[[ } ]]
-<!-- external dependencies -->
-<script src="http://www.youtube.com/player_api"></script>
-<script src="http://a.vimeocdn.com/js/froogaloop2.min.js"></script>
+<script type="text/javascript" src="http://www.youtube.com/player_api"></script>
+<script type="text/javascript" src="https://w.soundcloud.com/player/api.js"></script>
diff --git a/views/partials/sign-in.ejs b/views/partials/sign-in.ejs
index 98f0acc..0d36a1d 100644
--- a/views/partials/sign-in.ejs
+++ b/views/partials/sign-in.ejs
@@ -3,9 +3,12 @@
<div class="mediaDrawer fixed animate signin">
<span class="close">X</span>
<div class="box">
+
<form id="signIn" method="post">
+ <h2>Sign in</h2>
+
<input type="hidden" name="_csrf" value="[[- token ]]">
- <a href="/auth/facebook" class="facebook"><b class="icon-social-facebook"></b><span>Sign in with Facebook</span></a>
+ <a href="/auth/facebook" class="facebook"><b class="ion-social-facebook"></b><span>Sign in with Facebook</span></a>
<b class="signin-tagline">– or with your email –</b>
<li>
<label class="description" for="usernameInput">Username:</label>
@@ -37,8 +40,10 @@
<span class="close">X</span>
<div class="box">
<form id="signUp" method="post">
+ <h2>Sign up</h2>
+
<input type="hidden" name="_csrf" value="[[- token ]]">
- <a href="/auth/facebook" class="facebook"><b class="icon-social-facebook"></b><span>Sign up with Facebook</span></a>
+ <a href="/auth/facebook" class="facebook"><b class="ion-social-facebook"></b><span>Sign up with Facebook</span></a>
<b class="signin-tagline">– or with your email –</b>
<li>
<label class="description" for="usernameInput">Username:</label>
diff --git a/views/profile.ejs b/views/profile.ejs
index ada3d52..d3ae10e 100644
--- a/views/profile.ejs
+++ b/views/profile.ejs
@@ -1,52 +1,86 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls | [[- profile.displayName ]]</title>
[[ include partials/meta ]]
</head>
<body class="loading">
<div class="rapper page">
[[- include partials/header ]]
- <table class="profilepage">
- <tr>
- [[ if (profile.photo && profile.photo.length) { ]]
- <td class="border profilePic" style="background-image:url([[- profile.photo ]])">
- </td>
- [[ } else { ]]
- <td class="border profilePic">
- <span class="icon-ios7-person-outline"></span>
- </td>
+ <div class="profilepage">
+ [[ if (profile.photo && profile.photo.length) { ]]
+ <div class="profilePic" style="background-image:url([[- profile.photo ]])">
+ </div>
+ [[ } else { ]]
+ <div class="profilePic noPic">
+ <span class="holder">
+ <span class="ion-ios-person-outline"></span>
+ [[ if (isOwnProfile) { ]]
+ <div>click to add profile pic</div>
+ <input id="profile_avatar" name="avatar" class="element file" type="file">
+ [[ } ]]
+ </span>
+ </div>
+ [[ } ]]
+ <div class="bio">
+ <div class="holder">
+ <h2>[[- profile.displayName ]]</h2>
+ [[ if (profile.location) { ]]
+ <span>
+ [[- profile.location ]]
+ </span>
+ [[ } ]]
+ [[ if (profile.website && profile.website.length) { ]]
+ <span>
+ <a href="[[- profile.website ]]" target="_blank">[[- profile.website ]]</a>
+ </span>
+ [[ } ]]
+ [[ if (profile.twitterName && profile.twitterName.length) { ]]
+ <span>
+ <a href="https://twitter.com/[[- profile.twitterName ]]" target="_blank">@[[- profile.twitterName ]]</a>
+ </span>
[[ } ]]
- <td class="bio">
- <h2>[[- profile.displayName ]]</h2>
- [[ if (profile.location) { ]]
- <span>
- [[- profile.location ]]
- </span>
- [[ } ]]
- [[ if (profile.website && profile.website.length) { ]]
- <span>
- <a href="[[- profile.website ]]">[[- profile.website ]]</a>
- </span>
- [[ } ]]
- [[ if (profile.twitterName && profile.twitterName.length) { ]]
- <span>
- <a href="https://twitter.com/[[- profile.twitterName ]]">@[[- profile.twitterName ]]</a>
- </span>
- [[ } ]]
- </td>
- </tr>
- </table>
+ [[ if (profile.plan_level == 1) { ]]
+ <span class="plan_level premium">PREMIUM</span>
+ [[ } else if (profile.plan_level == 2) { ]]
+ <span class="plan_level pro">PRO</span>
+ [[ } ]]
+ </div>
+ </div>
[[ if (projects.length) { ]]
- <h1>[[- profile.username ]] has [[- projects.length ]] project[[- projects.length != 1 ? "s" : "" ]]</h1>
+
+ <h1>[[- profile.username ]] has [[- projectCount ]] project[[- projectCount != 1 ? "s" : "" ]]</h1>
+ [[ include projects/list-projects ]]
+
+ [[ } else { ]]
+
+ <h1>Welcome to VVALLS</h1>
+ <div class="projectList about">
+ <h2>
+ VValls lets you create awesome 3D rooms.
+ </h2>
+
+ [[ if (isOwnProfile) { ]]
+ <h2>
+ You don't have any projects yet.
+ </h2>
+ <h2>
+ <a href="#"class="btn" data-role="new-project-modal">Create a New Project</a>
+ </h2>
+ [[ } else { ]]
+ <h2><a href="/" class="homeLink">Learn more about VValls</a></h2>
+ <h3>This person has no projects.</h3>
+ [[ } ]]
+ </div>
+
[[ } ]]
-
- [[ include projects/list-projects ]]
- <a href="#" data-role="new-project-modal" class="viewMore btn">create project</a>
-
+ </div>
+<!--
+ [[ include partials/edit-subscription ]]
+ -->
[[ include partials/edit-profile ]]
[[ include projects/layouts-modal ]]
[[ include projects/edit-project ]]
diff --git a/views/projects/layouts-modal.ejs b/views/projects/layouts-modal.ejs
index 34dc9af..0d648cd 100644
--- a/views/projects/layouts-modal.ejs
+++ b/views/projects/layouts-modal.ejs
@@ -3,14 +3,18 @@
<div class="box">
<div class="templates">
- <h1>Edit Room Layouts</h1>
+ <h2>Edit Room Layouts</h2>
+ <div class="templates-list">
+ </div>
+ <form>
+ <input data-role="create-new-blueprint" class="button_text" type="submit" value="Trace a Blueprint">
+ <input data-role="create-new-layout" class="button_text" type="submit" value="Make a Standard Layout">
+ </form>
</div>
<div class="no-templates">
There are no room layouts available. Please <a href="/layout/new">create a new one.</a>
</div>
- <form>
- <input data-role="create-new-layout" class="button_text" type="submit" value="New Layout">
- </form>
+
</div>
</div>
@@ -19,7 +23,9 @@
<div class="box">
<div class="templates">
- <h1>Your Projects</h1>
+ <h2>Your Projects</h2>
+ <div class="templates-list">
+ </div>
</div>
<div class="no-templates">
</div>
@@ -33,8 +39,16 @@
<span class="close">X</span>
<div class="box">
- <h1>Choose Room Template</h1>
<div class="templates">
+ <h2>Select a Room Template</h2>
+
+ <div class="templates-list">
+ </div>
+
+ <form>
+ <input data-role="create-new-blueprint" class="button_text" type="submit" value="trace a blueprint">
+ <input data-role="create-new-layout" class="button_text" type="submit" value="or make your own template">
+ </form>
</div>
<div class="no-templates">
There are no room layouts available. Please <a href="/layout/new">create a new one.</a>
diff --git a/views/projects/list-projects.ejs b/views/projects/list-projects.ejs
index 537d409..2749b0e 100644
--- a/views/projects/list-projects.ejs
+++ b/views/projects/list-projects.ejs
@@ -1,23 +1,39 @@
[[ if (projects.length) { ]]
-
+
<div class="projectList">
[[ projects.forEach(function(project, i) { ]]
-
- <span class="room">
- <iframe src="/project/[[- project.slug ]]/view?noui=1&mute=1" class="embed"></iframe>
- [[ if (String(user._id) == String(project.user_id)) { ]]
- <a href="/project/[[- project.slug ]]/edit"><div class="editBtn">edit</div></a>
- [[ } ]]
- <div class="holder">
- <a href="/project/[[- project.slug ]]" class="roomName">
- [[- project.name ]]<br>
- [[- project.date ]]
- </a>
- </div>
+ [[ if (i > 5) { return } ]]
+ [[ if (String(user._id) == String(project.user_id)) { ]]
+ <a href="/project/[[- project.slug ]]/edit" class="projectItem" data-userid="[[- project.user_id ]]">
+ [[ } else { ]]
+ <a href="/project/[[- project.slug ]]" class="projectItem" data-userid="[[- project.user_id ]]">
+ [[ } ]]
+ <span class="room" style="background-color: rgb([[- project.color ]]);">
+ <span class="mask" style="background-image: url([[- project.photo ]]);">
+ </span>
+ <span class="images" data-mediaCount="[[- Math.min(project.media.length, 4) ]]">
+ [[ mediaCount = 0 ]]
+ [[ project.media.some(function(media){ ]]
+ [[ if (media.media.type != "image") { return false } ]]
+ [[ if (++mediaCount > 4) { return true } ]]
+ <div style="background-image:url([[- media.media.url ]])"></div>
+ [[ }) ]]
+ </span>
</span>
+ <label>
+ [[- project.name ]]<br>
+ Created &ndash; [[- project.date ]]
+ </label>
+
+ </a>
[[ }) ]]
+
+ [[ if (projects.length > 6) { ]]
+ <a href="#" class="viewMore btn">view more</a>
+ [[ } ]]
+
</div>
[[ } ]]
diff --git a/views/reader.ejs b/views/reader.ejs
index ed5df1f..7035356 100644
--- a/views/reader.ejs
+++ b/views/reader.ejs
@@ -1,10 +1,10 @@
<!doctype html>
<html>
<head>
- <title>vvalls</title>
+ <title>VValls</title>
[[ include partials/meta ]]
</head>
-<body class="loading">
+<body class="loading reader">
<div id="scene"></div>
@@ -15,6 +15,11 @@
<div id="editorView">
[[ include controls/reader/about-room ]]
[[ include controls/reader/media-player ]]
+ [[ include controls/reader/embed ]]
+ </div>
+
+ <div id="minimap" class="vvbox" data-intro="Mini-map shows your position and orientation in a room. Navigate with WASD keys or drag here." data-position="top">
+ <span class="el"></span>
</div>
</div>
[[ } ]]
@@ -23,6 +28,8 @@
[[ include projects/layouts-modal ]]
[[ include partials/sign-in ]]
+ <img src="/assets/img/keys.png" id="keyhint">
+ <img src="/assets/img/360.png" id="threesixty">
</body>
[[ include partials/scripts ]]
</html>
diff --git a/views/staff/_blueprints.ejs b/views/staff/_blueprints.ejs
new file mode 100644
index 0000000..58fe2a3
--- /dev/null
+++ b/views/staff/_blueprints.ejs
@@ -0,0 +1,21 @@
+<table id="users">
+[[ blueprints.forEach(function(blueprint){ ]]
+ <tr>
+ <td>
+ <a href="/staff/blueprints/[[- blueprint.slug ]]">[[- blueprint.name ]]</a>
+ </td>
+ <td class="editLinks">
+ <a href="/blueprint/[[- blueprint.slug ]]">[view]</a>
+<!--
+ <a href="/api/rooms/[[- blueprint.slug ]]">[api]</a>
+ -->
+ </td>
+ <td>
+ <a href="/staff/users/[[- blueprint.user.username ]]">[[- blueprint.user.username ]]</a>
+ </td>
+ <td>
+ [[- blueprint.date ]]
+ </td>
+ </tr>
+[[ }) ]]
+</table>
diff --git a/views/staff/_gallery.ejs b/views/staff/_gallery.ejs
new file mode 100644
index 0000000..d5948e3
--- /dev/null
+++ b/views/staff/_gallery.ejs
@@ -0,0 +1,38 @@
+[[ media.forEach(function(media){ ]]
+ <div class="media">
+ [[ if (media.type == "image") { ]]
+ <a class="medialink" href="[[- media.url ]]" target="_blank"><img src="[[- media.url ]]"></a>
+ [[ } else { ]]
+ <a class="medialink" href="[[- media.url ]]" target="_blank">[[- media.shortUrl ]]</a>
+ [[ } ]]
+ <br>
+ <a href="/staff/media/[[- media._id ]]">[view]</a>
+ <a href="/staff/users/[[- media.user.username ]]">[[- media.user.username ]]</a>
+ [[- media.date ]]
+ </div>
+[[ }) ]]
+</table>
+
+<style>
+.media {
+ height: 28vw;
+ width: 24vw;
+ margin: 1vw;
+ display: inline-block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.staff .body a.medialink {
+ width: 24vw;
+ height: 24vw;
+ display: block;
+ overflow: hidden;
+ color: #00f;
+ border: 0;
+ text-decoration: underline;
+}
+.staff .body a.medialink img {
+ max-width: 100%;
+}
+</style> \ No newline at end of file
diff --git a/views/staff/_header.ejs b/views/staff/_header.ejs
index 3bbf4f1..a73c12e 100644
--- a/views/staff/_header.ejs
+++ b/views/staff/_header.ejs
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
- <title>vvalls | staff</title>
+ <title>VValls | staff</title>
[[ include ../partials/meta ]]
<link rel="stylesheet" href="/assets/javascripts/vendor/bower_components/jquery-jsonview/dist/jquery.jsonview.css"></script>
<link rel="stylesheet" href="/assets/stylesheets/staff.css"></script>
diff --git a/views/staff/_layouts.ejs b/views/staff/_layouts.ejs
new file mode 100644
index 0000000..d97883b
--- /dev/null
+++ b/views/staff/_layouts.ejs
@@ -0,0 +1,22 @@
+<table id="users">
+[[ layouts.forEach(function(layout){ ]]
+ <tr>
+ <td>
+ <a href="/staff/layouts/[[- layout.slug ]]">[[- layout.name ]]</a>
+ </td>
+ <td class="editLinks">
+ <a href="/layout/[[- layout.slug ]]">[view]</a>
+ <a href="/layout/[[- layout.slug ]]/edit">[edit]</a>
+<!--
+ <a href="/api/rooms/[[- layout.slug ]]">[api]</a>
+ -->
+ </td>
+ <td>
+ <a href="/staff/users/[[- layout.user.username ]]">[[- layout.user.username ]]</a>
+ </td>
+ <td>
+ [[- layout.date ]]
+ </td>
+ </tr>
+[[ }) ]]
+</table>
diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs
new file mode 100644
index 0000000..702a374
--- /dev/null
+++ b/views/staff/_nav.ejs
@@ -0,0 +1,10 @@
+<nav>
+ <a href="/staff">home</a>
+ <a href="/staff/users">users</a>
+ <a href="/staff/projects">projects</a>
+ <a href="/staff/layouts">layouts</a>
+ <a href="/staff/blueprints">blueprints</a>
+ <a href="/staff/media">media</a>
+ <a href="/staff/plans">plans</a>
+<!-- <a href="/staff/subscriptions">subscriptions</a> -->
+</nav> \ No newline at end of file
diff --git a/views/staff/_pagination.ejs b/views/staff/_pagination.ejs
index 6c3bfb1..7d85c71 100644
--- a/views/staff/_pagination.ejs
+++ b/views/staff/_pagination.ejs
@@ -10,7 +10,7 @@
[[ if (pagination.next_page !== -1) { ]]
<a href="?[[- pagination.query ]]&offset=[[- pagination.next_page ]]">Next page &rarr;</a>
[[ } else { ]]
- &rarr;
+ ->
[[ } ]]
</div>
diff --git a/views/staff/_projects.ejs b/views/staff/_projects.ejs
index 0fdfcf5..2c3eb9f 100644
--- a/views/staff/_projects.ejs
+++ b/views/staff/_projects.ejs
@@ -7,11 +7,10 @@
<td class="editLinks">
<a href="/project/[[- project.slug ]]">[view]</a>
<a href="/project/[[- project.slug ]]/edit">[edit]</a>
+ <a href="/api/rooms/[[- project.slug ]]">[api]</a>
</td>
<td>
- [[ if (project.user) { ]]
<a href="/staff/users/[[- project.user.username ]]">[[- project.user.username ]]</a>
- [[ } ]]
</td>
<td>
[[- project.date ]]
diff --git a/views/staff/_users.ejs b/views/staff/_users.ejs
index d46058f..ee988ab 100644
--- a/views/staff/_users.ejs
+++ b/views/staff/_users.ejs
@@ -1,3 +1,18 @@
+<nav class="subnav">
+ sort by <a href="?sort=date">join date</a> ... <a href="?sort=last_seen">recent</a> ... <a href="?sort=name">name</a> ... jump to a letter:
+ <span class="alphabet">
+ [[ "abcdefghijklmnopqrstuvwxyz?".split("").forEach(function(letter){ ]]
+ <a href="?sort=name&initial=[[- letter ]]">[[- letter.toUpperCase() ]]</a>
+ [[ }) ]]
+ </span>
+</nav>
+
+[[ if (! users.length || opt.error) { ]]
+<div class="error">
+ [[- opt.error ]]
+</div>
+[[ } ]]
+
<table id="users">
[[ users.forEach(function(user){ ]]
<tr>
@@ -5,6 +20,10 @@
<a href="/staff/users/[[- user.username ]]"><div style="background-image:url([[- user.photo ]])" class="avatar"></div></a>
</td>
<td>
+ [[- user.plan_type ]]
+ [[- user.last_charged ]]
+ </td>
+ <td>
<a href="/staff/users/[[- user.username ]]">[[- user.username ]]</a>
</td>
<td>
@@ -12,6 +31,8 @@
</td>
<td class="editLinks">
<a href="/profile/[[- user.username ]]">[view profile]</a>
+ <a href="/staff/users/[[- user.username ]]/media">[view media]</a>
+ <a href="https://vvalls.recurly.com/accounts/[[- user._id ]]">[recurly]</a>
</td>
<td>
[[- user.last_seen ]]
diff --git a/views/staff/blueprints/index.ejs b/views/staff/blueprints/index.ejs
new file mode 100644
index 0000000..2206a1c
--- /dev/null
+++ b/views/staff/blueprints/index.ejs
@@ -0,0 +1,13 @@
+[[ include ../_header ]]
+
+ <h1>Blueprints</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_pagination ]]
+[[ include ../_blueprints ]]
+[[ include ../_pagination ]]
+
+[[ include ../_footer ]]
diff --git a/views/staff/blueprints/show.ejs b/views/staff/blueprints/show.ejs
new file mode 100644
index 0000000..5fd9db6
--- /dev/null
+++ b/views/staff/blueprints/show.ejs
@@ -0,0 +1,59 @@
+[[ include ../_header ]]
+
+ <h1>[[- blueprint.name ]]</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+ <table>
+ <tr>
+ <td>
+ <a href="/staff/blueprints/[[- blueprint.slug ]]">[[- blueprint.name ]]</a>
+ </td>
+ <td class="editLinks">
+ <a href="/blueprint/[[- blueprint.slug ]]">[view]</a>
+ <a href="/blueprint/[[- blueprint.slug ]]/edit">[edit]</a>
+<!--
+ <a href="/api/rooms/[[- blueprint.slug ]]">[api]</a>
+ -->
+ </td>
+ <td>
+ [[- blueprint.date ]]
+ </td>
+ </tr>
+ <tr>
+ <td>
+ [[ if (blueprintUser.photo) { ]]
+ <a href="/staff/users/[[- blueprintUser.username ]]"><div style="background-image:url([[- blueprintUser.photo ]])" class="avatar"></div></a>
+ [[ } ]]
+ <a href="/staff/users/[[- blueprintUser.username ]]">[[- blueprintUser.username ]]</a>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="999">
+ <img src="[[- blueprint.url ]]" style="max-width: 400px">
+ </td>
+ </tr>
+ <tr>
+ <td>Width</td>
+ <td>[[- blueprint.width ]]</td>
+ </tr>
+ <tr>
+ <td>Height</td>
+ <td>[[- blueprint.height ]]</td>
+ </tr>
+ <tr>
+ <td>Scale</td>
+ <td>[[- blueprint.scale ]]</td>
+ </tr>
+ </table>
+
+ <br><br>
+ <div id="actions">
+ </div>
+
+ <br>
+ <br>
+
+[[ include ../_footer ]]
diff --git a/views/staff/blueprints/show_404.ejs b/views/staff/blueprints/show_404.ejs
new file mode 100644
index 0000000..0ffca86
--- /dev/null
+++ b/views/staff/blueprints/show_404.ejs
@@ -0,0 +1,9 @@
+[[ include ../_header ]]
+
+ <h1>Blueprint not found</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_footer ]]
diff --git a/views/staff/index.ejs b/views/staff/index.ejs
index 5ca7269..1b73641 100644
--- a/views/staff/index.ejs
+++ b/views/staff/index.ejs
@@ -2,11 +2,7 @@
<h1>Staff Area</h1>
- <nav>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+ [[ include _nav ]]
<hr>
diff --git a/views/staff/layouts/index.ejs b/views/staff/layouts/index.ejs
new file mode 100644
index 0000000..71f5dc7
--- /dev/null
+++ b/views/staff/layouts/index.ejs
@@ -0,0 +1,13 @@
+[[ include ../_header ]]
+
+ <h1>Layouts</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_pagination ]]
+[[ include ../_layouts ]]
+[[ include ../_pagination ]]
+
+[[ include ../_footer ]]
diff --git a/views/staff/layouts/show.ejs b/views/staff/layouts/show.ejs
new file mode 100644
index 0000000..2742c1f
--- /dev/null
+++ b/views/staff/layouts/show.ejs
@@ -0,0 +1,61 @@
+[[ include ../_header ]]
+
+ <h1>[[- layout.name ]]</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+ <table>
+ <tr>
+ <td>
+ <a href="/staff/layouts/[[- layout.slug ]]">[[- layout.name ]]</a>
+ </td>
+ <td class="editLinks">
+ <a href="/layout/[[- layout.slug ]]">[view]</a>
+ <a href="/layout/[[- layout.slug ]]/edit">[edit]</a>
+<!--
+ <a href="/api/rooms/[[- layout.slug ]]">[api]</a>
+ -->
+ </td>
+ <td>
+ [[- layout.date ]]
+ </td>
+<!--
+ <td>
+ [[- layout.privacy ? "private" : "" ]]
+ </td>
+ -->
+ </tr>
+ <tr>
+ <td>
+ [[ if (layoutUser.photo) { ]]
+ <a href="/staff/users/[[- layoutUser.username ]]"><div style="background-image:url([[- layoutUser.photo ]])" class="avatar"></div></a>
+ [[ } ]]
+ <a href="/staff/users/[[- layoutUser.username ]]">[[- layoutUser.username ]]</a>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="999" class="description">
+ "[[- layout.description ]]"
+ </td>
+ </tr>
+ <tr>
+ <th>
+ stock layout?
+ </th>
+ <td id="isStockLayout">
+ [[- layout.is_stock ? "yes" : "no" ]]
+ </td>
+ </tr>
+ </table>
+
+ <br><br>
+ <div id="actions">
+ <button id="toggle-stock" data-stock="[[- !! (layout.is_stock) ]]">Make this layout Stock</button>
+ </div>
+
+ <br>
+ <br>
+
+[[ include ../_footer ]]
diff --git a/views/staff/layouts/show_404.ejs b/views/staff/layouts/show_404.ejs
new file mode 100644
index 0000000..5d24aa8
--- /dev/null
+++ b/views/staff/layouts/show_404.ejs
@@ -0,0 +1,9 @@
+[[ include ../_header ]]
+
+ <h1>Layout not found</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_footer ]]
diff --git a/views/staff/media/index.ejs b/views/staff/media/index.ejs
index 516af2d..3805c8e 100644
--- a/views/staff/media/index.ejs
+++ b/views/staff/media/index.ejs
@@ -2,12 +2,7 @@
<h1>Media</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/media/show.ejs b/views/staff/media/show.ejs
index 76dcd32..9d05cb9 100644
--- a/views/staff/media/show.ejs
+++ b/views/staff/media/show.ejs
@@ -2,12 +2,7 @@
<h1>Media: [[- media.type ]]</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/media/show_404.ejs b/views/staff/media/show_404.ejs
index f07cef2..c6bac6f 100644
--- a/views/staff/media/show_404.ejs
+++ b/views/staff/media/show_404.ejs
@@ -2,13 +2,8 @@
<h1>Media not found</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
-
+[[ include ../_nav ]]
+
<hr>
[[ include ../_footer ]]
diff --git a/views/staff/plans/_form.ejs b/views/staff/plans/_form.ejs
new file mode 100644
index 0000000..85375fa
--- /dev/null
+++ b/views/staff/plans/_form.ejs
@@ -0,0 +1,154 @@
+<input type="hidden" id="_csrf" name="_csrf" value="[[- token ]]">
+
+<ul>
+
+<li class="section_break">
+ <h3>New Plan</h3>
+</li>
+
+<li>
+ <label for="plan_name">Name</label>
+ <div><input id="plan_name" name="name" type="text" value="[[- plan.name ]]"></div>
+</li>
+
+<li>
+ <label for="plan_slug">Slug</label>
+ <div><input id="plan_slug" name="slug" type="text" value="[[- plan.slug ]]"></div>
+</li>
+
+<li>
+ <label for="plan_level">Level</label>
+ <div><input id="plan_level" name="level" type="number" min="0" value="[[- plan.level ]]"></div>
+</li>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Plan Pricing</h3>
+</li>
+
+<li>
+ <label for="plan_monthly_price">Monthly Price</label>
+ <div><input id="plan_monthly_price" name="monthly_price" type="number" min="0" value="[[- plan.monthly_price ]]"></div>
+</li>
+
+<li>
+ <label for="plan_yearly_price">Yearly Price</label>
+ <div><input id="plan_yearly_price" name="yearly_price" type="number" min="0" value="[[- plan.yearly_price ]]"></div>
+</li>
+
+<p>
+ <i>Note:</i> Pricing should be in cents, i.e. a price of $10.00 should be entered as 1000.
+</p>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Additional Template Pricing</h3>
+</li>
+
+<li>
+ <label for="plan_basic_layout_monthly_price">Basic Template Price (Monthly)</label>
+ <div><input id="plan_basic_layout_monthly_price" name="basic_layout_monthly_price" type="number" min="0" value="[[- plan.basic_layout_monthly_price ]]"></div>
+</li>
+
+<li>
+ <label for="plan_basic_layout_yearly_price">Basic Template Price (Yearly)</label>
+ <div><input id="plan_basic_layout_yearly_price" name="basic_layout_yearly_price" type="number" min="0" value="[[- plan.basic_layout_yearly_price ]]"></div>
+</li>
+
+<li>
+ <label for="plan_pro_layout_monthly_price">Pro Template Price (Monthly)</label>
+ <div><input id="plan_pro_layout_monthly_price" name="pro_layout_monthly_price" type="number" min="0" value="[[- plan.pro_layout_monthly_price ]]"></div>
+</li>
+
+<li>
+ <label for="plan_pro_layout_yearly_price">Pro Template Price (Yearly)</label>
+ <div><input id="plan_pro_layout_yearly_price" name="pro_layout_yearly_price" type="number" min="0" value="[[- plan.pro_layout_yearly_price ]]"></div>
+</li>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Per-Plan Template Limits</h3>
+</li>
+
+<li>
+ <label for="plan_basic_layout_limit">Basic Template Limit</label>
+ <div><input id="plan_basic_layout_limit" name="basic_layout_limit" type="number" min="0" value="[[- plan.basic_layout_limit ]]"></div>
+</li>
+
+<li>
+ <label for="plan_pro_layout_limit">Pro Template Limit</label>
+ <div><input id="plan_pro_layout_limit" name="pro_layout_limit" type="number" min="0" value="[[- plan.pro_layout_limit ]]"></div>
+</li>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Per-Plan Project Limits</h3>
+</li>
+
+<li>
+ <label for="plan_stock_project_limit">Stock Project Limit</label>
+ <div><input id="plan_stock_project_limit" name="stock_project_limit" type="number" min="0" value="[[- plan.stock_project_limit ]]"></div>
+</li>
+
+<li>
+ <label for="plan_basic_project_limit">Basic Project Limit</label>
+ <div><input id="plan_basic_project_limit" name="basic_project_limit" type="number" min="0" value="[[- plan.basic_project_limit ]]"></div>
+</li>
+
+<li>
+ <label for="plan_pro_project_limit">Pro Project Limit</label>
+ <div><input id="plan_pro_project_limit" name="pro_project_limit" type="number" min="0" value="[[- plan.pro_project_limit ]]"></div>
+</li>
+
+<!-- - - - - -->
+
+<li class="section_break">
+ <h3>Permissions</h3>
+</li>
+
+<div>
+<li>
+ <input name="permissions_basic_editor" type="hidden" value="0">
+ <input id="plan_permissions_basic_editor" name="permissions_basic_editor" type="checkbox" value="1" [[ if (plan.permissions.basic_editor) { ]]checked[[ } ]]>
+ <label for="plan_permissions_basic_editor">Basic Editor</label>
+</li>
+
+<li>
+ <input name="permissions_pro_editor" type="hidden" value="0">
+ <input id="plan_permissions_pro_editor" name="permissions_pro_editor" type="checkbox" value="1" [[ if (plan.permissions.pro_editor) { ]]checked[[ } ]]>
+ <label for="plan_permissions_pro_editor">Pro Editor</label>
+</li>
+
+<li>
+ <input name="permissions_sculpture" type="hidden" value="0">
+ <input id="plan_permissions_sculpture" name="permissions_sculpture" type="checkbox" value="1" [[ if (plan.permissions.sculpture) { ]]checked[[ } ]]>
+ <label for="plan_permissions_sculpture">3D Objects</label>
+</li>
+
+<li>
+ <input name="permissions_collaborators" type="hidden" value="0">
+ <input id="plan_permissions_collaborators" name="permissions_collaborators" type="checkbox" value="1" [[ if (plan.permissions.collaborators) { ]]checked[[ } ]]>
+ <label for="plan_permissions_collaborators">Collaborators</label>
+</li>
+
+<li>
+ <input name="permissions_no_logo" type="hidden" value="0">
+ <input id="plan_permissions_no_logo" name="permissions_no_logo" type="checkbox" value="1" [[ if (plan.permissions.no_logo) { ]]checked[[ } ]]>
+ <label for="plan_permissions_no_logo">No Logo</label>
+</li>
+
+<p>
+ These permissions should harmonize with the restrictions on layouts set above.
+</p>
+
+</div>
+
+<li>
+ <input type="submit" value="Save Changes">
+</li>
+
+</ul>
diff --git a/views/staff/plans/edit.ejs b/views/staff/plans/edit.ejs
new file mode 100644
index 0000000..9848873
--- /dev/null
+++ b/views/staff/plans/edit.ejs
@@ -0,0 +1,13 @@
+[[ include ../_header ]]
+
+ <h1>Edit Plan</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+<form action="" method="post">
+[[- include _form ]]
+</form>
+
+[[ include ../_footer ]]
diff --git a/views/staff/plans/index.ejs b/views/staff/plans/index.ejs
new file mode 100644
index 0000000..16fcf14
--- /dev/null
+++ b/views/staff/plans/index.ejs
@@ -0,0 +1,65 @@
+[[ include ../_header ]]
+
+ <h1>Plans</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+<table>
+ <tr>
+ <td>
+ </td>
+ [[ plans.forEach(function(plan){ ]]
+ <td style="text-align:right; min-width: 100px;">
+ <b style="text-transform:uppercase">[[- plan.name ]]</b>
+ </td>
+ [[ }) ]]
+ </tr>
+
+ <tr class="editLinks">
+ <td>
+ <a href="/staff/plans/new">New Plan</a>
+ </td>
+ [[ plans.forEach(function(plan){ ]]
+ <td style="text-align:right">
+ [<a href="/staff/plans/[[- plan.slug ]]">edit</a>]
+ </td>
+ [[ }) ]]
+ </tr>
+
+ [[ fields.forEach(function(field){ ]]
+ <tr>
+ <td style="text-transform:capitalize">[[- field.replace(/_/g," ") ]]</td>
+ [[ plans.forEach(function(plan){ ]]
+ <td style="text-align:right">
+ [[ if (field.indexOf("_price") != -1) { ]]
+ [[- plan[field] == 0 ? "" : "$" + (plan[field]/100).toFixed(2) ]]
+ [[ } else { ]]
+ [[- plan[field] ]]
+ [[ } ]]
+ </td>
+ [[ }) ]]
+ </tr>
+ [[ }) ]]
+
+ <tr>
+ <td style="border-bottom: 1px dotted #888;" colspan='10'></td>
+ </tr>
+
+ [[ permissions.forEach(function(permission){ ]]
+ <tr>
+ <td style="text-transform:capitalize">[[- permission.replace(/_/g," ") ]]</td>
+ [[ plans.forEach(function(plan){ ]]
+ <td style="text-align:right">
+ [[- plan.permissions[permission] ? "<b>x</b>" : " " ]]
+ </td>
+ [[ }) ]]
+ </tr>
+ [[ }) ]]
+</table>
+<br clear="all">
+
+ <hr>
+
+[[ include ../_footer ]]
diff --git a/views/staff/plans/new.ejs b/views/staff/plans/new.ejs
new file mode 100644
index 0000000..297d3d6
--- /dev/null
+++ b/views/staff/plans/new.ejs
@@ -0,0 +1,13 @@
+[[ include ../_header ]]
+
+ <h1>New Plan</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+<form action="" method="post">
+[[- include _form ]]
+</form>
+
+[[ include ../_footer ]]
diff --git a/views/staff/projects/index.ejs b/views/staff/projects/index.ejs
index 482ea25..e4ba469 100644
--- a/views/staff/projects/index.ejs
+++ b/views/staff/projects/index.ejs
@@ -2,12 +2,7 @@
<h1>Projects</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/projects/show.ejs b/views/staff/projects/show.ejs
index 687f0c2..b090a41 100644
--- a/views/staff/projects/show.ejs
+++ b/views/staff/projects/show.ejs
@@ -2,13 +2,8 @@
<h1>[[- project.name ]]</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
-
+[[ include ../_nav ]]
+
<hr>
<table>
@@ -41,8 +36,21 @@
"[[- project.description ]]"
</td>
</tr>
+ <tr>
+ <th>
+ featured?
+ </th>
+ <td id="isFeaturedProject">
+ [[- project.featured ? "yes" : "no" ]]
+ </td>
+ </tr>
</table>
+ <br><br>
+ <div id="actions">
+ <button id="toggle-featured" data-featured="[[- !! project.featured ]]">Feature this Project</button>
+ </div>
+
<br>
<br>
<table id="iframe-embed" class="projectList">
diff --git a/views/staff/projects/show_404.ejs b/views/staff/projects/show_404.ejs
index 70320c0..f5e1658 100644
--- a/views/staff/projects/show_404.ejs
+++ b/views/staff/projects/show_404.ejs
@@ -2,12 +2,7 @@
<h1>Project not found</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/subscriptions/index.ejs b/views/staff/subscriptions/index.ejs
new file mode 100644
index 0000000..adf148c
--- /dev/null
+++ b/views/staff/subscriptions/index.ejs
@@ -0,0 +1,39 @@
+[[ include ../_header ]]
+
+ <h1>Subscriptions</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+[[ include ../_pagination ]]
+
+<table id="users">
+[[ subscriptions.forEach(function(subscription){ ]]
+ <tr>
+ <td>
+ <a href="/staff/subscriptions/[[- subscription._id ]]"><div style="background-image:url([[- subscription.user.photo ]])" class="avatar"></div></a>
+ </td>
+ <td>
+ <a href="/staff/subscriptions/[[- subscription._id ]]">[[- subscription.user.username ]]</a>
+ </td>
+ <td>
+ [[- subscription.user.displayName ]]
+ </td>
+ <td class="editLinks">
+ <a href="/profile/[[- user.username ]]">[view profile]</a>
+ </td>
+ <td>
+ [[- subscription.user.last_seen ]]
+ </td>
+ <td>
+ [[- subscription.plan_code ]]
+ </td>
+ </tr>
+[[ }) ]]
+</table>
+
+
+[[ include ../_pagination ]]
+
+[[ include ../_footer ]]
diff --git a/views/staff/subscriptions/show.ejs b/views/staff/subscriptions/show.ejs
new file mode 100644
index 0000000..e2839a6
--- /dev/null
+++ b/views/staff/subscriptions/show.ejs
@@ -0,0 +1,12 @@
+[[ include ../_header ]]
+ <h1>User: [[- subscription.user.username ]]</h1>
+
+[[ include ../_nav ]]
+
+ <hr>
+
+<pre>
+info to show..
+- link to recurly profile
+- link to vvalls profile
+- subscription tier + add-ons
diff --git a/views/staff/users/index.ejs b/views/staff/users/index.ejs
index f14d666..1795dde 100644
--- a/views/staff/users/index.ejs
+++ b/views/staff/users/index.ejs
@@ -2,12 +2,7 @@
<h1>Users</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
diff --git a/views/staff/users/media.ejs b/views/staff/users/media.ejs
index b13e5fb..8927c00 100644
--- a/views/staff/users/media.ejs
+++ b/views/staff/users/media.ejs
@@ -1,18 +1,13 @@
[[ include ../_header ]]
- <h1>Users</h1>
+<h1>User Media: [[- profile.username ]]</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
-
- <hr>
+[[ include ../_nav ]]
+
+<hr>
[[ include ../_pagination ]]
-[[ include ../_media ]]
+[[ include ../_gallery ]]
[[ include ../_pagination ]]
[[ include ../_footer ]]
diff --git a/views/staff/users/show.ejs b/views/staff/users/show.ejs
index 8e9b447..a434b57 100644
--- a/views/staff/users/show.ejs
+++ b/views/staff/users/show.ejs
@@ -1,12 +1,7 @@
[[ include ../_header ]]
<h1>User: [[- profile.username ]]</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
+[[ include ../_nav ]]
<hr>
@@ -22,12 +17,38 @@
[[- profile.displayName ]]
</td>
<td class="editLinks">
- <a href="/profile/[[- profile.username ]]">[view profile]</a>
- <a href="/staff/users/[[- profile.username ]]/media">[view media]</a>
+ <a href="/profile/[[- profile.username ]]">[profile]</a>
+ <a href="/staff/users/[[- profile.username ]]/media">[media]</a>
+ [[ if (profile.subscription) { ]]
+ <a href="https://vvalls.recurly.com/accounts/[[- profile._id ]]">[recurly]</a>
+ [[ } ]]
</td>
</tr>
</table>
+
+ [[ if (profile.subscription) { ]]
+ <h2>Subscription</h2>
+ <table>
+ <tr>
+ <th>
+ plan
+ </th>
+ <td>
+ [[- profile.plan_code ]]
+ </td>
+ </tr>
+ <tr>
+ <th>
+ last charged
+ </th>
+ <td>
+ [[- profile.last_charged ]]
+ </td>
+ </tr>
+ </table>
+ [[ } ]]
+
<h2>Profile</h2>
<table>
@@ -80,12 +101,21 @@
[[- profile.isStaff ? "yes" : "no" ]]
</td>
</tr>
+ <tr>
+ <th>
+ is artist?
+ </th>
+ <td id="is-artist">
+ [[- profile.isArtist ? "yes" : "no" ]]
+ </td>
+ </tr>
</table>
<br><br>
<div id="actions">
[[ if (String(user._id) != String(profile._id)) { ]]
<button id="toggle-staff" data-isStaff="[[- !! profile.isStaff ]]">Make Staff</button>
+ <button id="toggle-artist" data-isArtist="[[- !! profile.isArtist ]]">Make Artist</button>
[[ } ]]
</div>
diff --git a/views/staff/users/show_404.ejs b/views/staff/users/show_404.ejs
index bcd0271..11663fa 100644
--- a/views/staff/users/show_404.ejs
+++ b/views/staff/users/show_404.ejs
@@ -1,13 +1,9 @@
[[ include ../_header ]]
- <h1>User not found</h1>
- <nav>
- <a href="/staff">home</a>
- <a href="/staff/users">users</a>
- <a href="/staff/projects">projects</a>
- <a href="/staff/media">media</a>
- </nav>
-
- <hr>
+<h1>User not found</h1>
+
+[[ include ../_nav ]]
+
+<hr>
[[ include ../_footer ]]