├── README.md ├── css ├── bootstrap-theme.css ├── bootstrap-theme.min.css ├── bootstrap.css ├── bootstrap.min.css ├── font-awesome.min.css ├── jquery-ui.css ├── jquery-ui.min.css ├── jquery-ui.structure.css ├── jquery-ui.structure.min.css ├── normalize.css ├── style.css └── viewer.css ├── fonts ├── FontAwesome.otf ├── fontawesome-webfont.eot ├── fontawesome-webfont.svg ├── fontawesome-webfont.ttf ├── fontawesome-webfont.woff ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf └── glyphicons-halflings-regular.woff ├── images ├── closedhand.cur ├── openhand.cur ├── pencil.cur └── zoom.cur ├── index.html ├── js ├── coffee │ ├── app-view.coffee │ ├── app.coffee │ ├── common.coffee │ ├── editor.coffee │ ├── model.coffee │ ├── samples.coffee │ ├── svg-render.coffee │ ├── template.coffee │ ├── text-import.coffee │ ├── text-render.coffee │ ├── themes.coffee │ ├── utils.coffee │ └── viewer.coffee ├── compiled │ ├── app-view.js │ ├── app.js │ ├── common.js │ ├── editor.js │ ├── model.js │ ├── samples.js │ ├── svg-render.js │ ├── template.js │ ├── text-import.js │ ├── text-render.js │ ├── themes.js │ ├── utils.js │ └── viewer.js ├── libs-min │ ├── bootstrap.js │ ├── jquery-ui.js │ ├── jquery.js │ ├── jquery.mousewheel.js │ ├── jquery.scrollintoview.js │ ├── jquery2.js │ ├── ractive.js │ ├── svg.export.js │ ├── svg.filter.js │ └── svg.js └── libs │ ├── bootstrap.js │ ├── jquery-ui.js │ ├── jquery.js │ ├── jquery.mousewheel.js │ ├── jquery.scrollintoview.js │ ├── jquery2.js │ ├── ractive.js │ ├── svg.export.js │ ├── svg.filter.js │ └── svg.js └── view.html /README.md: -------------------------------------------------------------------------------- 1 | # Тектограф 2 | 3 | ## Формат 4 | *Тектограмма* (_системная карта_) — это новый формат представления структурированной информации. 5 | Может использоваться для конспектирования, систематизации мыслей, моделирования программ и процессов, планирования статей, 6 | презентаций, выступлений — всего, что имеет иерархическую структуру. 7 | 8 | Тектограмма рисуется «слоями», от высшего иерархического уровня к низшим. 9 | Размер шрифта и толщина линий на соседних иерархических уровнях отличается в 1,5−2,5 раза. 10 | Элемент высшего иерархического уровня всегда находится выше и задает расположение элементов нижнего иерархического уровня. 11 | Каждый элемент включает заголовок, описание (возможно с изображением) и структуру из вложенных элементов. 12 | Есть несколько вариантов структуры: списки, матрица, граф. 13 | 14 | ## Редактор 15 | [_Тектограф_](http://leonidovcharenko.github.com/tectograph) — программа для создания тектограмм. 16 | Позволяет редактировать только содержание системной карты глубиной до 7 уровней, отображая её в одном из предустановленных стилей. 17 | Созданные схемы можно сохранять в localStorage, экспортировать в форматах JSON (исходный код), SVG, PNG, TXT, HTML, XML. 18 | 19 | Есть «упрощенный редактор», в котором вся система представлена в текстовом виде в одном поле. 20 | В нем отсутствуют способы форматирования структуры, однако в нем можно фиксировать мысли «в потоке» и не тратить время на оформление. 21 | Удобно накидать систему в целом, затем понемногу править отдельные элементы. 22 | 23 | Работают горячие клавиши, отмена/возврат действий, автосохранение. 24 | 25 | Программа не требует серверной части. 26 | 27 | ## Просмотр 28 | Поделиться схемой (предварительно сохраненной в формате JSON), в том числе встроить на страницу через iframe, 29 | можно с помощью [просмотрщика](http://leonidovcharenko.github.com/tectograph/view) (не требует серверной поддержки). 30 | 31 | Ссылка для просмотра тектограммы: `http://leonidovcharenko.github.com/tectograph/view#прямая-ссылка-на-json-файл##N`, где `N` — код стиля, число от 0 до 6. 32 | 33 | Примеры: [№1](http://leonidovcharenko.github.io/tectograph/view#https://dl.dropboxusercontent.com/s/1o2ne7gxvbu5us3/25-point_website_usability_checklist.json?dl=0##2), 34 | [№2](http://leonidovcharenko.github.io/tectograph/view#https://dl.dropboxusercontent.com/s/qlo8yjt8j1g017c/text-for-reading.json?dl=0?dl=0##0), 35 | [№3](http://leonidovcharenko.github.io/tectograph/view#https://dl.dropboxusercontent.com/s/jkzv0zvse1r1tjd/user-iterface.json?dl=0##1) 36 | -------------------------------------------------------------------------------- /css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.2.0 (http://getbootstrap.com) 3 | * Copyright 2011-2014 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:-o-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#2d6ca2));background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-primary:disabled,.btn-primary[disabled]{background-color:#2d6ca2;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-o-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#357ebd));background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f3f3f3));background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:-o-linear-gradient(top,#222 0,#282828 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#222),to(#282828));background-image:linear-gradient(to bottom,#222 0,#282828 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:-o-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#3071a9));background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:-o-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#3278b3));background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);background-repeat:repeat-x;border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-o-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#357ebd));background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} -------------------------------------------------------------------------------- /css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"} -------------------------------------------------------------------------------- /css/jquery-ui.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.1 - 2014-10-15 2 | * http://jqueryui.com 3 | * Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, slider.css 4 | * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ 5 | 6 | /* Layout helpers 7 | ----------------------------------*/ 8 | .ui-helper-hidden { 9 | display: none; 10 | } 11 | .ui-helper-hidden-accessible { 12 | border: 0; 13 | clip: rect(0 0 0 0); 14 | height: 1px; 15 | margin: -1px; 16 | overflow: hidden; 17 | padding: 0; 18 | position: absolute; 19 | width: 1px; 20 | } 21 | .ui-helper-reset { 22 | margin: 0; 23 | padding: 0; 24 | border: 0; 25 | outline: 0; 26 | line-height: 1.3; 27 | text-decoration: none; 28 | font-size: 100%; 29 | list-style: none; 30 | } 31 | .ui-helper-clearfix:before, 32 | .ui-helper-clearfix:after { 33 | content: ""; 34 | display: table; 35 | border-collapse: collapse; 36 | } 37 | .ui-helper-clearfix:after { 38 | clear: both; 39 | } 40 | .ui-helper-clearfix { 41 | min-height: 0; /* support: IE7 */ 42 | } 43 | .ui-helper-zfix { 44 | width: 100%; 45 | height: 100%; 46 | top: 0; 47 | left: 0; 48 | position: absolute; 49 | opacity: 0; 50 | filter:Alpha(Opacity=0); /* support: IE8 */ 51 | } 52 | 53 | .ui-front { 54 | z-index: 100; 55 | } 56 | 57 | 58 | /* Interaction Cues 59 | ----------------------------------*/ 60 | .ui-state-disabled { 61 | cursor: default !important; 62 | } 63 | 64 | 65 | /* Icons 66 | ----------------------------------*/ 67 | 68 | /* states and images */ 69 | .ui-icon { 70 | display: block; 71 | text-indent: -99999px; 72 | overflow: hidden; 73 | background-repeat: no-repeat; 74 | } 75 | 76 | 77 | /* Misc visuals 78 | ----------------------------------*/ 79 | 80 | /* Overlays */ 81 | .ui-widget-overlay { 82 | position: fixed; 83 | top: 0; 84 | left: 0; 85 | width: 100%; 86 | height: 100%; 87 | } 88 | .ui-draggable-handle { 89 | -ms-touch-action: none; 90 | touch-action: none; 91 | } 92 | .ui-resizable { 93 | position: relative; 94 | } 95 | .ui-resizable-handle { 96 | position: absolute; 97 | font-size: 0.1px; 98 | display: block; 99 | -ms-touch-action: none; 100 | touch-action: none; 101 | } 102 | .ui-resizable-disabled .ui-resizable-handle, 103 | .ui-resizable-autohide .ui-resizable-handle { 104 | display: none; 105 | } 106 | .ui-resizable-n { 107 | cursor: n-resize; 108 | height: 7px; 109 | width: 100%; 110 | top: -5px; 111 | left: 0; 112 | } 113 | .ui-resizable-s { 114 | cursor: s-resize; 115 | height: 7px; 116 | width: 100%; 117 | bottom: -5px; 118 | left: 0; 119 | } 120 | .ui-resizable-e { 121 | cursor: e-resize; 122 | width: 7px; 123 | right: -5px; 124 | top: 0; 125 | height: 100%; 126 | } 127 | .ui-resizable-w { 128 | cursor: w-resize; 129 | width: 7px; 130 | left: -5px; 131 | top: 0; 132 | height: 100%; 133 | } 134 | .ui-resizable-se { 135 | cursor: se-resize; 136 | width: 12px; 137 | height: 12px; 138 | right: 1px; 139 | bottom: 1px; 140 | } 141 | .ui-resizable-sw { 142 | cursor: sw-resize; 143 | width: 9px; 144 | height: 9px; 145 | left: -5px; 146 | bottom: -5px; 147 | } 148 | .ui-resizable-nw { 149 | cursor: nw-resize; 150 | width: 9px; 151 | height: 9px; 152 | left: -5px; 153 | top: -5px; 154 | } 155 | .ui-resizable-ne { 156 | cursor: ne-resize; 157 | width: 9px; 158 | height: 9px; 159 | right: -5px; 160 | top: -5px; 161 | } 162 | .ui-selectable { 163 | -ms-touch-action: none; 164 | touch-action: none; 165 | } 166 | .ui-selectable-helper { 167 | position: absolute; 168 | z-index: 100; 169 | border: 1px dotted black; 170 | } 171 | .ui-sortable-handle { 172 | -ms-touch-action: none; 173 | touch-action: none; 174 | } 175 | .ui-slider { 176 | position: relative; 177 | text-align: left; 178 | } 179 | .ui-slider .ui-slider-handle { 180 | position: absolute; 181 | z-index: 2; 182 | width: 1.2em; 183 | height: 1.2em; 184 | cursor: default; 185 | -ms-touch-action: none; 186 | touch-action: none; 187 | } 188 | .ui-slider .ui-slider-range { 189 | position: absolute; 190 | z-index: 1; 191 | font-size: .7em; 192 | display: block; 193 | border: 0; 194 | background-position: 0 0; 195 | } 196 | 197 | /* support: IE8 - See #6727 */ 198 | .ui-slider.ui-state-disabled .ui-slider-handle, 199 | .ui-slider.ui-state-disabled .ui-slider-range { 200 | filter: inherit; 201 | } 202 | 203 | .ui-slider-horizontal { 204 | height: .8em; 205 | } 206 | .ui-slider-horizontal .ui-slider-handle { 207 | top: -.3em; 208 | margin-left: -.6em; 209 | } 210 | .ui-slider-horizontal .ui-slider-range { 211 | top: 0; 212 | height: 100%; 213 | } 214 | .ui-slider-horizontal .ui-slider-range-min { 215 | left: 0; 216 | } 217 | .ui-slider-horizontal .ui-slider-range-max { 218 | right: 0; 219 | } 220 | 221 | .ui-slider-vertical { 222 | width: .8em; 223 | height: 100px; 224 | } 225 | .ui-slider-vertical .ui-slider-handle { 226 | left: -.3em; 227 | margin-left: 0; 228 | margin-bottom: -.6em; 229 | } 230 | .ui-slider-vertical .ui-slider-range { 231 | left: 0; 232 | width: 100%; 233 | } 234 | .ui-slider-vertical .ui-slider-range-min { 235 | bottom: 0; 236 | } 237 | .ui-slider-vertical .ui-slider-range-max { 238 | top: 0; 239 | } 240 | -------------------------------------------------------------------------------- /css/jquery-ui.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.1 - 2014-10-15 2 | * http://jqueryui.com 3 | * Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, slider.css 4 | * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ 5 | 6 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0} -------------------------------------------------------------------------------- /css/jquery-ui.structure.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.11.1 3 | * http://jqueryui.com 4 | * 5 | * Copyright 2014 jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | */ 11 | 12 | /* Layout helpers 13 | ----------------------------------*/ 14 | .ui-helper-hidden { 15 | display: none; 16 | } 17 | .ui-helper-hidden-accessible { 18 | border: 0; 19 | clip: rect(0 0 0 0); 20 | height: 1px; 21 | margin: -1px; 22 | overflow: hidden; 23 | padding: 0; 24 | position: absolute; 25 | width: 1px; 26 | } 27 | .ui-helper-reset { 28 | margin: 0; 29 | padding: 0; 30 | border: 0; 31 | outline: 0; 32 | line-height: 1.3; 33 | text-decoration: none; 34 | font-size: 100%; 35 | list-style: none; 36 | } 37 | .ui-helper-clearfix:before, 38 | .ui-helper-clearfix:after { 39 | content: ""; 40 | display: table; 41 | border-collapse: collapse; 42 | } 43 | .ui-helper-clearfix:after { 44 | clear: both; 45 | } 46 | .ui-helper-clearfix { 47 | min-height: 0; /* support: IE7 */ 48 | } 49 | .ui-helper-zfix { 50 | width: 100%; 51 | height: 100%; 52 | top: 0; 53 | left: 0; 54 | position: absolute; 55 | opacity: 0; 56 | filter:Alpha(Opacity=0); /* support: IE8 */ 57 | } 58 | 59 | .ui-front { 60 | z-index: 100; 61 | } 62 | 63 | 64 | /* Interaction Cues 65 | ----------------------------------*/ 66 | .ui-state-disabled { 67 | cursor: default !important; 68 | } 69 | 70 | 71 | /* Icons 72 | ----------------------------------*/ 73 | 74 | /* states and images */ 75 | .ui-icon { 76 | display: block; 77 | text-indent: -99999px; 78 | overflow: hidden; 79 | background-repeat: no-repeat; 80 | } 81 | 82 | 83 | /* Misc visuals 84 | ----------------------------------*/ 85 | 86 | /* Overlays */ 87 | .ui-widget-overlay { 88 | position: fixed; 89 | top: 0; 90 | left: 0; 91 | width: 100%; 92 | height: 100%; 93 | } 94 | .ui-draggable-handle { 95 | -ms-touch-action: none; 96 | touch-action: none; 97 | } 98 | .ui-resizable { 99 | position: relative; 100 | } 101 | .ui-resizable-handle { 102 | position: absolute; 103 | font-size: 0.1px; 104 | display: block; 105 | -ms-touch-action: none; 106 | touch-action: none; 107 | } 108 | .ui-resizable-disabled .ui-resizable-handle, 109 | .ui-resizable-autohide .ui-resizable-handle { 110 | display: none; 111 | } 112 | .ui-resizable-n { 113 | cursor: n-resize; 114 | height: 7px; 115 | width: 100%; 116 | top: -5px; 117 | left: 0; 118 | } 119 | .ui-resizable-s { 120 | cursor: s-resize; 121 | height: 7px; 122 | width: 100%; 123 | bottom: -5px; 124 | left: 0; 125 | } 126 | .ui-resizable-e { 127 | cursor: e-resize; 128 | width: 7px; 129 | right: -5px; 130 | top: 0; 131 | height: 100%; 132 | } 133 | .ui-resizable-w { 134 | cursor: w-resize; 135 | width: 7px; 136 | left: -5px; 137 | top: 0; 138 | height: 100%; 139 | } 140 | .ui-resizable-se { 141 | cursor: se-resize; 142 | width: 12px; 143 | height: 12px; 144 | right: 1px; 145 | bottom: 1px; 146 | } 147 | .ui-resizable-sw { 148 | cursor: sw-resize; 149 | width: 9px; 150 | height: 9px; 151 | left: -5px; 152 | bottom: -5px; 153 | } 154 | .ui-resizable-nw { 155 | cursor: nw-resize; 156 | width: 9px; 157 | height: 9px; 158 | left: -5px; 159 | top: -5px; 160 | } 161 | .ui-resizable-ne { 162 | cursor: ne-resize; 163 | width: 9px; 164 | height: 9px; 165 | right: -5px; 166 | top: -5px; 167 | } 168 | .ui-selectable { 169 | -ms-touch-action: none; 170 | touch-action: none; 171 | } 172 | .ui-selectable-helper { 173 | position: absolute; 174 | z-index: 100; 175 | border: 1px dotted black; 176 | } 177 | .ui-sortable-handle { 178 | -ms-touch-action: none; 179 | touch-action: none; 180 | } 181 | .ui-slider { 182 | position: relative; 183 | text-align: left; 184 | } 185 | .ui-slider .ui-slider-handle { 186 | position: absolute; 187 | z-index: 2; 188 | width: 1.2em; 189 | height: 1.2em; 190 | cursor: default; 191 | -ms-touch-action: none; 192 | touch-action: none; 193 | } 194 | .ui-slider .ui-slider-range { 195 | position: absolute; 196 | z-index: 1; 197 | font-size: .7em; 198 | display: block; 199 | border: 0; 200 | background-position: 0 0; 201 | } 202 | 203 | /* support: IE8 - See #6727 */ 204 | .ui-slider.ui-state-disabled .ui-slider-handle, 205 | .ui-slider.ui-state-disabled .ui-slider-range { 206 | filter: inherit; 207 | } 208 | 209 | .ui-slider-horizontal { 210 | height: .8em; 211 | } 212 | .ui-slider-horizontal .ui-slider-handle { 213 | top: -.3em; 214 | margin-left: -.6em; 215 | } 216 | .ui-slider-horizontal .ui-slider-range { 217 | top: 0; 218 | height: 100%; 219 | } 220 | .ui-slider-horizontal .ui-slider-range-min { 221 | left: 0; 222 | } 223 | .ui-slider-horizontal .ui-slider-range-max { 224 | right: 0; 225 | } 226 | 227 | .ui-slider-vertical { 228 | width: .8em; 229 | height: 100px; 230 | } 231 | .ui-slider-vertical .ui-slider-handle { 232 | left: -.3em; 233 | margin-left: 0; 234 | margin-bottom: -.6em; 235 | } 236 | .ui-slider-vertical .ui-slider-range { 237 | left: 0; 238 | width: 100%; 239 | } 240 | .ui-slider-vertical .ui-slider-range-min { 241 | bottom: 0; 242 | } 243 | .ui-slider-vertical .ui-slider-range-max { 244 | top: 0; 245 | } 246 | -------------------------------------------------------------------------------- /css/jquery-ui.structure.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.1 - 2014-10-15 2 | * http://jqueryui.com 3 | * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0} -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v2.1.3 | MIT License | git.io/normalize */ 2 | 3 | /* ========================================================================== 4 | HTML5 display definitions 5 | ========================================================================== */ 6 | 7 | /** 8 | * Correct `block` display not defined in IE 8/9. 9 | */ 10 | 11 | article, 12 | aside, 13 | details, 14 | figcaption, 15 | figure, 16 | footer, 17 | header, 18 | hgroup, 19 | main, 20 | nav, 21 | section, 22 | summary { 23 | display: block; 24 | } 25 | 26 | /** 27 | * Correct `inline-block` display not defined in IE 8/9. 28 | */ 29 | 30 | audio, 31 | canvas, 32 | video { 33 | display: inline-block; 34 | } 35 | 36 | /** 37 | * Prevent modern browsers from displaying `audio` without controls. 38 | * Remove excess height in iOS 5 devices. 39 | */ 40 | 41 | audio:not([controls]) { 42 | display: none; 43 | height: 0; 44 | } 45 | 46 | /** 47 | * Address `[hidden]` styling not present in IE 8/9. 48 | * Hide the `template` element in IE, Safari, and Firefox < 22. 49 | */ 50 | 51 | [hidden], 52 | template { 53 | display: none; 54 | } 55 | 56 | /* ========================================================================== 57 | Base 58 | ========================================================================== */ 59 | 60 | /** 61 | * 1. Set default font family to sans-serif. 62 | * 2. Prevent iOS text size adjust after orientation change, without disabling 63 | * user zoom. 64 | */ 65 | 66 | html { 67 | font-family: sans-serif; /* 1 */ 68 | -ms-text-size-adjust: 100%; /* 2 */ 69 | -webkit-text-size-adjust: 100%; /* 2 */ 70 | } 71 | 72 | /** 73 | * Remove default margin. 74 | */ 75 | 76 | body { 77 | margin: 0; 78 | } 79 | 80 | /* ========================================================================== 81 | Links 82 | ========================================================================== */ 83 | 84 | /** 85 | * Remove the gray background color from active links in IE 10. 86 | */ 87 | 88 | a { 89 | background: transparent; 90 | } 91 | 92 | /** 93 | * Address `outline` inconsistency between Chrome and other browsers. 94 | */ 95 | 96 | a:focus { 97 | outline: thin dotted; 98 | } 99 | 100 | /** 101 | * Improve readability when focused and also mouse hovered in all browsers. 102 | */ 103 | 104 | a:active, 105 | a:hover { 106 | outline: 0; 107 | } 108 | 109 | /* ========================================================================== 110 | Typography 111 | ========================================================================== */ 112 | 113 | /** 114 | * Address variable `h1` font-size and margin within `section` and `article` 115 | * contexts in Firefox 4+, Safari 5, and Chrome. 116 | */ 117 | 118 | h1 { 119 | font-size: 2em; 120 | margin: 0.67em 0; 121 | } 122 | 123 | /** 124 | * Address styling not present in IE 8/9, Safari 5, and Chrome. 125 | */ 126 | 127 | abbr[title] { 128 | border-bottom: 1px dotted; 129 | } 130 | 131 | /** 132 | * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. 133 | */ 134 | 135 | b, 136 | strong { 137 | font-weight: bold; 138 | } 139 | 140 | /** 141 | * Address styling not present in Safari 5 and Chrome. 142 | */ 143 | 144 | dfn { 145 | font-style: italic; 146 | } 147 | 148 | /** 149 | * Address differences between Firefox and other browsers. 150 | */ 151 | 152 | hr { 153 | -moz-box-sizing: content-box; 154 | box-sizing: content-box; 155 | height: 0; 156 | } 157 | 158 | /** 159 | * Address styling not present in IE 8/9. 160 | */ 161 | 162 | mark { 163 | background: #ff0; 164 | color: #000; 165 | } 166 | 167 | /** 168 | * Correct font family set oddly in Safari 5 and Chrome. 169 | */ 170 | 171 | code, 172 | kbd, 173 | pre, 174 | samp { 175 | font-family: monospace, serif; 176 | font-size: 1em; 177 | } 178 | 179 | /** 180 | * Improve readability of pre-formatted text in all browsers. 181 | */ 182 | 183 | pre { 184 | white-space: pre-wrap; 185 | } 186 | 187 | /** 188 | * Set consistent quote types. 189 | */ 190 | 191 | q { 192 | quotes: "\201C" "\201D" "\2018" "\2019"; 193 | } 194 | 195 | /** 196 | * Address inconsistent and variable font size in all browsers. 197 | */ 198 | 199 | small { 200 | font-size: 80%; 201 | } 202 | 203 | /** 204 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 205 | */ 206 | 207 | sub, 208 | sup { 209 | font-size: 75%; 210 | line-height: 0; 211 | position: relative; 212 | vertical-align: baseline; 213 | } 214 | 215 | sup { 216 | top: -0.5em; 217 | } 218 | 219 | sub { 220 | bottom: -0.25em; 221 | } 222 | 223 | /* ========================================================================== 224 | Embedded content 225 | ========================================================================== */ 226 | 227 | /** 228 | * Remove border when inside `a` element in IE 8/9. 229 | */ 230 | 231 | img { 232 | border: 0; 233 | } 234 | 235 | /** 236 | * Correct overflow displayed oddly in IE 9. 237 | */ 238 | 239 | svg:not(:root) { 240 | overflow: hidden; 241 | } 242 | 243 | /* ========================================================================== 244 | Figures 245 | ========================================================================== */ 246 | 247 | /** 248 | * Address margin not present in IE 8/9 and Safari 5. 249 | */ 250 | 251 | figure { 252 | margin: 0; 253 | } 254 | 255 | /* ========================================================================== 256 | Forms 257 | ========================================================================== */ 258 | 259 | /** 260 | * Define consistent border, margin, and padding. 261 | */ 262 | 263 | fieldset { 264 | border: 1px solid #c0c0c0; 265 | margin: 0 2px; 266 | padding: 0.35em 0.625em 0.75em; 267 | } 268 | 269 | /** 270 | * 1. Correct `color` not being inherited in IE 8/9. 271 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 272 | */ 273 | 274 | legend { 275 | border: 0; /* 1 */ 276 | padding: 0; /* 2 */ 277 | } 278 | 279 | /** 280 | * 1. Correct font family not being inherited in all browsers. 281 | * 2. Correct font size not being inherited in all browsers. 282 | * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. 283 | */ 284 | 285 | button, 286 | input, 287 | select, 288 | textarea { 289 | font-family: inherit; /* 1 */ 290 | font-size: 100%; /* 2 */ 291 | margin: 0; /* 3 */ 292 | } 293 | 294 | /** 295 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 296 | * the UA stylesheet. 297 | */ 298 | 299 | button, 300 | input { 301 | line-height: normal; 302 | } 303 | 304 | /** 305 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 306 | * All other form control elements do not inherit `text-transform` values. 307 | * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. 308 | * Correct `select` style inheritance in Firefox 4+ and Opera. 309 | */ 310 | 311 | button, 312 | select { 313 | text-transform: none; 314 | } 315 | 316 | /** 317 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 318 | * and `video` controls. 319 | * 2. Correct inability to style clickable `input` types in iOS. 320 | * 3. Improve usability and consistency of cursor style between image-type 321 | * `input` and others. 322 | */ 323 | 324 | button, 325 | html input[type="button"], /* 1 */ 326 | input[type="reset"], 327 | input[type="submit"] { 328 | -webkit-appearance: button; /* 2 */ 329 | cursor: pointer; /* 3 */ 330 | } 331 | 332 | /** 333 | * Re-set default cursor for disabled elements. 334 | */ 335 | 336 | button[disabled], 337 | html input[disabled] { 338 | cursor: default; 339 | } 340 | 341 | /** 342 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 343 | * 2. Remove excess padding in IE 8/9/10. 344 | */ 345 | 346 | input[type="checkbox"], 347 | input[type="radio"] { 348 | box-sizing: border-box; /* 1 */ 349 | padding: 0; /* 2 */ 350 | } 351 | 352 | /** 353 | * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 354 | * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome 355 | * (include `-moz` to future-proof). 356 | */ 357 | 358 | input[type="search"] { 359 | -webkit-appearance: textfield; /* 1 */ 360 | -moz-box-sizing: content-box; 361 | -webkit-box-sizing: content-box; /* 2 */ 362 | box-sizing: content-box; 363 | } 364 | 365 | /** 366 | * Remove inner padding and search cancel button in Safari 5 and Chrome 367 | * on OS X. 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Remove inner padding and border in Firefox 4+. 377 | */ 378 | 379 | button::-moz-focus-inner, 380 | input::-moz-focus-inner { 381 | border: 0; 382 | padding: 0; 383 | } 384 | 385 | /** 386 | * 1. Remove default vertical scrollbar in IE 8/9. 387 | * 2. Improve readability and alignment in all browsers. 388 | */ 389 | 390 | textarea { 391 | overflow: auto; /* 1 */ 392 | vertical-align: top; /* 2 */ 393 | } 394 | 395 | /* ========================================================================== 396 | Tables 397 | ========================================================================== */ 398 | 399 | /** 400 | * Remove most spacing between table cells. 401 | */ 402 | 403 | table { 404 | border-collapse: collapse; 405 | border-spacing: 0; 406 | } 407 | -------------------------------------------------------------------------------- /css/viewer.css: -------------------------------------------------------------------------------- 1 | @import url(http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic&subset=latin,cyrillic,latin-ext,cyrillic-ext); 2 | /* @import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700&subset=latin,cyrillic-ext,cyrillic,latin-ext,greek-ext,greek); */ 3 | @import url(https://fonts.googleapis.com/css?family=Neucha&subset=latin,cyrillic); 4 | html, body { 5 | height: 100%; 6 | } 7 | body { 8 | background-color: white; 9 | position: relative; 10 | font-family: 'PT Sans', sans-serif; 11 | } 12 | 13 | #wrapper { 14 | background-color: white; 15 | height: 100%; 16 | margin: 0 auto; 17 | overflow: hidden; 18 | position: relative; 19 | cursor: default; 20 | } 21 | #canvas { 22 | width: 100%; 23 | position: absolute; 24 | } 25 | #canvas svg { 26 | overflow: visible; 27 | } 28 | #canvas svg, #t { 29 | font-family: 'PT Sans', sans-serif; 30 | } 31 | #canvas svg a { 32 | text-decoration: underline; 33 | } 34 | #canvas rect.frame.none { 35 | stroke-width: 0!important; 36 | } 37 | .drag { 38 | cursor: url(/images/openhand.cur), url(../images/openhand.cur), auto!important; 39 | cursor: -moz-grab!important; 40 | /*cursor: -webkit-grab!important; - looks ugly :( */ 41 | } 42 | .dragging { 43 | cursor: url(/images/closedhand.cur), url(../images/closedhand.cur), auto!important; 44 | cursor: -moz-grabbing!important; 45 | /*cursor: -webkit-grabbing!important; - looks ugly :( */ 46 | } 47 | .smooth-transform { 48 | -webkit-transition: all 0.4s ease-in-out; 49 | -moz-transition: all 0.4s ease-in-out; 50 | -ms-transition: all 0.4s ease-in-out; 51 | -o-transition: all 0.4s ease-in-out; 52 | transition: all 0.4s ease-in-out; 53 | } 54 | .edit { 55 | cursor: url(/images/pencil.cur), url(../images/pencil.cur), auto!important; 56 | } 57 | .zoom_fit { 58 | cursor: url(/images/zoom.cur), url(../images/zoom.cur), auto!important; 59 | } 60 | .pointer { 61 | cursor: pointer; 62 | } 63 | 64 | /* controls */ 65 | #wrapper #zoom-control { 66 | position: absolute; 67 | left: 15px; 68 | bottom: 15px; 69 | z-index: 2; 70 | } 71 | #wrapper #minimap { 72 | position: absolute; 73 | right: 15px; 74 | bottom: 15px; 75 | z-index: 2; 76 | } 77 | #wrapper #minimap .map { 78 | width: 100px; 79 | height: 100px; 80 | position: relative; 81 | background-color: white; 82 | overflow: hidden; 83 | border: 1px solid #CCCCCC; 84 | } 85 | #wrapper #minimap .model { 86 | position: absolute; 87 | left: 0; 88 | top: 0; 89 | width: 10px; 90 | height: 10px; 91 | background: #CCCCCC; 92 | } 93 | #wrapper #minimap .view { 94 | position: absolute; 95 | left: 0; 96 | top: 0; 97 | width: 10px; 98 | height: 10px; 99 | border: 1px solid #357EBD; 100 | background: rgba(66, 139, 202, 0.3); 101 | } 102 | #wrapper #search { 103 | position: absolute; 104 | right: 15px; 105 | top: 15px; 106 | z-index: 2; 107 | } 108 | #wrapper #search input { 109 | width: 60px; 110 | } 111 | #wrapper #search input:focus, 112 | #wrapper #search input.active { 113 | width: 160px; 114 | } 115 | #wrapper #search .form-control-feedback { 116 | right: 30px; 117 | } 118 | 119 | 120 | 121 | /* printing */ 122 | @media print { 123 | @page { 124 | /*size: 11.7in 8.3in;*/ 125 | size: landscape; /*A4 landscape;*/ 126 | margin: 0.5cm; 127 | } 128 | #schema-editor { 129 | padding-top: 0; 130 | } 131 | #menu, #modeller, #sidebar, #controls { 132 | display: none; 133 | } 134 | #wrapper { 135 | margin-top: 0; 136 | overflow: visible; 137 | width: auto; 138 | height: auto; 139 | } 140 | #canvas { 141 | position: static; 142 | width: 100%; 143 | height: 100%; 144 | } 145 | rect.frame, rect.mask { 146 | display: none!important; 147 | } 148 | text { 149 | display: block!important; 150 | } 151 | a:link:after { 152 | content: " (" attr(href) ") "; 153 | } 154 | 155 | } -------------------------------------------------------------------------------- /fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /images/closedhand.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/images/closedhand.cur -------------------------------------------------------------------------------- /images/openhand.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/images/openhand.cur -------------------------------------------------------------------------------- /images/pencil.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/images/pencil.cur -------------------------------------------------------------------------------- /images/zoom.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeonidOvcharenko/tectograph/eec244c60d9132c72dc27874a5b6e6e5381be509/images/zoom.cur -------------------------------------------------------------------------------- /js/coffee/app-view.coffee: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | !(($, win, doc) -> 3 | $doc = $ doc 4 | $win = $ win 5 | 6 | def = $.Deferred() 7 | 8 | # load from params 9 | s = location.hash.substring 1 10 | s = s.split '##' 11 | if s[0] 12 | url = s[0] 13 | $.ajax( 14 | url: url 15 | crossDomain: true 16 | contentType: "application/json" 17 | success: (data)-> 18 | system = new S {} 19 | system.deserialize data 20 | def.resolve system 21 | ) 22 | .fail -> def.resolve system7 23 | else 24 | def.resolve system7 25 | style = if s[1]!='' then Math.min(win.Themes.length-1, parseInt s[1]) else 1 26 | 27 | $win.load -> 28 | $.when(def).then (s) -> 29 | win.system = s 30 | win.Theme = win.Themes[style] 31 | win.viewer = new Viewer 32 | div: 'canvas' 33 | # smooth: true 34 | win.modelview = new ModelWebView 35 | div: 'canvas' 36 | model: system 37 | doc.title = system[system.root]?.title || 'Tectogram' 38 | 39 | # win.modelviewstatic = new ModelStaticView 40 | # div: 'static' 41 | # model: system 42 | # bbox = modelviewstatic.object.bbox() 43 | # $('#static').css 44 | # position: 'absolute' 45 | # width: bbox.width 46 | # height: bbox.height 47 | # top: 0 48 | # left: 0 49 | # zIndex: 99999 50 | # background: 'white' 51 | 52 | )(jQuery, window, document) -------------------------------------------------------------------------------- /js/coffee/app.coffee: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | !(($, win, doc) -> 3 | $doc = $ doc 4 | $win = $ win 5 | 6 | win.editor = win.viewer = null 7 | win.system = win.empty_system 8 | win.system.reload 'autosave' 9 | 10 | $win.load -> 11 | win.Theme = win.Themes[0] 12 | win.viewer = new Viewer 13 | div: 'canvas' 14 | win.modelview = new ModelWebViewEditable 15 | div: 'canvas' 16 | model: system 17 | #win.DasModel.show_story() 18 | 19 | win.editor = new Editor system 20 | win.editor.edit system.root 21 | 22 | win.editor.load_settings() 23 | 24 | # responces on extension's messages 25 | # win.addEventListener "message", (event)-> 26 | # # We only accept messages from ourselves 27 | # return if event.source != win 28 | # if event.data.type 29 | # if event.data.type == "SAVE" 30 | # win.postMessage { type: "DATA", system: system.serialize() }, "*" 31 | # else if event.data.type == "LOAD" 32 | # editor.load_file event.data.system 33 | # , false 34 | 35 | )(jQuery, window, document) -------------------------------------------------------------------------------- /js/coffee/model.coffee: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | !(($, win, doc) -> 3 | $doc = $ doc 4 | $win = $ win 5 | 6 | # system inner objects — extend with methods 7 | # .system .id [.title .description .picture .link .structure .matrix] 8 | class win.A 9 | constructor: (system, id)-> 10 | $.extend @, system 11 | @id = @id || id || 'i'+Math.round(Math.random()*100000) # TODO: autogenerate id on server 12 | 13 | each_element: (func)-> 14 | return if not @matrix 15 | for row, i in @matrix 16 | func @system[row[i]], i 17 | 18 | each_relation: (func)-> 19 | return if not @matrix 20 | for row, i in @matrix 21 | for m, j in row 22 | func @system[m], i, j if m and i!=j 23 | 24 | each_child: (func)-> 25 | return if not @matrix 26 | for row, i in @matrix 27 | for m, j in row 28 | func @system[m], i, j if m 29 | 30 | create_child: (id, title='')-> 31 | # create matrix if empty 32 | if not @matrix 33 | @matrix = [] 34 | @structure = "list.inline" 35 | # use existing element or create a new one 36 | if id 37 | child = @system[id] 38 | else 39 | child = new A 40 | system: @system 41 | title: title || '['+(@matrix.length+1)+'] '+@title 42 | @system[child.id] = child 43 | # expand matrix 44 | newline = [] 45 | for row, i in @matrix 46 | row.push null 47 | newline.push null 48 | newline.push child.id 49 | @matrix.push newline 50 | # return id 51 | child.id 52 | 53 | create_sibling_shift: (shift)-> 54 | parent = @system.parent_of @id 55 | pmatrix = @system[parent].matrix 56 | # create new element 57 | sibling = new A 58 | system: @system 59 | title: '['+(pmatrix.length+1)+'] '+@system[parent].title 60 | @system[sibling.id] = sibling 61 | # get index of inserted element 62 | for row, i in pmatrix 63 | break if row[i] == @id 64 | # if current element is relation, add into the end 65 | pos = i+shift 66 | # expand parent matrix 67 | newline = [] 68 | for row, i in pmatrix 69 | row.splice pos, 0, null 70 | newline.push null 71 | newline.splice pos, 0, sibling.id 72 | pmatrix.splice pos, 0, newline 73 | # return id 74 | sibling.id 75 | 76 | create_sibling_before: -> @create_sibling_shift 0 77 | create_sibling_after: -> @create_sibling_shift +1 78 | 79 | create_relation: (id1, id2)-> 80 | for row, k in @matrix 81 | i = k if row[k]==id1 82 | j = k if row[k]==id2 83 | return @matrix[i][j] if @matrix[i][j] 84 | relation = new A 85 | system: @system 86 | title: @system[id1].nav_title()+' → '+@system[id2].nav_title() 87 | @system[relation.id] = relation 88 | @matrix[i][j] = relation.id 89 | relation.id 90 | 91 | delete_child: (id, leave)-> 92 | # we assume there is only one link to an element in structure 93 | delete @system[id] unless leave # delete element/relation 94 | for row, i in @matrix 95 | break if row[i]==id # this is an element 96 | for m, j in row 97 | if m==id and i!=j # this is a relation 98 | @matrix[i][j] = null 99 | return 100 | # delete relations of deleted element 101 | @each_relation (rel, ri, rj)=> 102 | delete @system[rel.id] if ri==i or rj==i 103 | # collapse matrix: remove row and columns 104 | @matrix.splice i, 1 105 | row.splice i, 1 for row in @matrix 106 | 107 | move_child: (id, step)-> 108 | for row, i in @matrix 109 | j = i+step 110 | if row[i]==id and @matrix[j] and @matrix[j][j] 111 | # swap columns 112 | for row1 in @matrix 113 | e = row1[i] 114 | row1[i] = row1[j] 115 | row1[j] = e 116 | # swap rows 117 | r = @matrix[i] 118 | @matrix[i] = @matrix[j] 119 | @matrix[j] = r 120 | return 121 | 122 | next_sibling: (id)-> 123 | for row, i in @matrix 124 | j = i+1 125 | if row[i]==id and @matrix[j] and @matrix[j][j] 126 | return @matrix[j][j] 127 | null 128 | 129 | nav_title: -> 130 | if @title and not /^\s*$/.test @title 131 | return @.title 132 | else if @description 133 | return @description.split('\n')[0] 134 | else 135 | return @id 136 | 137 | match: (regexp)-> 138 | return ((@title and @title.match regexp) or (@description and @description.match regexp)) 139 | 140 | class win.S 141 | constructor: (system)-> 142 | $.extend @, system 143 | for key, a of @ 144 | if a instanceof A 145 | a.system = @ 146 | a.id = key 147 | 148 | parent_of: (child)-> 149 | for id, model of @ 150 | if model.matrix 151 | for row in model.matrix 152 | for element in row 153 | return id if element and element == child 154 | null 155 | 156 | depth_of: (id)-> 157 | el = @[id] 158 | if el.matrix 159 | d = 0 160 | el.each_element (child)=> 161 | d = Math.max d, @depth_of child.id 162 | return d+1 163 | else 164 | return 0 165 | 166 | height: -> 167 | @depth_of(@root)+1 168 | 169 | # TODO: auto-id, add-element, add-link, remove-element, ... 170 | rebuild: (s)-> 171 | for key, a of @ 172 | delete @[key] if a instanceof A 173 | for key, a of s 174 | if key=='root' or key=='story' 175 | @[key] = a 176 | else 177 | @[key] = new A a 178 | @[key].system = @ 179 | 180 | serialize: -> 181 | JSON.stringify @, (key, value)-> 182 | return if key == "system" then undefined else value # avoid circular reference 183 | 184 | deserialize: (s)-> 185 | @rebuild JSON.parse s 186 | 187 | save: (key)-> 188 | key = key || 'system' 189 | s = @serialize() 190 | localStorage.setItem key, s 191 | 192 | reload: (key)-> 193 | key = key || 'system' 194 | s = localStorage.getItem key 195 | @deserialize s if s 196 | 197 | find: (query, from)-> 198 | reg = new RegExp RegExp.escape(query), 'gi' 199 | search_on = not from? 200 | for key, a of @ 201 | if a instanceof A 202 | return key if search_on and a.match reg 203 | search_on = true if not search_on and key == from # start search at "from" element 204 | null 205 | 206 | findAll: (query)-> 207 | reg = new RegExp RegExp.escape(query), 'gi' 208 | res = [] 209 | for key, a of @ 210 | res.push key if a instanceof A and a.match reg 211 | res 212 | 213 | )(jQuery, window, document) -------------------------------------------------------------------------------- /js/coffee/template.coffee: -------------------------------------------------------------------------------- 1 | #- wrapper 2 | 3 | "use strict"; 4 | !(($, win, doc) -> 5 | $doc = $ doc 6 | $win = $ win 7 | class win.Template 8 | constructor: (options)-> 9 | defaults = 10 | cont: '' 11 | @opt = $.extend {}, defaults, options 12 | @cont = $ @opt.cont 13 | @build_content() 14 | @controller() 15 | 16 | build_content: -> 17 | T = {} 18 | 19 | T.footer = """ 20 | footer.container-fluid 21 | .row 22 | .col-xs-12.small 23 | p 24 | | © ParetoNews 2014    25 | a href="#" 26 | =t 'footer.blog' 27 | |  ·  28 | a href="#" 29 | =t 'footer.help' 30 | |  ·  31 | a href="#" 32 | =t 'footer.faq' 33 | |  ·  34 | a href="#" 35 | =t 'footer.terms' 36 | |  ·  37 | a href="#" 38 | =t 'footer.privacy' 39 | """ 40 | 41 | @div = $('
') 42 | # @div.appendTo @cont 43 | 44 | @create_tpl('application', """ 45 | .content = outlet 46 | """) 47 | for tpl of T 48 | @create_tpl tpl, T[tpl] 49 | 50 | controller: -> 51 | 52 | compile: (source, data)-> 53 | template = Emblem.compile Handlebars, source 54 | template(data) 55 | 56 | create_tpl: (id, source)-> 57 | # console.log source 58 | $('body').append "" 59 | 60 | destroy: -> 61 | @div.remove() 62 | @div = null 63 | )(jQuery, window, document) 64 | 65 | -------------------------------------------------------------------------------- /js/coffee/text-import.coffee: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | !(($, win, doc) -> 3 | $doc = $ doc 4 | $win = $ win 5 | 6 | # -import plain text, -import text, -text reader 7 | class win.TEXTreader 8 | constructor: (options)-> 9 | defaults = 10 | text: {} 11 | @opt = $.extend {}, defaults, options 12 | @lines = @opt.text.split '\n' 13 | @i = 0 14 | @build_content() 15 | build_content: -> 16 | @read() 17 | read_element: (lines, el)-> 18 | line = lines[0] 19 | # pick title 20 | m = line.match /^\-\s(.*)$/ 21 | title = m[1] if m 22 | j = 1 23 | struct = [] 24 | desc = [] 25 | while lines[j] and lines[j].substr(0,2)==' ' 26 | line = lines[j].replace(/^\s\s/,'') 27 | j++ 28 | continue if not line 29 | # test for link 30 | m = line.match /^\[(.*)\]$/ 31 | if m 32 | link = m[1] 33 | skip = true 34 | else 35 | # test for illustration 36 | m = line.match /^Илл\.\:\s(.*)$/ 37 | if m 38 | ill = m[1] 39 | skip = true 40 | else 41 | skip = false 42 | # pick structure 43 | if line.substr(0,2)==' ' or line.substr(0,2)=='- ' 44 | struct.push line 45 | # rest is for description 46 | else 47 | desc.push line if not skip 48 | description = desc.join '\n' 49 | el.title = title || '' 50 | el.description = description || '' 51 | el.link = {url:link} if link 52 | el.picture = {url:ill, width: 100, height: 100} if ill 53 | @read_structure struct, el 54 | read_structure: (lines, el)-> 55 | children = lines.join '\n' 56 | return if not children 57 | children = children.split '\n- ' 58 | for child, i in children 59 | child = '- '+child if i>0 60 | lines = child.split '\n' 61 | C = el.create_child() 62 | C = @system[C] 63 | @read_element lines, C 64 | el.structure = 'list.bricks' 65 | read: -> 66 | @system = new S 67 | root: 'iSystem' 68 | iSystem: new A { title: 'New' } 69 | @read_element @lines, @system.iSystem 70 | @system 71 | 72 | )(jQuery, window, document) -------------------------------------------------------------------------------- /js/coffee/text-render.coffee: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | !(($, win, doc) -> 3 | $doc = $ doc 4 | $win = $ win 5 | 6 | # -TEXT, -plain text, -text 7 | class win.TEXTrender 8 | constructor: (options)-> 9 | defaults = 10 | model: {} 11 | @opt = $.extend {}, defaults, options 12 | @model = @opt.model 13 | @build_content() 14 | build_content: -> 15 | @render() 16 | render: -> 17 | model = @model[@model.root] 18 | system = new TEXTElement 19 | id: @model.root 20 | level: 0 21 | model: model 22 | system.render() 23 | 24 | class win.XObj 25 | constructor: (options)-> 26 | defaults = 27 | model: {} 28 | @opt = $.extend {}, defaults, options 29 | @model = @opt.model 30 | @level = @opt.level 31 | @indent = @make_indent @level 32 | render: -> 33 | model.title 34 | make_indent: (tabs)-> 35 | indent = '' 36 | indent += ' ' for i in [0...tabs] # \t 37 | indent 38 | 39 | class win.TEXTElement extends XObj 40 | constructor: (options)-> super options 41 | render: -> 42 | t = '' 43 | t += @indent+'- '+(@model.title || '') 44 | if @model.link and @model.link.url 45 | t += '\n'+@indent+' ['+@model.link.url+']' 46 | if @model.description 47 | t += '\n'+@indent+' '+@model.description.replace(/\n/g, '\n'+@indent+' ') 48 | if @model.picture and @model.picture.url 49 | t += '\n'+@indent+'Илл.: '+@model.picture.url 50 | # structure 51 | if @model.structure 52 | t += @render_structure() 53 | t 54 | render_structure: (x, y, w, ready)-> 55 | @structure = new TEXTStructure 56 | model: @model 57 | level: @level 58 | @structure.render() 59 | 60 | class win.TEXTStructure extends XObj 61 | constructor: (options)-> super options 62 | render: -> 63 | t = '' 64 | relations = false 65 | @model.each_element (model, i)=> 66 | # element 67 | t += '\n'+@render_element model 68 | # relations 69 | for rel, j in @model.matrix[i] 70 | continue if j==i or not rel or not @model.system[rel] 71 | t += '\n'+@render_element @model.system[rel] 72 | t 73 | render_element: (model)-> 74 | element = new TEXTElement 75 | id: model.id 76 | model: model 77 | level: @level+1 78 | element.render() 79 | 80 | # -XML 81 | class win.XMLrender extends TEXTrender 82 | constructor: (options)-> super options 83 | render: -> 84 | model = @model[@model.root] 85 | system = new XMLElement 86 | id: @model.root 87 | level: 0 88 | type: 'element' 89 | model: model 90 | '\n\n'+system.render()+'\n' 91 | 92 | class win.XMLElement extends XObj 93 | constructor: (options)-> 94 | super options 95 | @indent = @make_indent @level+1 96 | @indent2 = @make_indent @level+2 97 | render: -> 98 | t = @indent+'' 99 | if @model.title 100 | t += '\n'+@indent2+''+$.escape(@model.title || '')+'' 101 | if @model.link and @model.link.url 102 | t += '\n'+@indent2+''+@model.link.url+'' 103 | if @model.description 104 | t += '\n'+@indent2+''+$.escape(@model.description)+'' 105 | if @model.picture and @model.picture.url 106 | t += '\n'+@indent2+'' 107 | # structure 108 | if @model.structure 109 | t += @render_structure() 110 | t+'\n'+@indent+'' 111 | render_structure: (x, y, w, ready)-> 112 | @structure = new XMLStructure 113 | model: @model 114 | level: @level+1 115 | @structure.render() 116 | 117 | class win.XMLStructure extends XObj 118 | constructor: (options)-> 119 | super options 120 | @indent = @make_indent @level+1 121 | render: -> 122 | t = '\n'+@indent+'' 123 | relations = false 124 | @model.each_element (model, i)=> 125 | # element 126 | t += '\n'+@render_element model, 'element' 127 | # relations 128 | for rel, j in @model.matrix[i] 129 | continue if j==i or not rel or not @model.system[rel] 130 | t += '\n'+@render_element @model.system[rel], 'relation' 131 | t+'\n'+@indent+'' 132 | render_element: (model, type)-> 133 | element = new XMLElement 134 | id: model.id 135 | model: model 136 | type: type 137 | level: @level+1 138 | element.render() 139 | 140 | # -HTML 141 | class win.HTMLrender extends TEXTrender 142 | constructor: (options)-> super options 143 | render: -> 144 | model = @model[@model.root] 145 | system = new HTMLElement 146 | id: @model.root 147 | level: 0 148 | type: 'element' 149 | model: model 150 | '' 151 | 152 | class win.HTMLElement extends XObj 153 | constructor: (options)-> 154 | super options 155 | @opt.tag = 'li' if not @opt.tag 156 | render: -> 157 | t = '<'+@opt.tag+' class="'+@opt.type+' level-'+@level+'">' 158 | if @model.title 159 | t += '

'+$.escape(@model.title || '')+'

' 160 | if @model.link and @model.link.url 161 | t += ''+@model.link.url+'' 162 | if @model.description 163 | t += '

'+$.escape(@model.description).replace(/\n/g, '
')+'

' 164 | if @model.picture and @model.picture.url 165 | if @model.picture.video 166 | t += @model.picture.video+'Video' 167 | else 168 | t += '' 169 | # structure 170 | if @model.structure 171 | t += @render_structure() 172 | t+'' 173 | render_structure: (x, y, w, ready)-> 174 | @structure = new HTMLStructure 175 | model: @model 176 | level: @level 177 | @structure.render() 178 | 179 | class win.HTMLStructure extends XObj 180 | constructor: (options)-> super options 181 | render: -> 182 | if @model.structure in ['graph', 'matrix'] 183 | @render_table() 184 | else 185 | @render_list() 186 | render_table: -> 187 | t = '' 188 | @model.each_element (model, i)=> 189 | t += '' 190 | for rel, j in @model.matrix[i] 191 | if rel and @model.system[rel] 192 | type = if i==j then 'element' else 'relation' 193 | t += @render_element @model.system[rel], type, 'td' 194 | else 195 | t += '' 196 | t += '' 197 | t+'
' 198 | render_list: -> 199 | t = '' 209 | render_element: (model, type, tag)-> 210 | element = new HTMLElement 211 | id: model.id 212 | model: model 213 | type: type 214 | tag: tag 215 | level: @level+1 216 | element.render() 217 | 218 | )(jQuery, window, document) -------------------------------------------------------------------------------- /js/coffee/themes.coffee: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | !(($, win, doc) -> 3 | $doc = $ doc 4 | $win = $ win 5 | 6 | # -theme 7 | class win.ThemeGen 8 | constructor: (options)-> 9 | defaults = 10 | title: '' 11 | basefontsize: 7812.5 # px at level #0 12 | K: 2.5 # interlevel scale 13 | xSpace: 2.5 # × fontsize 14 | xStroke: 0.02 # × fontsize 15 | xCellp: 0.16 # × fontsize 16 | xImgsize: 10 # × fontsize 17 | xWidth: 20 # × fontsize 18 | minfontsize: 5.98 # px — 6 in Chrome 19 | max_imgwidth: 300 # px 20 | margin: 20 # px 21 | markersize: 5 # px 22 | fontFamily: "PT Sans" 23 | lineHeight: 1.25 24 | rel_opacity: 0.8 25 | toplevel: 1 26 | slideshow: 2000 27 | color: 28 | text: '#000000' 29 | background: '#FFFFFF' 30 | selected: 31 | stroke: '#8DBEFF' 32 | fill: '#FFFFE2' 33 | stroke: '#C0C0C0' 34 | mask: '#C0C0C0' 35 | found: '#E5FF00' 36 | bullet: '#C0C0C0' 37 | emphasis: '#F08010' 38 | link: '#4F7FCE' 39 | link_hover: '#2020F0' 40 | $.extend true, @, defaults, options 41 | 42 | Levels = 10 43 | # generate font sizes 44 | @sizes = [@basefontsize] 45 | @sizes.push @sizes[i]/@K for i in [0...Levels] 46 | # generate spaces, strokes, cellp, imgsize 47 | @spaces = [] 48 | @strokes = [] 49 | @cellp = [] 50 | @imgsize = [] 51 | @width = [] 52 | for i in [0...Levels] 53 | s = @sizes[i] 54 | @spaces.push s*@xSpace 55 | @strokes.push s*@xStroke 56 | @cellp.push s*@xCellp 57 | @imgsize.push s*@xImgsize 58 | @width.push s*@xWidth 59 | # max zoom: min stroke = 1px 60 | @maxzoom = 1/@strokes[@strokes.length-1] 61 | # min zoom: fontsize[toplevel+1] = minfontsize 62 | @minzoom = @minfontsize / @sizes[@toplevel+1] 63 | 64 | threshold: (s)-> 65 | for fs, i in @sizes 66 | if @minfontsize > fs*s 67 | return i 68 | @sizes.length 69 | 70 | win.Themes = [] 71 | 72 | # -default theme settings 73 | win.Themes.push new ThemeGen 74 | title: 'Веб' 75 | basefontsize: 7812.5 # px at level #0 76 | K: 2.5 77 | max_imgwidth: 300 # px 78 | margin: 20 # px 79 | markersize: 5 # px 80 | fontFamily: "PT Sans" 81 | lineHeight: 1.25 82 | slideshow: 2000 83 | color: 84 | selected: 85 | stroke: '#8DBEFF' # '#E88DFF' # '#3071A9' 86 | fill: '#FFFFE2' 87 | bullet: '#C0C0C0' 88 | mask: '#C0C0C0' 89 | emphasis: '#F08010' 90 | link: '#4F7FCE' 91 | link_hover: '#2020F0' 92 | 93 | win.Themes.push new ThemeGen 94 | title: 'Презентация' 95 | K: 2.5 96 | fontFamily: 'Trebuchet MS' 97 | lineHeight: 1.33 98 | color: 99 | background: '#F4F4F3' 100 | text: '#36424E' 101 | bullet: '#36424E' 102 | stroke: '#36424E' 103 | mask: '#D5D8D6' 104 | emphasis: '#70A3EF' 105 | link: '#7491BC' 106 | link_hover: '#70A3EF' 107 | selected: 108 | stroke: '#2D261D' 109 | fill: '#2D261D' 110 | 111 | win.Themes.push new ThemeGen 112 | title: 'Книга' 113 | K: 2.5 114 | fontFamily: 'Georgia' 115 | lineHeight: 1.33 116 | color: 117 | bullet: '#A0A0A0' 118 | mask: '#A0A0A0' 119 | emphasis: '#FF3333' 120 | 121 | win.Themes.push new ThemeGen 122 | title: 'Старая книга' 123 | K: 2.5 124 | fontFamily: 'Georgia' 125 | lineHeight: 1.5 126 | color: 127 | background: '#FDE7B2' 128 | text: '#371C07' 129 | bullet: '#BD8E58' 130 | stroke: '#63481E' 131 | mask: '#BD8E58' 132 | emphasis: '#862400' # '#BD8E58' 133 | link: '#B4794A' 134 | link_hover: '#FFDA73' 135 | selected: 136 | stroke: '#2D261D' 137 | fill: '#2D261D' 138 | 139 | win.Themes.push new ThemeGen 140 | title: 'Печатная машинка' 141 | K: 2 142 | fontFamily: 'courier new' 143 | color: 144 | text: '#333333' 145 | emphasis: '#FF3333' 146 | 147 | win.Themes.push new ThemeGen 148 | title: 'Рукопись 1' 149 | K: 2 150 | xStroke: 0.085 151 | markersize: 1.5 152 | fontFamily: 'comic sans ms' 153 | lineHeight: 1.15 154 | 155 | win.Themes.push new ThemeGen 156 | title: 'Рукопись 2' 157 | K: 2.25 158 | fontFamily: 'Neucha' 159 | lineHeight: 1.15 160 | color: 161 | emphasis: '#F9AF33' 162 | 163 | win.Theme = win.Themes[0] 164 | 165 | )(jQuery, window, document) -------------------------------------------------------------------------------- /js/coffee/utils.coffee: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | RegExp.escape = (text)-> 4 | text.replace /[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&" 5 | 6 | # -random ~pseudo 7 | Rand = 8 | seed: 1 9 | reset: -> @seed = 1 10 | random: -> 11 | @seed = @seed*40692%2147483399 12 | @seed/2147483399 13 | 14 | # jQuery object extentions 15 | !(($, win, doc) -> 16 | $doc = $ doc 17 | $win = $ win 18 | 19 | $.key = 20 | Enter: 13 21 | Esc: 27 22 | Down: 40 23 | Up: 38 24 | Left: 37 25 | Right: 39 26 | Tab: 9 27 | Backspace: 8 28 | Space: 32 29 | Plus: 187 30 | Minus: 189 31 | Slash_cyr: 190 32 | Slash: 191 33 | Shift: 16 34 | Ctrl: 17 35 | PgUp: 33 36 | PgDn: 34 37 | End: 35 38 | Home: 36 39 | Ins: 45 40 | Del: 46 41 | n1: 49 42 | n2: 50 43 | n3: 51 44 | n4: 52 45 | n5: 53 46 | A: 65 47 | D: 68 48 | F: 70 49 | G: 71 50 | H: 72 51 | I: 73 52 | J: 74 53 | K: 75 54 | L: 76 55 | R: 82 56 | S: 83 57 | T: 84 58 | U: 85 59 | V: 86 60 | W: 87 61 | X: 88 62 | Y: 89 63 | Z: 90 64 | n1_num: 97 65 | n2_num: 98 66 | n3_num: 99 67 | n4_num: 100 68 | n5_num: 101 69 | n6_num: 102 70 | n7_num: 103 71 | n8_num: 104 72 | n9_num: 105 73 | Star_num: 106 74 | Plus_num: 107 75 | Minus_num: 109 76 | Slash_num: 111 77 | 78 | $.activeInput = -> 79 | tag = doc.activeElement.tagName 80 | tag == "INPUT" || tag == "TEXTAREA" || tag == "SELECT" || doc.activeElement.contentEditable == 'true' 81 | 82 | $.clearSelection = -> 83 | if doc.selection and doc.selection.empty 84 | doc.selection.empty 85 | else if win.getSelection 86 | sel = win.getSelection() 87 | sel.removeAllRanges() 88 | 89 | $.selectContents = (id)-> 90 | el = doc.getElementById id 91 | range = doc.createRange() 92 | range.selectNodeContents el 93 | sel = win.getSelection() 94 | sel.removeAllRanges() 95 | sel.addRange range 96 | 97 | $.selection = -> 98 | s = '' 99 | if win.getSelection 100 | sel = win.getSelection() 101 | s = sel.toString() 102 | s 103 | 104 | $.escape = (text)-> 105 | text.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'") 106 | 107 | $.fn.svgRemoveClass = (c)-> 108 | @.each (i, el)-> el.instance?.removeClass c 109 | 110 | $.fn.svgAddClass = (c)-> 111 | @.each (i, el)-> el.instance?.addClass c 112 | 113 | $.browser = 114 | firefox: navigator.userAgent.toLowerCase().indexOf('firefox') > -1 115 | 116 | )(jQuery, window, document) -------------------------------------------------------------------------------- /js/coffee/viewer.coffee: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | !(($, win, doc) -> 3 | $doc = $ doc 4 | $win = $ win 5 | 6 | class win.Viewer 7 | constructor: (options)-> 8 | defaults = 9 | div: 'canvas' 10 | model: {} 11 | smooth: false 12 | svg: null 13 | @opt = $.extend {}, defaults, options 14 | @div = $ '#'+@opt.div 15 | @wrapper = @div.parent() 16 | @build_content() 17 | @controller() 18 | 19 | build_content: -> 20 | @scale = 1 21 | @save_canvas_size() 22 | @controls = new Ractive 23 | el: 'controls' 24 | template: '#map-controls' 25 | data: 26 | zoomlock: '' 27 | is_drawing: false 28 | progress: 0 29 | @minimap = $ '#minimap .model' 30 | @viewport = $ '#minimap .view' 31 | @quickdrag = $ '#minimap .map' 32 | 33 | @wrapper.addClass 'drag' 34 | @div.addClass 'smooth-transform' if @opt.smooth 35 | $('#wrapper').css {backgroundColor: Theme.color.background} 36 | @update_minimap() 37 | 38 | controller: -> 39 | @controls.on 40 | 'zoom-in': => 41 | @zoom_step true 42 | 'zoom-out': => 43 | @zoom_step false 44 | 'clear-search': => 45 | @controls.set 'search', '' 46 | 'show-search-results': (e)=> 47 | if e.original.which in [$.key.Down, $.key.Enter] 48 | $('#filter-dropdown').dropdown 'toggle' 49 | return false 50 | 'goto': (e)=> 51 | id = e.context.link 52 | @find_and_zoom id if id 53 | e.original.preventDefault() 54 | false 55 | @controls.observe 56 | 'search': (query)=> 57 | @search query 58 | $win.on 'keydown.viewer', (e)=> 59 | @wrapper.addClass 'zoom_fit' if e.which == $.key.Ctrl 60 | if $.activeInput() 61 | return true 62 | # Shift+key 63 | else if e.shiftKey 64 | switch e.which 65 | when $.key.Plus, $.key.Plus_num 66 | # zoom in 67 | @zoom_step true 68 | when $.key.Minus, $.key.Minus_num 69 | # zoom out 70 | @zoom_step false 71 | when $.key.Up 72 | # pan up 73 | @pan_step 0, +1 74 | when $.key.Down 75 | # pan down 76 | @pan_step 0, -1 77 | when $.key.Left 78 | # pan left 79 | @pan_step +1, 0 80 | when $.key.Right 81 | # pan right 82 | @pan_step -1, 0 83 | else 84 | return true 85 | return false 86 | # key 87 | else 88 | switch e.which 89 | when $.key.Plus, $.key.Plus_num 90 | # zoom in 91 | @zoom_step true 92 | when $.key.Minus, $.key.Minus_num 93 | # zoom out 94 | @zoom_step false 95 | when $.key.n8_num 96 | # pan up 97 | @pan_step 0, +1 98 | when $.key.n2_num 99 | # pan down 100 | @pan_step 0, -1 101 | when $.key.n4_num 102 | # pan left 103 | @pan_step +1, 0 104 | when $.key.n6_num 105 | # pan right 106 | @pan_step -1, 0 107 | when $.key.n7_num 108 | # pan up-left 109 | @pan_step +1, +1 110 | when $.key.n9_num 111 | # pan up-right 112 | @pan_step -1, +1 113 | when $.key.n1_num 114 | # pan down-left 115 | @pan_step +1, -1 116 | when $.key.n3_num 117 | # pan down-right 118 | @pan_step -1, -1 119 | when $.key.Slash, $.key.Slash_cyr, $.key.Slash_num 120 | # activate search field 121 | $('#search input').focus().select() 122 | return false 123 | else 124 | return true 125 | return false 126 | true 127 | $win.on 'keyup.viewer', (e)=> 128 | @wrapper.removeClass 'zoom_fit' if e.which == $.key.Ctrl 129 | # zoom on mousewheel 130 | @wrapper.on 'mousewheel.viewer', (e)=> 131 | @fix_point e.pageX-@wrapper.offset().left, e.pageY-@wrapper.offset().top 132 | factor = if e.deltaY > 0 then @Settings.zoomInStepMouse else @Settings.zoomOutStepMouse 133 | @zoom_by factor 134 | false 135 | # zoom 136 | $win.on 'dblclick.viewer', (e)=> 137 | el = $(e.target).closest('g').data('model') 138 | @find_and_zoom el if el 139 | false 140 | $('#search, #zoom-control').on 'mousedown', (e)=> 141 | e.stopPropagation() 142 | $('#search').on 'mousedown', (e)=> 143 | $('#search input').focus() 144 | # dragging 145 | @wrapper.on 'mousedown.viewer', (e)=> 146 | $.clearSelection() 147 | doc.activeElement.blur() if $.activeInput() 148 | if e.ctrlKey 149 | el = $(e.target).closest('g')[0] 150 | @zoom_fit el.instance if el 151 | return 152 | @wrapper.addClass 'dragging' 153 | @dragging = 154 | x: e.clientX, 155 | y: e.clientY 156 | e.preventDefault() 157 | false 158 | @wrapper.on 'mousemove.viewer', (e)=> 159 | return if not @dragging 160 | @div.removeClass 'smooth-transform' if @opt.smooth 161 | @pan_by e.clientX-@dragging.x, e.clientY-@dragging.y 162 | @dragging.x = e.clientX 163 | @dragging.y = e.clientY 164 | $win.on 'mouseup.viewer', (e)=> 165 | # $.clearSelection() 166 | @wrapper.trigger 'mousemove', e 167 | @wrapper.removeClass 'dragging' 168 | @dragging = null 169 | @div.addClass 'smooth-transform' if @opt.smooth 170 | # quick dragging 171 | @quickdrag.on 'mousedown.viewer', (e)=> 172 | $.clearSelection() 173 | doc.activeElement.blur() if $.activeInput() 174 | @wrapper.addClass 'dragging' 175 | @dragging = 176 | x: e.clientX, 177 | y: e.clientY 178 | e.preventDefault() 179 | false 180 | @quickdrag.on 'mousemove.viewer', (e)=> 181 | return if not @dragging 182 | @div.removeClass 'smooth-transform' if @opt.smooth 183 | @pan_by (e.clientX-@dragging.x)*5, (e.clientY-@dragging.y)*5 184 | @dragging.x = e.clientX 185 | @dragging.y = e.clientY 186 | # resize 187 | $win.on 'resize.viewer', (e)=> 188 | @update_minimap() 189 | # after smooth canvas resize 190 | if @opt.smooth 191 | @div.on 'transitionend webkitTransitionEnd oTransitionEnd', (e)=> 192 | @update_minimap() 193 | 194 | Settings: 195 | zoomInStep: 1.25 196 | zoomOutStep: 0.8 197 | zoomInStepMouse: 1.111111 198 | zoomOutStepMouse: 0.9 199 | scaleDuration: 100 # ms 200 | panStep: 100 # px 201 | minisize: 0.05 202 | miniH: 100 # px 203 | miniW: 100 # px 204 | # minZoom: 0.01 205 | # maxZoom: 50.0 206 | 207 | save_canvas_size: (w, h)-> 208 | @original_width = w || @div.width() 209 | @original_height = h || @div.height() 210 | 211 | update_minimap: -> 212 | # mini viewport 213 | vw = @wrapper.width()*@Settings.minisize 214 | vh = @wrapper.height()*@Settings.minisize 215 | vl = (@Settings.miniW-vw)/2 216 | vt = (@Settings.miniH-vh)/2 217 | @viewport.css 218 | width: vw 219 | height: vh 220 | left: vl 221 | top: vt 222 | # mini model map 223 | mw = @div.width() * @Settings.minisize 224 | mh = @div.height() * @Settings.minisize 225 | dp = @div.position() 226 | ml = dp.left * @Settings.minisize + vl 227 | mt = dp.top * @Settings.minisize + vt 228 | @minimap.css 229 | width: mw 230 | height: mh 231 | left: ml 232 | top: mt 233 | 234 | search: (query)-> 235 | if query == '' 236 | @filtered = [] 237 | @search_query = '' 238 | @controls.set 'filtered', [] 239 | return 240 | system = win.modelview?.opt?.model || null 241 | if @search_query != query 242 | @search_from = null 243 | @search_query = query 244 | @filtered = system.findAll(query) 245 | filtered = [] 246 | for el in @filtered 247 | filtered.push 248 | link: el 249 | title: system[el].nav_title() 250 | @controls.set 'filtered', filtered 251 | # !!! doesn't work for now: 252 | id = system.find query, @search_from if system 253 | @find_and_zoom id if id 254 | @search_from = id 255 | 256 | lock_zoom: (param)-> 257 | @controls.set 'zoomlock', param 258 | 259 | zoom_step: (zoomin)-> 260 | @fix_point @wrapper.width()/2, @wrapper.height()/2 261 | factor = if zoomin then @Settings.zoomInStep else @Settings.zoomOutStep 262 | @zoom_by factor 263 | 264 | zoom_by: (factor)-> 265 | scale = Math.max Theme.minzoom, Math.min(Theme.maxzoom, @scale*factor) 266 | @apply_scale scale 267 | 268 | zoom: (zoom)-> 269 | @apply_scale zoom 270 | 271 | scale_content: (scale, dx, dy)-> 272 | # console.log 'TODO: scale content for canvas to',scale 273 | 274 | apply_scale: (scale)-> 275 | @scale = scale 276 | @lock_zoom(if @scale==Theme.minzoom then 'min' else if @scale==Theme.maxzoom then 'max' else '') 277 | 278 | # gather the old properties 279 | oldw = @div.width() 280 | oldh = @div.height() 281 | oldpos = @div.position() 282 | 283 | # compute the new width and height 284 | neww = @original_width * @scale 285 | newh = @original_height * @scale 286 | 287 | # compute the new left and top 288 | newl = @fixed_x + (neww / oldw) * (oldpos.left - @fixed_x) 289 | newt = @fixed_y + (newh / oldh) * (oldpos.top - @fixed_y) 290 | 291 | # limit the new left and top to the new mins and maxes 292 | newl = Math.min(Math.max(newl, -neww), @wrapper.width()) 293 | newt = Math.min(Math.max(newt, -newh), @wrapper.height()) 294 | 295 | @scale_content(@scale, (newl-oldpos.left)/@scale, (newt-oldpos.top)/@scale).then => 296 | # save all the property updating to last 297 | @div.css 298 | width: neww 299 | height: newh 300 | left: newl 301 | top: newt 302 | 303 | @update_minimap() 304 | 305 | pan_by: (dx, dy)-> 306 | # calculate new left and top 307 | oldpos = @div.position() 308 | newl = oldpos.left+dx 309 | newt = oldpos.top+dy 310 | # limit the new left and top to the new mins and maxes 311 | newl = Math.min(Math.max(newl, -@div.width()), @wrapper.width()) 312 | newt = Math.min(Math.max(newt, -@div.height()), @wrapper.height()) 313 | # set properties 314 | @div.css 315 | left: newl 316 | top: newt 317 | @update_minimap() 318 | 319 | pan_step: (dx, dy)-> 320 | @pan_by dx*@Settings.panStep, dy*@Settings.panStep 321 | 322 | fix_point: (x, y)-> 323 | @fixed_x = x 324 | @fixed_y = y 325 | 326 | zoom_fit_all: -> 327 | @fix_point 0, 0 328 | scale = Math.min @wrapper.height()/@div.height(), @wrapper.width()/@div.width() 329 | @apply_scale scale 330 | 331 | # methods for editor: on canvas — SVG object 332 | find: (tag)-> 333 | @div.find('g[data-model="'+tag+'"]') 334 | 335 | find_and_zoom: (tag)-> 336 | el = @div.find('g[data-model="'+tag+'"]')[0] 337 | @zoom_fit el.instance if el 338 | 339 | find_and_pan: (tag)-> 340 | el = @div.find('g[data-model="'+tag+'"]')[0] 341 | @pan_to el.instance if el 342 | 343 | pan_to: (el)-> 344 | # rbox = el.rbox() # rbox stopped to work here 345 | rect = el.node.getBoundingClientRect() 346 | div_rect = @div.offset() 347 | dx = rect.left+rect.width/2-div_rect.left 348 | dy = rect.top+rect.height/2-div_rect.top 349 | @div.css 350 | left: -dx+@wrapper.width()/2 # -rbox.cx+@wrapper.width()/2 351 | top: -dy+@wrapper.height()/2 # -rbox.cy+@wrapper.height()/2 352 | @update_minimap() 353 | 354 | zoom_fit: (el)-> 355 | @fix_point 0, 0 356 | rbox = el.rbox() 357 | factor = Math.min (@wrapper.height()-Theme.margin)/rbox.height, (@wrapper.width()-Theme.margin)/rbox.width 358 | @zoom_by factor 359 | @pan_to el 360 | 361 | in_center: -> 362 | p = @wrapper.offset() 363 | x = p.left + @wrapper.width()/2 364 | y = p.top + @wrapper.height()/2 365 | node = doc.elementFromPoint x, y 366 | el = if node then $(node).closest('g').data('model') else null 367 | return el 368 | 369 | is_too_big: (tag)-> 370 | el = @div.find('g[data-model="'+tag+'"]')[0] 371 | if el 372 | rbox = el.instance.rbox() 373 | return @wrapper.height() 378 | node = @div.find('[data-model='+el+']')[0] 379 | @zoom_fit node.instance if node 380 | 381 | show_story: -> 382 | return if not @model.story 383 | $.each @model.story, (i, el)=> 384 | $doc.queue 'slides', ()=> 385 | setTimeout( ()=> 386 | @show_slide el 387 | $doc.dequeue 'slides' 388 | , Theme.slideshow) 389 | $doc.dequeue 'slides' 390 | 391 | destroy: -> 392 | @div.empty() 393 | 394 | )(jQuery, window, document) -------------------------------------------------------------------------------- /js/compiled/app-view.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | !(function($, win, doc) { 4 | var $doc, $win, def, s, style, url; 5 | $doc = $(doc); 6 | $win = $(win); 7 | def = $.Deferred(); 8 | s = location.hash.substring(1); 9 | s = s.split('##'); 10 | if (s[0]) { 11 | url = s[0]; 12 | $.ajax({ 13 | url: url, 14 | crossDomain: true, 15 | contentType: "application/json", 16 | success: function(data) { 17 | var system; 18 | system = new S({}); 19 | system.deserialize(data); 20 | return def.resolve(system); 21 | } 22 | }).fail(function() { 23 | return def.resolve(system7); 24 | }); 25 | } else { 26 | def.resolve(system7); 27 | } 28 | style = s[1] !== '' ? Math.min(win.Themes.length - 1, parseInt(s[1])) : 1; 29 | return $win.load(function() { 30 | return $.when(def).then(function(s) { 31 | var ref; 32 | win.system = s; 33 | win.Theme = win.Themes[style]; 34 | win.viewer = new Viewer({ 35 | div: 'canvas' 36 | }); 37 | win.modelview = new ModelWebView({ 38 | div: 'canvas', 39 | model: system 40 | }); 41 | return doc.title = ((ref = system[system.root]) != null ? ref.title : void 0) || 'Tectogram'; 42 | }); 43 | }); 44 | })(jQuery, window, document); 45 | 46 | //# sourceMappingURL=app-view.js.map 47 | -------------------------------------------------------------------------------- /js/compiled/app.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | !(function($, win, doc) { 4 | var $doc, $win; 5 | $doc = $(doc); 6 | $win = $(win); 7 | win.editor = win.viewer = null; 8 | win.system = win.empty_system; 9 | win.system.reload('autosave'); 10 | return $win.load(function() { 11 | win.Theme = win.Themes[0]; 12 | win.viewer = new Viewer({ 13 | div: 'canvas' 14 | }); 15 | win.modelview = new ModelWebViewEditable({ 16 | div: 'canvas', 17 | model: system 18 | }); 19 | win.editor = new Editor(system); 20 | win.editor.edit(system.root); 21 | return win.editor.load_settings(); 22 | }); 23 | })(jQuery, window, document); 24 | 25 | //# sourceMappingURL=app.js.map 26 | -------------------------------------------------------------------------------- /js/compiled/model.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | !(function($, win, doc) { 4 | var $doc, $win; 5 | $doc = $(doc); 6 | $win = $(win); 7 | win.A = (function() { 8 | function A(system, id) { 9 | $.extend(this, system); 10 | this.id = this.id || id || 'i' + Math.round(Math.random() * 100000); 11 | } 12 | 13 | A.prototype.each_element = function(func) { 14 | var i, l, len, ref, results, row; 15 | if (!this.matrix) { 16 | return; 17 | } 18 | ref = this.matrix; 19 | results = []; 20 | for (i = l = 0, len = ref.length; l < len; i = ++l) { 21 | row = ref[i]; 22 | results.push(func(this.system[row[i]], i)); 23 | } 24 | return results; 25 | }; 26 | 27 | A.prototype.each_relation = function(func) { 28 | var i, j, l, len, m, ref, results, row; 29 | if (!this.matrix) { 30 | return; 31 | } 32 | ref = this.matrix; 33 | results = []; 34 | for (i = l = 0, len = ref.length; l < len; i = ++l) { 35 | row = ref[i]; 36 | results.push((function() { 37 | var len1, n, results1; 38 | results1 = []; 39 | for (j = n = 0, len1 = row.length; n < len1; j = ++n) { 40 | m = row[j]; 41 | if (m && i !== j) { 42 | results1.push(func(this.system[m], i, j)); 43 | } else { 44 | results1.push(void 0); 45 | } 46 | } 47 | return results1; 48 | }).call(this)); 49 | } 50 | return results; 51 | }; 52 | 53 | A.prototype.each_child = function(func) { 54 | var i, j, l, len, m, ref, results, row; 55 | if (!this.matrix) { 56 | return; 57 | } 58 | ref = this.matrix; 59 | results = []; 60 | for (i = l = 0, len = ref.length; l < len; i = ++l) { 61 | row = ref[i]; 62 | results.push((function() { 63 | var len1, n, results1; 64 | results1 = []; 65 | for (j = n = 0, len1 = row.length; n < len1; j = ++n) { 66 | m = row[j]; 67 | if (m) { 68 | results1.push(func(this.system[m], i, j)); 69 | } else { 70 | results1.push(void 0); 71 | } 72 | } 73 | return results1; 74 | }).call(this)); 75 | } 76 | return results; 77 | }; 78 | 79 | A.prototype.create_child = function(id, title) { 80 | var child, i, l, len, newline, ref, row; 81 | if (title == null) { 82 | title = ''; 83 | } 84 | if (!this.matrix) { 85 | this.matrix = []; 86 | this.structure = "list.inline"; 87 | } 88 | if (id) { 89 | child = this.system[id]; 90 | } else { 91 | child = new A({ 92 | system: this.system, 93 | title: title || '[' + (this.matrix.length + 1) + '] ' + this.title 94 | }); 95 | this.system[child.id] = child; 96 | } 97 | newline = []; 98 | ref = this.matrix; 99 | for (i = l = 0, len = ref.length; l < len; i = ++l) { 100 | row = ref[i]; 101 | row.push(null); 102 | newline.push(null); 103 | } 104 | newline.push(child.id); 105 | this.matrix.push(newline); 106 | return child.id; 107 | }; 108 | 109 | A.prototype.create_sibling_shift = function(shift) { 110 | var i, l, len, len1, n, newline, parent, pmatrix, pos, row, sibling; 111 | parent = this.system.parent_of(this.id); 112 | pmatrix = this.system[parent].matrix; 113 | sibling = new A({ 114 | system: this.system, 115 | title: '[' + (pmatrix.length + 1) + '] ' + this.system[parent].title 116 | }); 117 | this.system[sibling.id] = sibling; 118 | for (i = l = 0, len = pmatrix.length; l < len; i = ++l) { 119 | row = pmatrix[i]; 120 | if (row[i] === this.id) { 121 | break; 122 | } 123 | } 124 | pos = i + shift; 125 | newline = []; 126 | for (i = n = 0, len1 = pmatrix.length; n < len1; i = ++n) { 127 | row = pmatrix[i]; 128 | row.splice(pos, 0, null); 129 | newline.push(null); 130 | } 131 | newline.splice(pos, 0, sibling.id); 132 | pmatrix.splice(pos, 0, newline); 133 | return sibling.id; 134 | }; 135 | 136 | A.prototype.create_sibling_before = function() { 137 | return this.create_sibling_shift(0); 138 | }; 139 | 140 | A.prototype.create_sibling_after = function() { 141 | return this.create_sibling_shift(+1); 142 | }; 143 | 144 | A.prototype.create_relation = function(id1, id2) { 145 | var i, j, k, l, len, ref, relation, row; 146 | ref = this.matrix; 147 | for (k = l = 0, len = ref.length; l < len; k = ++l) { 148 | row = ref[k]; 149 | if (row[k] === id1) { 150 | i = k; 151 | } 152 | if (row[k] === id2) { 153 | j = k; 154 | } 155 | } 156 | if (this.matrix[i][j]) { 157 | return this.matrix[i][j]; 158 | } 159 | relation = new A({ 160 | system: this.system, 161 | title: this.system[id1].nav_title() + ' → ' + this.system[id2].nav_title() 162 | }); 163 | this.system[relation.id] = relation; 164 | this.matrix[i][j] = relation.id; 165 | return relation.id; 166 | }; 167 | 168 | A.prototype.delete_child = function(id, leave) { 169 | var i, j, l, len, len1, len2, m, n, o, ref, ref1, results, row; 170 | if (!leave) { 171 | delete this.system[id]; 172 | } 173 | ref = this.matrix; 174 | for (i = l = 0, len = ref.length; l < len; i = ++l) { 175 | row = ref[i]; 176 | if (row[i] === id) { 177 | break; 178 | } 179 | for (j = n = 0, len1 = row.length; n < len1; j = ++n) { 180 | m = row[j]; 181 | if (m === id && i !== j) { 182 | this.matrix[i][j] = null; 183 | return; 184 | } 185 | } 186 | } 187 | this.each_relation((function(_this) { 188 | return function(rel, ri, rj) { 189 | if (ri === i || rj === i) { 190 | return delete _this.system[rel.id]; 191 | } 192 | }; 193 | })(this)); 194 | this.matrix.splice(i, 1); 195 | ref1 = this.matrix; 196 | results = []; 197 | for (o = 0, len2 = ref1.length; o < len2; o++) { 198 | row = ref1[o]; 199 | results.push(row.splice(i, 1)); 200 | } 201 | return results; 202 | }; 203 | 204 | A.prototype.move_child = function(id, step) { 205 | var e, i, j, l, len, len1, n, r, ref, ref1, row, row1; 206 | ref = this.matrix; 207 | for (i = l = 0, len = ref.length; l < len; i = ++l) { 208 | row = ref[i]; 209 | j = i + step; 210 | if (row[i] === id && this.matrix[j] && this.matrix[j][j]) { 211 | ref1 = this.matrix; 212 | for (n = 0, len1 = ref1.length; n < len1; n++) { 213 | row1 = ref1[n]; 214 | e = row1[i]; 215 | row1[i] = row1[j]; 216 | row1[j] = e; 217 | } 218 | r = this.matrix[i]; 219 | this.matrix[i] = this.matrix[j]; 220 | this.matrix[j] = r; 221 | return; 222 | } 223 | } 224 | }; 225 | 226 | A.prototype.next_sibling = function(id) { 227 | var i, j, l, len, ref, row; 228 | ref = this.matrix; 229 | for (i = l = 0, len = ref.length; l < len; i = ++l) { 230 | row = ref[i]; 231 | j = i + 1; 232 | if (row[i] === id && this.matrix[j] && this.matrix[j][j]) { 233 | return this.matrix[j][j]; 234 | } 235 | } 236 | return null; 237 | }; 238 | 239 | A.prototype.nav_title = function() { 240 | if (this.title && !/^\s*$/.test(this.title)) { 241 | return this.title; 242 | } else if (this.description) { 243 | return this.description.split('\n')[0]; 244 | } else { 245 | return this.id; 246 | } 247 | }; 248 | 249 | A.prototype.match = function(regexp) { 250 | return (this.title && this.title.match(regexp)) || (this.description && this.description.match(regexp)); 251 | }; 252 | 253 | return A; 254 | 255 | })(); 256 | return win.S = (function() { 257 | function S(system) { 258 | var a, key; 259 | $.extend(this, system); 260 | for (key in this) { 261 | a = this[key]; 262 | if (a instanceof A) { 263 | a.system = this; 264 | a.id = key; 265 | } 266 | } 267 | } 268 | 269 | S.prototype.parent_of = function(child) { 270 | var element, id, l, len, len1, model, n, ref, row; 271 | for (id in this) { 272 | model = this[id]; 273 | if (model.matrix) { 274 | ref = model.matrix; 275 | for (l = 0, len = ref.length; l < len; l++) { 276 | row = ref[l]; 277 | for (n = 0, len1 = row.length; n < len1; n++) { 278 | element = row[n]; 279 | if (element && element === child) { 280 | return id; 281 | } 282 | } 283 | } 284 | } 285 | } 286 | return null; 287 | }; 288 | 289 | S.prototype.depth_of = function(id) { 290 | var d, el; 291 | el = this[id]; 292 | if (el.matrix) { 293 | d = 0; 294 | el.each_element((function(_this) { 295 | return function(child) { 296 | return d = Math.max(d, _this.depth_of(child.id)); 297 | }; 298 | })(this)); 299 | return d + 1; 300 | } else { 301 | return 0; 302 | } 303 | }; 304 | 305 | S.prototype.height = function() { 306 | return this.depth_of(this.root) + 1; 307 | }; 308 | 309 | S.prototype.rebuild = function(s) { 310 | var a, key, results; 311 | for (key in this) { 312 | a = this[key]; 313 | if (a instanceof A) { 314 | delete this[key]; 315 | } 316 | } 317 | results = []; 318 | for (key in s) { 319 | a = s[key]; 320 | if (key === 'root' || key === 'story') { 321 | results.push(this[key] = a); 322 | } else { 323 | this[key] = new A(a); 324 | results.push(this[key].system = this); 325 | } 326 | } 327 | return results; 328 | }; 329 | 330 | S.prototype.serialize = function() { 331 | return JSON.stringify(this, function(key, value) { 332 | if (key === "system") { 333 | return void 0; 334 | } else { 335 | return value; 336 | } 337 | }); 338 | }; 339 | 340 | S.prototype.deserialize = function(s) { 341 | return this.rebuild(JSON.parse(s)); 342 | }; 343 | 344 | S.prototype.save = function(key) { 345 | var s; 346 | key = key || 'system'; 347 | s = this.serialize(); 348 | return localStorage.setItem(key, s); 349 | }; 350 | 351 | S.prototype.reload = function(key) { 352 | var s; 353 | key = key || 'system'; 354 | s = localStorage.getItem(key); 355 | if (s) { 356 | return this.deserialize(s); 357 | } 358 | }; 359 | 360 | S.prototype.find = function(query, from) { 361 | var a, key, reg, search_on; 362 | reg = new RegExp(RegExp.escape(query), 'gi'); 363 | search_on = from == null; 364 | for (key in this) { 365 | a = this[key]; 366 | if (a instanceof A) { 367 | if (search_on && a.match(reg)) { 368 | return key; 369 | } 370 | if (!search_on && key === from) { 371 | search_on = true; 372 | } 373 | } 374 | } 375 | return null; 376 | }; 377 | 378 | S.prototype.findAll = function(query) { 379 | var a, key, reg, res; 380 | reg = new RegExp(RegExp.escape(query), 'gi'); 381 | res = []; 382 | for (key in this) { 383 | a = this[key]; 384 | if (a instanceof A && a.match(reg)) { 385 | res.push(key); 386 | } 387 | } 388 | return res; 389 | }; 390 | 391 | return S; 392 | 393 | })(); 394 | })(jQuery, window, document); 395 | 396 | //# sourceMappingURL=model.js.map 397 | -------------------------------------------------------------------------------- /js/compiled/template.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | !(function($, win, doc) { 4 | var $doc, $win; 5 | $doc = $(doc); 6 | $win = $(win); 7 | return win.Template = (function() { 8 | function Template(options) { 9 | var defaults; 10 | defaults = { 11 | cont: '' 12 | }; 13 | this.opt = $.extend({}, defaults, options); 14 | this.cont = $(this.opt.cont); 15 | this.build_content(); 16 | this.controller(); 17 | } 18 | 19 | Template.prototype.build_content = function() { 20 | var T, results, tpl; 21 | T = {}; 22 | T.footer = "footer.container-fluid\n .row\n .col-xs-12.small\n p\n | © ParetoNews 2014   \n a href=\"#\"\n =t 'footer.blog'\n |  · \n a href=\"#\"\n =t 'footer.help'\n |  · \n a href=\"#\"\n =t 'footer.faq'\n |  · \n a href=\"#\"\n =t 'footer.terms'\n |  · \n a href=\"#\"\n =t 'footer.privacy'"; 23 | this.div = $('
'); 24 | this.create_tpl('application', ".content = outlet"); 25 | results = []; 26 | for (tpl in T) { 27 | results.push(this.create_tpl(tpl, T[tpl])); 28 | } 29 | return results; 30 | }; 31 | 32 | Template.prototype.controller = function() {}; 33 | 34 | Template.prototype.compile = function(source, data) { 35 | var template; 36 | template = Emblem.compile(Handlebars, source); 37 | return template(data); 38 | }; 39 | 40 | Template.prototype.create_tpl = function(id, source) { 41 | return $('body').append(""); 42 | }; 43 | 44 | Template.prototype.destroy = function() { 45 | this.div.remove(); 46 | return this.div = null; 47 | }; 48 | 49 | return Template; 50 | 51 | })(); 52 | })(jQuery, window, document); 53 | 54 | //# sourceMappingURL=template.js.map 55 | -------------------------------------------------------------------------------- /js/compiled/text-import.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | !(function($, win, doc) { 4 | var $doc, $win; 5 | $doc = $(doc); 6 | $win = $(win); 7 | return win.TEXTreader = (function() { 8 | function TEXTreader(options) { 9 | var defaults; 10 | defaults = { 11 | text: {} 12 | }; 13 | this.opt = $.extend({}, defaults, options); 14 | this.lines = this.opt.text.split('\n'); 15 | this.i = 0; 16 | this.build_content(); 17 | } 18 | 19 | TEXTreader.prototype.build_content = function() { 20 | return this.read(); 21 | }; 22 | 23 | TEXTreader.prototype.read_element = function(lines, el) { 24 | var desc, description, ill, j, line, link, m, skip, struct, title; 25 | line = lines[0]; 26 | m = line.match(/^\-\s(.*)$/); 27 | if (m) { 28 | title = m[1]; 29 | } 30 | j = 1; 31 | struct = []; 32 | desc = []; 33 | while (lines[j] && lines[j].substr(0, 2) === ' ') { 34 | line = lines[j].replace(/^\s\s/, ''); 35 | j++; 36 | if (!line) { 37 | continue; 38 | } 39 | m = line.match(/^\[(.*)\]$/); 40 | if (m) { 41 | link = m[1]; 42 | skip = true; 43 | } else { 44 | m = line.match(/^Илл\.\:\s(.*)$/); 45 | if (m) { 46 | ill = m[1]; 47 | skip = true; 48 | } else { 49 | skip = false; 50 | } 51 | } 52 | if (line.substr(0, 2) === ' ' || line.substr(0, 2) === '- ') { 53 | struct.push(line); 54 | } else { 55 | if (!skip) { 56 | desc.push(line); 57 | } 58 | } 59 | } 60 | description = desc.join('\n'); 61 | el.title = title || ''; 62 | el.description = description || ''; 63 | if (link) { 64 | el.link = { 65 | url: link 66 | }; 67 | } 68 | if (ill) { 69 | el.picture = { 70 | url: ill, 71 | width: 100, 72 | height: 100 73 | }; 74 | } 75 | return this.read_structure(struct, el); 76 | }; 77 | 78 | TEXTreader.prototype.read_structure = function(lines, el) { 79 | var C, child, children, i, k, len; 80 | children = lines.join('\n'); 81 | if (!children) { 82 | return; 83 | } 84 | children = children.split('\n- '); 85 | for (i = k = 0, len = children.length; k < len; i = ++k) { 86 | child = children[i]; 87 | if (i > 0) { 88 | child = '- ' + child; 89 | } 90 | lines = child.split('\n'); 91 | C = el.create_child(); 92 | C = this.system[C]; 93 | this.read_element(lines, C); 94 | } 95 | return el.structure = 'list.bricks'; 96 | }; 97 | 98 | TEXTreader.prototype.read = function() { 99 | this.system = new S({ 100 | root: 'iSystem', 101 | iSystem: new A({ 102 | title: 'New' 103 | }) 104 | }); 105 | this.read_element(this.lines, this.system.iSystem); 106 | return this.system; 107 | }; 108 | 109 | return TEXTreader; 110 | 111 | })(); 112 | })(jQuery, window, document); 113 | 114 | //# sourceMappingURL=text-import.js.map 115 | -------------------------------------------------------------------------------- /js/compiled/text-render.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 4 | hasProp = {}.hasOwnProperty; 5 | 6 | !(function($, win, doc) { 7 | var $doc, $win; 8 | $doc = $(doc); 9 | $win = $(win); 10 | win.TEXTrender = (function() { 11 | function TEXTrender(options) { 12 | var defaults; 13 | defaults = { 14 | model: {} 15 | }; 16 | this.opt = $.extend({}, defaults, options); 17 | this.model = this.opt.model; 18 | this.build_content(); 19 | } 20 | 21 | TEXTrender.prototype.build_content = function() { 22 | return this.render(); 23 | }; 24 | 25 | TEXTrender.prototype.render = function() { 26 | var model, system; 27 | model = this.model[this.model.root]; 28 | system = new TEXTElement({ 29 | id: this.model.root, 30 | level: 0, 31 | model: model 32 | }); 33 | return system.render(); 34 | }; 35 | 36 | return TEXTrender; 37 | 38 | })(); 39 | win.XObj = (function() { 40 | function XObj(options) { 41 | var defaults; 42 | defaults = { 43 | model: {} 44 | }; 45 | this.opt = $.extend({}, defaults, options); 46 | this.model = this.opt.model; 47 | this.level = this.opt.level; 48 | this.indent = this.make_indent(this.level); 49 | } 50 | 51 | XObj.prototype.render = function() { 52 | return model.title; 53 | }; 54 | 55 | XObj.prototype.make_indent = function(tabs) { 56 | var i, indent, k, ref; 57 | indent = ''; 58 | for (i = k = 0, ref = tabs; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { 59 | indent += ' '; 60 | } 61 | return indent; 62 | }; 63 | 64 | return XObj; 65 | 66 | })(); 67 | win.TEXTElement = (function(superClass) { 68 | extend(TEXTElement, superClass); 69 | 70 | function TEXTElement(options) { 71 | TEXTElement.__super__.constructor.call(this, options); 72 | } 73 | 74 | TEXTElement.prototype.render = function() { 75 | var t; 76 | t = ''; 77 | t += this.indent + '- ' + (this.model.title || ''); 78 | if (this.model.link && this.model.link.url) { 79 | t += '\n' + this.indent + ' [' + this.model.link.url + ']'; 80 | } 81 | if (this.model.description) { 82 | t += '\n' + this.indent + ' ' + this.model.description.replace(/\n/g, '\n' + this.indent + ' '); 83 | } 84 | if (this.model.picture && this.model.picture.url) { 85 | t += '\n' + this.indent + 'Илл.: ' + this.model.picture.url; 86 | } 87 | if (this.model.structure) { 88 | t += this.render_structure(); 89 | } 90 | return t; 91 | }; 92 | 93 | TEXTElement.prototype.render_structure = function(x, y, w, ready) { 94 | this.structure = new TEXTStructure({ 95 | model: this.model, 96 | level: this.level 97 | }); 98 | return this.structure.render(); 99 | }; 100 | 101 | return TEXTElement; 102 | 103 | })(XObj); 104 | win.TEXTStructure = (function(superClass) { 105 | extend(TEXTStructure, superClass); 106 | 107 | function TEXTStructure(options) { 108 | TEXTStructure.__super__.constructor.call(this, options); 109 | } 110 | 111 | TEXTStructure.prototype.render = function() { 112 | var relations, t; 113 | t = ''; 114 | relations = false; 115 | this.model.each_element((function(_this) { 116 | return function(model, i) { 117 | var j, k, len, ref, rel, results; 118 | t += '\n' + _this.render_element(model); 119 | ref = _this.model.matrix[i]; 120 | results = []; 121 | for (j = k = 0, len = ref.length; k < len; j = ++k) { 122 | rel = ref[j]; 123 | if (j === i || !rel || !_this.model.system[rel]) { 124 | continue; 125 | } 126 | results.push(t += '\n' + _this.render_element(_this.model.system[rel])); 127 | } 128 | return results; 129 | }; 130 | })(this)); 131 | return t; 132 | }; 133 | 134 | TEXTStructure.prototype.render_element = function(model) { 135 | var element; 136 | element = new TEXTElement({ 137 | id: model.id, 138 | model: model, 139 | level: this.level + 1 140 | }); 141 | return element.render(); 142 | }; 143 | 144 | return TEXTStructure; 145 | 146 | })(XObj); 147 | win.XMLrender = (function(superClass) { 148 | extend(XMLrender, superClass); 149 | 150 | function XMLrender(options) { 151 | XMLrender.__super__.constructor.call(this, options); 152 | } 153 | 154 | XMLrender.prototype.render = function() { 155 | var model, system; 156 | model = this.model[this.model.root]; 157 | system = new XMLElement({ 158 | id: this.model.root, 159 | level: 0, 160 | type: 'element', 161 | model: model 162 | }); 163 | return '\n\n' + system.render() + '\n'; 164 | }; 165 | 166 | return XMLrender; 167 | 168 | })(TEXTrender); 169 | win.XMLElement = (function(superClass) { 170 | extend(XMLElement, superClass); 171 | 172 | function XMLElement(options) { 173 | XMLElement.__super__.constructor.call(this, options); 174 | this.indent = this.make_indent(this.level + 1); 175 | this.indent2 = this.make_indent(this.level + 2); 176 | } 177 | 178 | XMLElement.prototype.render = function() { 179 | var t; 180 | t = this.indent + ''; 181 | if (this.model.title) { 182 | t += '\n' + this.indent2 + '' + $.escape(this.model.title || '') + ''; 183 | } 184 | if (this.model.link && this.model.link.url) { 185 | t += '\n' + this.indent2 + '' + this.model.link.url + ''; 186 | } 187 | if (this.model.description) { 188 | t += '\n' + this.indent2 + '' + $.escape(this.model.description) + ''; 189 | } 190 | if (this.model.picture && this.model.picture.url) { 191 | t += '\n' + this.indent2 + ''; 192 | } 193 | if (this.model.structure) { 194 | t += this.render_structure(); 195 | } 196 | return t + '\n' + this.indent + ''; 197 | }; 198 | 199 | XMLElement.prototype.render_structure = function(x, y, w, ready) { 200 | this.structure = new XMLStructure({ 201 | model: this.model, 202 | level: this.level + 1 203 | }); 204 | return this.structure.render(); 205 | }; 206 | 207 | return XMLElement; 208 | 209 | })(XObj); 210 | win.XMLStructure = (function(superClass) { 211 | extend(XMLStructure, superClass); 212 | 213 | function XMLStructure(options) { 214 | XMLStructure.__super__.constructor.call(this, options); 215 | this.indent = this.make_indent(this.level + 1); 216 | } 217 | 218 | XMLStructure.prototype.render = function() { 219 | var relations, t; 220 | t = '\n' + this.indent + ''; 221 | relations = false; 222 | this.model.each_element((function(_this) { 223 | return function(model, i) { 224 | var j, k, len, ref, rel, results; 225 | t += '\n' + _this.render_element(model, 'element'); 226 | ref = _this.model.matrix[i]; 227 | results = []; 228 | for (j = k = 0, len = ref.length; k < len; j = ++k) { 229 | rel = ref[j]; 230 | if (j === i || !rel || !_this.model.system[rel]) { 231 | continue; 232 | } 233 | results.push(t += '\n' + _this.render_element(_this.model.system[rel], 'relation')); 234 | } 235 | return results; 236 | }; 237 | })(this)); 238 | return t + '\n' + this.indent + ''; 239 | }; 240 | 241 | XMLStructure.prototype.render_element = function(model, type) { 242 | var element; 243 | element = new XMLElement({ 244 | id: model.id, 245 | model: model, 246 | type: type, 247 | level: this.level + 1 248 | }); 249 | return element.render(); 250 | }; 251 | 252 | return XMLStructure; 253 | 254 | })(XObj); 255 | win.HTMLrender = (function(superClass) { 256 | extend(HTMLrender, superClass); 257 | 258 | function HTMLrender(options) { 259 | HTMLrender.__super__.constructor.call(this, options); 260 | } 261 | 262 | HTMLrender.prototype.render = function() { 263 | var model, system; 264 | model = this.model[this.model.root]; 265 | system = new HTMLElement({ 266 | id: this.model.root, 267 | level: 0, 268 | type: 'element', 269 | model: model 270 | }); 271 | return '
    ' + system.render() + '
'; 272 | }; 273 | 274 | return HTMLrender; 275 | 276 | })(TEXTrender); 277 | win.HTMLElement = (function(superClass) { 278 | extend(HTMLElement, superClass); 279 | 280 | function HTMLElement(options) { 281 | HTMLElement.__super__.constructor.call(this, options); 282 | if (!this.opt.tag) { 283 | this.opt.tag = 'li'; 284 | } 285 | } 286 | 287 | HTMLElement.prototype.render = function() { 288 | var t; 289 | t = '<' + this.opt.tag + ' class="' + this.opt.type + ' level-' + this.level + '">'; 290 | if (this.model.title) { 291 | t += '

' + $.escape(this.model.title || '') + '

'; 292 | } 293 | if (this.model.link && this.model.link.url) { 294 | t += '' + this.model.link.url + ''; 295 | } 296 | if (this.model.description) { 297 | t += '

' + $.escape(this.model.description).replace(/\n/g, '
') + '

'; 298 | } 299 | if (this.model.picture && this.model.picture.url) { 300 | if (this.model.picture.video) { 301 | t += this.model.picture.video + 'Video'; 302 | } else { 303 | t += ''; 304 | } 305 | } 306 | if (this.model.structure) { 307 | t += this.render_structure(); 308 | } 309 | return t + ''; 310 | }; 311 | 312 | HTMLElement.prototype.render_structure = function(x, y, w, ready) { 313 | this.structure = new HTMLStructure({ 314 | model: this.model, 315 | level: this.level 316 | }); 317 | return this.structure.render(); 318 | }; 319 | 320 | return HTMLElement; 321 | 322 | })(XObj); 323 | return win.HTMLStructure = (function(superClass) { 324 | extend(HTMLStructure, superClass); 325 | 326 | function HTMLStructure(options) { 327 | HTMLStructure.__super__.constructor.call(this, options); 328 | } 329 | 330 | HTMLStructure.prototype.render = function() { 331 | var ref; 332 | if ((ref = this.model.structure) === 'graph' || ref === 'matrix') { 333 | return this.render_table(); 334 | } else { 335 | return this.render_list(); 336 | } 337 | }; 338 | 339 | HTMLStructure.prototype.render_table = function() { 340 | var t; 341 | t = ''; 342 | this.model.each_element((function(_this) { 343 | return function(model, i) { 344 | var j, k, len, ref, rel, type; 345 | t += ''; 346 | ref = _this.model.matrix[i]; 347 | for (j = k = 0, len = ref.length; k < len; j = ++k) { 348 | rel = ref[j]; 349 | if (rel && _this.model.system[rel]) { 350 | type = i === j ? 'element' : 'relation'; 351 | t += _this.render_element(_this.model.system[rel], type, 'td'); 352 | } else { 353 | t += ''; 354 | } 355 | } 356 | return t += ''; 357 | }; 358 | })(this)); 359 | return t + '
'; 360 | }; 361 | 362 | HTMLStructure.prototype.render_list = function() { 363 | var relations, t; 364 | t = '
    '; 365 | relations = false; 366 | this.model.each_element((function(_this) { 367 | return function(model, i) { 368 | var j, k, len, ref, rel, results; 369 | t += _this.render_element(model, 'element', 'li'); 370 | ref = _this.model.matrix[i]; 371 | results = []; 372 | for (j = k = 0, len = ref.length; k < len; j = ++k) { 373 | rel = ref[j]; 374 | if (j === i || !rel || !_this.model.system[rel]) { 375 | continue; 376 | } 377 | results.push(t += _this.render_element(_this.model.system[rel], 'relation', 'li')); 378 | } 379 | return results; 380 | }; 381 | })(this)); 382 | return t + '
'; 383 | }; 384 | 385 | HTMLStructure.prototype.render_element = function(model, type, tag) { 386 | var element; 387 | element = new HTMLElement({ 388 | id: model.id, 389 | model: model, 390 | type: type, 391 | tag: tag, 392 | level: this.level + 1 393 | }); 394 | return element.render(); 395 | }; 396 | 397 | return HTMLStructure; 398 | 399 | })(XObj); 400 | })(jQuery, window, document); 401 | 402 | //# sourceMappingURL=text-render.js.map 403 | -------------------------------------------------------------------------------- /js/compiled/themes.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | !(function($, win, doc) { 4 | var $doc, $win; 5 | $doc = $(doc); 6 | $win = $(win); 7 | win.ThemeGen = (function() { 8 | function ThemeGen(options) { 9 | var Levels, defaults, i, j, k, ref, ref1, s; 10 | defaults = { 11 | title: '', 12 | basefontsize: 7812.5, 13 | K: 2.5, 14 | xSpace: 2.5, 15 | xStroke: 0.02, 16 | xCellp: 0.16, 17 | xImgsize: 10, 18 | xWidth: 20, 19 | minfontsize: 5.98, 20 | max_imgwidth: 300, 21 | margin: 20, 22 | markersize: 5, 23 | fontFamily: "PT Sans", 24 | lineHeight: 1.25, 25 | rel_opacity: 0.8, 26 | toplevel: 1, 27 | slideshow: 2000, 28 | color: { 29 | text: '#000000', 30 | background: '#FFFFFF', 31 | selected: { 32 | stroke: '#8DBEFF', 33 | fill: '#FFFFE2' 34 | }, 35 | stroke: '#C0C0C0', 36 | mask: '#C0C0C0', 37 | found: '#E5FF00', 38 | bullet: '#C0C0C0', 39 | emphasis: '#F08010', 40 | link: '#4F7FCE', 41 | link_hover: '#2020F0' 42 | } 43 | }; 44 | $.extend(true, this, defaults, options); 45 | Levels = 10; 46 | this.sizes = [this.basefontsize]; 47 | for (i = j = 0, ref = Levels; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { 48 | this.sizes.push(this.sizes[i] / this.K); 49 | } 50 | this.spaces = []; 51 | this.strokes = []; 52 | this.cellp = []; 53 | this.imgsize = []; 54 | this.width = []; 55 | for (i = k = 0, ref1 = Levels; 0 <= ref1 ? k < ref1 : k > ref1; i = 0 <= ref1 ? ++k : --k) { 56 | s = this.sizes[i]; 57 | this.spaces.push(s * this.xSpace); 58 | this.strokes.push(s * this.xStroke); 59 | this.cellp.push(s * this.xCellp); 60 | this.imgsize.push(s * this.xImgsize); 61 | this.width.push(s * this.xWidth); 62 | } 63 | this.maxzoom = 1 / this.strokes[this.strokes.length - 1]; 64 | this.minzoom = this.minfontsize / this.sizes[this.toplevel + 1]; 65 | } 66 | 67 | ThemeGen.prototype.threshold = function(s) { 68 | var fs, i, j, len, ref; 69 | ref = this.sizes; 70 | for (i = j = 0, len = ref.length; j < len; i = ++j) { 71 | fs = ref[i]; 72 | if (this.minfontsize > fs * s) { 73 | return i; 74 | } 75 | } 76 | return this.sizes.length; 77 | }; 78 | 79 | return ThemeGen; 80 | 81 | })(); 82 | win.Themes = []; 83 | win.Themes.push(new ThemeGen({ 84 | title: 'Веб', 85 | basefontsize: 7812.5, 86 | K: 2.5, 87 | max_imgwidth: 300, 88 | margin: 20, 89 | markersize: 5, 90 | fontFamily: "PT Sans", 91 | lineHeight: 1.25, 92 | slideshow: 2000, 93 | color: { 94 | selected: { 95 | stroke: '#8DBEFF', 96 | fill: '#FFFFE2' 97 | }, 98 | bullet: '#C0C0C0', 99 | mask: '#C0C0C0', 100 | emphasis: '#F08010', 101 | link: '#4F7FCE', 102 | link_hover: '#2020F0' 103 | } 104 | })); 105 | win.Themes.push(new ThemeGen({ 106 | title: 'Презентация', 107 | K: 2.5, 108 | fontFamily: 'Trebuchet MS', 109 | lineHeight: 1.33, 110 | color: { 111 | background: '#F4F4F3', 112 | text: '#36424E', 113 | bullet: '#36424E', 114 | stroke: '#36424E', 115 | mask: '#D5D8D6', 116 | emphasis: '#70A3EF', 117 | link: '#7491BC', 118 | link_hover: '#70A3EF', 119 | selected: { 120 | stroke: '#2D261D', 121 | fill: '#2D261D' 122 | } 123 | } 124 | })); 125 | win.Themes.push(new ThemeGen({ 126 | title: 'Книга', 127 | K: 2.5, 128 | fontFamily: 'Georgia', 129 | lineHeight: 1.33, 130 | color: { 131 | bullet: '#A0A0A0', 132 | mask: '#A0A0A0', 133 | emphasis: '#FF3333' 134 | } 135 | })); 136 | win.Themes.push(new ThemeGen({ 137 | title: 'Старая книга', 138 | K: 2.5, 139 | fontFamily: 'Georgia', 140 | lineHeight: 1.5, 141 | color: { 142 | background: '#FDE7B2', 143 | text: '#371C07', 144 | bullet: '#BD8E58', 145 | stroke: '#63481E', 146 | mask: '#BD8E58', 147 | emphasis: '#862400', 148 | link: '#B4794A', 149 | link_hover: '#FFDA73', 150 | selected: { 151 | stroke: '#2D261D', 152 | fill: '#2D261D' 153 | } 154 | } 155 | })); 156 | win.Themes.push(new ThemeGen({ 157 | title: 'Печатная машинка', 158 | K: 2, 159 | fontFamily: 'courier new', 160 | color: { 161 | text: '#333333', 162 | emphasis: '#FF3333' 163 | } 164 | })); 165 | win.Themes.push(new ThemeGen({ 166 | title: 'Рукопись 1', 167 | K: 2, 168 | xStroke: 0.085, 169 | markersize: 1.5, 170 | fontFamily: 'comic sans ms', 171 | lineHeight: 1.15 172 | })); 173 | win.Themes.push(new ThemeGen({ 174 | title: 'Рукопись 2', 175 | K: 2.25, 176 | fontFamily: 'Neucha', 177 | lineHeight: 1.15, 178 | color: { 179 | emphasis: '#F9AF33' 180 | } 181 | })); 182 | return win.Theme = win.Themes[0]; 183 | })(jQuery, window, document); 184 | 185 | //# sourceMappingURL=themes.js.map 186 | -------------------------------------------------------------------------------- /js/compiled/utils.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | var Rand; 4 | 5 | RegExp.escape = function(text) { 6 | return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 7 | }; 8 | 9 | Rand = { 10 | seed: 1, 11 | reset: function() { 12 | return this.seed = 1; 13 | }, 14 | random: function() { 15 | this.seed = this.seed * 40692 % 2147483399; 16 | return this.seed / 2147483399; 17 | } 18 | }; 19 | 20 | !(function($, win, doc) { 21 | var $doc, $win; 22 | $doc = $(doc); 23 | $win = $(win); 24 | $.key = { 25 | Enter: 13, 26 | Esc: 27, 27 | Down: 40, 28 | Up: 38, 29 | Left: 37, 30 | Right: 39, 31 | Tab: 9, 32 | Backspace: 8, 33 | Space: 32, 34 | Plus: 187, 35 | Minus: 189, 36 | Slash_cyr: 190, 37 | Slash: 191, 38 | Shift: 16, 39 | Ctrl: 17, 40 | PgUp: 33, 41 | PgDn: 34, 42 | End: 35, 43 | Home: 36, 44 | Ins: 45, 45 | Del: 46, 46 | n1: 49, 47 | n2: 50, 48 | n3: 51, 49 | n4: 52, 50 | n5: 53, 51 | A: 65, 52 | D: 68, 53 | F: 70, 54 | G: 71, 55 | H: 72, 56 | I: 73, 57 | J: 74, 58 | K: 75, 59 | L: 76, 60 | R: 82, 61 | S: 83, 62 | T: 84, 63 | U: 85, 64 | V: 86, 65 | W: 87, 66 | X: 88, 67 | Y: 89, 68 | Z: 90, 69 | n1_num: 97, 70 | n2_num: 98, 71 | n3_num: 99, 72 | n4_num: 100, 73 | n5_num: 101, 74 | n6_num: 102, 75 | n7_num: 103, 76 | n8_num: 104, 77 | n9_num: 105, 78 | Star_num: 106, 79 | Plus_num: 107, 80 | Minus_num: 109, 81 | Slash_num: 111 82 | }; 83 | $.activeInput = function() { 84 | var tag; 85 | tag = doc.activeElement.tagName; 86 | return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || doc.activeElement.contentEditable === 'true'; 87 | }; 88 | $.clearSelection = function() { 89 | var sel; 90 | if (doc.selection && doc.selection.empty) { 91 | return doc.selection.empty; 92 | } else if (win.getSelection) { 93 | sel = win.getSelection(); 94 | return sel.removeAllRanges(); 95 | } 96 | }; 97 | $.selectContents = function(id) { 98 | var el, range, sel; 99 | el = doc.getElementById(id); 100 | range = doc.createRange(); 101 | range.selectNodeContents(el); 102 | sel = win.getSelection(); 103 | sel.removeAllRanges(); 104 | return sel.addRange(range); 105 | }; 106 | $.selection = function() { 107 | var s, sel; 108 | s = ''; 109 | if (win.getSelection) { 110 | sel = win.getSelection(); 111 | s = sel.toString(); 112 | } 113 | return s; 114 | }; 115 | $.escape = function(text) { 116 | return text.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); 117 | }; 118 | $.fn.svgRemoveClass = function(c) { 119 | return this.each(function(i, el) { 120 | var ref; 121 | return (ref = el.instance) != null ? ref.removeClass(c) : void 0; 122 | }); 123 | }; 124 | $.fn.svgAddClass = function(c) { 125 | return this.each(function(i, el) { 126 | var ref; 127 | return (ref = el.instance) != null ? ref.addClass(c) : void 0; 128 | }); 129 | }; 130 | return $.browser = { 131 | firefox: navigator.userAgent.toLowerCase().indexOf('firefox') > -1 132 | }; 133 | })(jQuery, window, document); 134 | 135 | //# sourceMappingURL=utils.js.map 136 | -------------------------------------------------------------------------------- /js/compiled/viewer.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | "use strict"; 3 | !(function($, win, doc) { 4 | var $doc, $win; 5 | $doc = $(doc); 6 | $win = $(win); 7 | return win.Viewer = (function() { 8 | function Viewer(options) { 9 | var defaults; 10 | defaults = { 11 | div: 'canvas', 12 | model: {}, 13 | smooth: false, 14 | svg: null 15 | }; 16 | this.opt = $.extend({}, defaults, options); 17 | this.div = $('#' + this.opt.div); 18 | this.wrapper = this.div.parent(); 19 | this.build_content(); 20 | this.controller(); 21 | } 22 | 23 | Viewer.prototype.build_content = function() { 24 | this.scale = 1; 25 | this.save_canvas_size(); 26 | this.controls = new Ractive({ 27 | el: 'controls', 28 | template: '#map-controls', 29 | data: { 30 | zoomlock: '', 31 | is_drawing: false, 32 | progress: 0 33 | } 34 | }); 35 | this.minimap = $('#minimap .model'); 36 | this.viewport = $('#minimap .view'); 37 | this.quickdrag = $('#minimap .map'); 38 | this.wrapper.addClass('drag'); 39 | if (this.opt.smooth) { 40 | this.div.addClass('smooth-transform'); 41 | } 42 | $('#wrapper').css({ 43 | backgroundColor: Theme.color.background 44 | }); 45 | return this.update_minimap(); 46 | }; 47 | 48 | Viewer.prototype.controller = function() { 49 | this.controls.on({ 50 | 'zoom-in': (function(_this) { 51 | return function() { 52 | return _this.zoom_step(true); 53 | }; 54 | })(this), 55 | 'zoom-out': (function(_this) { 56 | return function() { 57 | return _this.zoom_step(false); 58 | }; 59 | })(this), 60 | 'clear-search': (function(_this) { 61 | return function() { 62 | return _this.controls.set('search', ''); 63 | }; 64 | })(this), 65 | 'show-search-results': (function(_this) { 66 | return function(e) { 67 | var ref; 68 | if ((ref = e.original.which) === $.key.Down || ref === $.key.Enter) { 69 | $('#filter-dropdown').dropdown('toggle'); 70 | return false; 71 | } 72 | }; 73 | })(this), 74 | 'goto': (function(_this) { 75 | return function(e) { 76 | var id; 77 | id = e.context.link; 78 | if (id) { 79 | _this.find_and_zoom(id); 80 | } 81 | e.original.preventDefault(); 82 | return false; 83 | }; 84 | })(this) 85 | }); 86 | this.controls.observe({ 87 | 'search': (function(_this) { 88 | return function(query) { 89 | return _this.search(query); 90 | }; 91 | })(this) 92 | }); 93 | $win.on('keydown.viewer', (function(_this) { 94 | return function(e) { 95 | if (e.which === $.key.Ctrl) { 96 | _this.wrapper.addClass('zoom_fit'); 97 | } 98 | if ($.activeInput()) { 99 | return true; 100 | } else if (e.shiftKey) { 101 | switch (e.which) { 102 | case $.key.Plus: 103 | case $.key.Plus_num: 104 | _this.zoom_step(true); 105 | break; 106 | case $.key.Minus: 107 | case $.key.Minus_num: 108 | _this.zoom_step(false); 109 | break; 110 | case $.key.Up: 111 | _this.pan_step(0, +1); 112 | break; 113 | case $.key.Down: 114 | _this.pan_step(0, -1); 115 | break; 116 | case $.key.Left: 117 | _this.pan_step(+1, 0); 118 | break; 119 | case $.key.Right: 120 | _this.pan_step(-1, 0); 121 | break; 122 | default: 123 | return true; 124 | } 125 | return false; 126 | } else { 127 | switch (e.which) { 128 | case $.key.Plus: 129 | case $.key.Plus_num: 130 | _this.zoom_step(true); 131 | break; 132 | case $.key.Minus: 133 | case $.key.Minus_num: 134 | _this.zoom_step(false); 135 | break; 136 | case $.key.n8_num: 137 | _this.pan_step(0, +1); 138 | break; 139 | case $.key.n2_num: 140 | _this.pan_step(0, -1); 141 | break; 142 | case $.key.n4_num: 143 | _this.pan_step(+1, 0); 144 | break; 145 | case $.key.n6_num: 146 | _this.pan_step(-1, 0); 147 | break; 148 | case $.key.n7_num: 149 | _this.pan_step(+1, +1); 150 | break; 151 | case $.key.n9_num: 152 | _this.pan_step(-1, +1); 153 | break; 154 | case $.key.n1_num: 155 | _this.pan_step(+1, -1); 156 | break; 157 | case $.key.n3_num: 158 | _this.pan_step(-1, -1); 159 | break; 160 | case $.key.Slash: 161 | case $.key.Slash_cyr: 162 | case $.key.Slash_num: 163 | $('#search input').focus().select(); 164 | return false; 165 | default: 166 | return true; 167 | } 168 | return false; 169 | } 170 | return true; 171 | }; 172 | })(this)); 173 | $win.on('keyup.viewer', (function(_this) { 174 | return function(e) { 175 | if (e.which === $.key.Ctrl) { 176 | return _this.wrapper.removeClass('zoom_fit'); 177 | } 178 | }; 179 | })(this)); 180 | this.wrapper.on('mousewheel.viewer', (function(_this) { 181 | return function(e) { 182 | var factor; 183 | _this.fix_point(e.pageX - _this.wrapper.offset().left, e.pageY - _this.wrapper.offset().top); 184 | factor = e.deltaY > 0 ? _this.Settings.zoomInStepMouse : _this.Settings.zoomOutStepMouse; 185 | _this.zoom_by(factor); 186 | return false; 187 | }; 188 | })(this)); 189 | $win.on('dblclick.viewer', (function(_this) { 190 | return function(e) { 191 | var el; 192 | el = $(e.target).closest('g').data('model'); 193 | if (el) { 194 | _this.find_and_zoom(el); 195 | } 196 | return false; 197 | }; 198 | })(this)); 199 | $('#search, #zoom-control').on('mousedown', (function(_this) { 200 | return function(e) { 201 | return e.stopPropagation(); 202 | }; 203 | })(this)); 204 | $('#search').on('mousedown', (function(_this) { 205 | return function(e) { 206 | return $('#search input').focus(); 207 | }; 208 | })(this)); 209 | this.wrapper.on('mousedown.viewer', (function(_this) { 210 | return function(e) { 211 | var el; 212 | $.clearSelection(); 213 | if ($.activeInput()) { 214 | doc.activeElement.blur(); 215 | } 216 | if (e.ctrlKey) { 217 | el = $(e.target).closest('g')[0]; 218 | if (el) { 219 | _this.zoom_fit(el.instance); 220 | } 221 | return; 222 | } 223 | _this.wrapper.addClass('dragging'); 224 | _this.dragging = { 225 | x: e.clientX, 226 | y: e.clientY 227 | }; 228 | e.preventDefault(); 229 | return false; 230 | }; 231 | })(this)); 232 | this.wrapper.on('mousemove.viewer', (function(_this) { 233 | return function(e) { 234 | if (!_this.dragging) { 235 | return; 236 | } 237 | if (_this.opt.smooth) { 238 | _this.div.removeClass('smooth-transform'); 239 | } 240 | _this.pan_by(e.clientX - _this.dragging.x, e.clientY - _this.dragging.y); 241 | _this.dragging.x = e.clientX; 242 | return _this.dragging.y = e.clientY; 243 | }; 244 | })(this)); 245 | $win.on('mouseup.viewer', (function(_this) { 246 | return function(e) { 247 | _this.wrapper.trigger('mousemove', e); 248 | _this.wrapper.removeClass('dragging'); 249 | _this.dragging = null; 250 | if (_this.opt.smooth) { 251 | return _this.div.addClass('smooth-transform'); 252 | } 253 | }; 254 | })(this)); 255 | this.quickdrag.on('mousedown.viewer', (function(_this) { 256 | return function(e) { 257 | $.clearSelection(); 258 | if ($.activeInput()) { 259 | doc.activeElement.blur(); 260 | } 261 | _this.wrapper.addClass('dragging'); 262 | _this.dragging = { 263 | x: e.clientX, 264 | y: e.clientY 265 | }; 266 | e.preventDefault(); 267 | return false; 268 | }; 269 | })(this)); 270 | this.quickdrag.on('mousemove.viewer', (function(_this) { 271 | return function(e) { 272 | if (!_this.dragging) { 273 | return; 274 | } 275 | if (_this.opt.smooth) { 276 | _this.div.removeClass('smooth-transform'); 277 | } 278 | _this.pan_by((e.clientX - _this.dragging.x) * 5, (e.clientY - _this.dragging.y) * 5); 279 | _this.dragging.x = e.clientX; 280 | return _this.dragging.y = e.clientY; 281 | }; 282 | })(this)); 283 | $win.on('resize.viewer', (function(_this) { 284 | return function(e) { 285 | return _this.update_minimap(); 286 | }; 287 | })(this)); 288 | if (this.opt.smooth) { 289 | return this.div.on('transitionend webkitTransitionEnd oTransitionEnd', (function(_this) { 290 | return function(e) { 291 | return _this.update_minimap(); 292 | }; 293 | })(this)); 294 | } 295 | }; 296 | 297 | Viewer.prototype.Settings = { 298 | zoomInStep: 1.25, 299 | zoomOutStep: 0.8, 300 | zoomInStepMouse: 1.111111, 301 | zoomOutStepMouse: 0.9, 302 | scaleDuration: 100, 303 | panStep: 100, 304 | minisize: 0.05, 305 | miniH: 100, 306 | miniW: 100 307 | }; 308 | 309 | Viewer.prototype.save_canvas_size = function(w, h) { 310 | this.original_width = w || this.div.width(); 311 | return this.original_height = h || this.div.height(); 312 | }; 313 | 314 | Viewer.prototype.update_minimap = function() { 315 | var dp, mh, ml, mt, mw, vh, vl, vt, vw; 316 | vw = this.wrapper.width() * this.Settings.minisize; 317 | vh = this.wrapper.height() * this.Settings.minisize; 318 | vl = (this.Settings.miniW - vw) / 2; 319 | vt = (this.Settings.miniH - vh) / 2; 320 | this.viewport.css({ 321 | width: vw, 322 | height: vh, 323 | left: vl, 324 | top: vt 325 | }); 326 | mw = this.div.width() * this.Settings.minisize; 327 | mh = this.div.height() * this.Settings.minisize; 328 | dp = this.div.position(); 329 | ml = dp.left * this.Settings.minisize + vl; 330 | mt = dp.top * this.Settings.minisize + vt; 331 | return this.minimap.css({ 332 | width: mw, 333 | height: mh, 334 | left: ml, 335 | top: mt 336 | }); 337 | }; 338 | 339 | Viewer.prototype.search = function(query) { 340 | var el, filtered, id, j, len, ref, ref1, ref2, system; 341 | if (query === '') { 342 | this.filtered = []; 343 | this.search_query = ''; 344 | this.controls.set('filtered', []); 345 | return; 346 | } 347 | system = ((ref = win.modelview) != null ? (ref1 = ref.opt) != null ? ref1.model : void 0 : void 0) || null; 348 | if (this.search_query !== query) { 349 | this.search_from = null; 350 | this.search_query = query; 351 | this.filtered = system.findAll(query); 352 | filtered = []; 353 | ref2 = this.filtered; 354 | for (j = 0, len = ref2.length; j < len; j++) { 355 | el = ref2[j]; 356 | filtered.push({ 357 | link: el, 358 | title: system[el].nav_title() 359 | }); 360 | } 361 | this.controls.set('filtered', filtered); 362 | } 363 | if (system) { 364 | id = system.find(query, this.search_from); 365 | } 366 | if (id) { 367 | this.find_and_zoom(id); 368 | } 369 | return this.search_from = id; 370 | }; 371 | 372 | Viewer.prototype.lock_zoom = function(param) { 373 | return this.controls.set('zoomlock', param); 374 | }; 375 | 376 | Viewer.prototype.zoom_step = function(zoomin) { 377 | var factor; 378 | this.fix_point(this.wrapper.width() / 2, this.wrapper.height() / 2); 379 | factor = zoomin ? this.Settings.zoomInStep : this.Settings.zoomOutStep; 380 | return this.zoom_by(factor); 381 | }; 382 | 383 | Viewer.prototype.zoom_by = function(factor) { 384 | var scale; 385 | scale = Math.max(Theme.minzoom, Math.min(Theme.maxzoom, this.scale * factor)); 386 | return this.apply_scale(scale); 387 | }; 388 | 389 | Viewer.prototype.zoom = function(zoom) { 390 | return this.apply_scale(zoom); 391 | }; 392 | 393 | Viewer.prototype.scale_content = function(scale, dx, dy) {}; 394 | 395 | Viewer.prototype.apply_scale = function(scale) { 396 | var newh, newl, newt, neww, oldh, oldpos, oldw; 397 | this.scale = scale; 398 | this.lock_zoom(this.scale === Theme.minzoom ? 'min' : this.scale === Theme.maxzoom ? 'max' : ''); 399 | oldw = this.div.width(); 400 | oldh = this.div.height(); 401 | oldpos = this.div.position(); 402 | neww = this.original_width * this.scale; 403 | newh = this.original_height * this.scale; 404 | newl = this.fixed_x + (neww / oldw) * (oldpos.left - this.fixed_x); 405 | newt = this.fixed_y + (newh / oldh) * (oldpos.top - this.fixed_y); 406 | newl = Math.min(Math.max(newl, -neww), this.wrapper.width()); 407 | newt = Math.min(Math.max(newt, -newh), this.wrapper.height()); 408 | this.scale_content(this.scale, (newl - oldpos.left) / this.scale, (newt - oldpos.top) / this.scale).then((function(_this) { 409 | return function() { 410 | return _this.div.css({ 411 | width: neww, 412 | height: newh, 413 | left: newl, 414 | top: newt 415 | }); 416 | }; 417 | })(this)); 418 | return this.update_minimap(); 419 | }; 420 | 421 | Viewer.prototype.pan_by = function(dx, dy) { 422 | var newl, newt, oldpos; 423 | oldpos = this.div.position(); 424 | newl = oldpos.left + dx; 425 | newt = oldpos.top + dy; 426 | newl = Math.min(Math.max(newl, -this.div.width()), this.wrapper.width()); 427 | newt = Math.min(Math.max(newt, -this.div.height()), this.wrapper.height()); 428 | this.div.css({ 429 | left: newl, 430 | top: newt 431 | }); 432 | return this.update_minimap(); 433 | }; 434 | 435 | Viewer.prototype.pan_step = function(dx, dy) { 436 | return this.pan_by(dx * this.Settings.panStep, dy * this.Settings.panStep); 437 | }; 438 | 439 | Viewer.prototype.fix_point = function(x, y) { 440 | this.fixed_x = x; 441 | return this.fixed_y = y; 442 | }; 443 | 444 | Viewer.prototype.zoom_fit_all = function() { 445 | var scale; 446 | this.fix_point(0, 0); 447 | scale = Math.min(this.wrapper.height() / this.div.height(), this.wrapper.width() / this.div.width()); 448 | return this.apply_scale(scale); 449 | }; 450 | 451 | Viewer.prototype.find = function(tag) { 452 | return this.div.find('g[data-model="' + tag + '"]'); 453 | }; 454 | 455 | Viewer.prototype.find_and_zoom = function(tag) { 456 | var el; 457 | el = this.div.find('g[data-model="' + tag + '"]')[0]; 458 | if (el) { 459 | return this.zoom_fit(el.instance); 460 | } 461 | }; 462 | 463 | Viewer.prototype.find_and_pan = function(tag) { 464 | var el; 465 | el = this.div.find('g[data-model="' + tag + '"]')[0]; 466 | if (el) { 467 | return this.pan_to(el.instance); 468 | } 469 | }; 470 | 471 | Viewer.prototype.pan_to = function(el) { 472 | var div_rect, dx, dy, rect; 473 | rect = el.node.getBoundingClientRect(); 474 | div_rect = this.div.offset(); 475 | dx = rect.left + rect.width / 2 - div_rect.left; 476 | dy = rect.top + rect.height / 2 - div_rect.top; 477 | this.div.css({ 478 | left: -dx + this.wrapper.width() / 2, 479 | top: -dy + this.wrapper.height() / 2 480 | }); 481 | return this.update_minimap(); 482 | }; 483 | 484 | Viewer.prototype.zoom_fit = function(el) { 485 | var factor, rbox; 486 | this.fix_point(0, 0); 487 | rbox = el.rbox(); 488 | factor = Math.min((this.wrapper.height() - Theme.margin) / rbox.height, (this.wrapper.width() - Theme.margin) / rbox.width); 489 | this.zoom_by(factor); 490 | return this.pan_to(el); 491 | }; 492 | 493 | Viewer.prototype.in_center = function() { 494 | var el, node, p, x, y; 495 | p = this.wrapper.offset(); 496 | x = p.left + this.wrapper.width() / 2; 497 | y = p.top + this.wrapper.height() / 2; 498 | node = doc.elementFromPoint(x, y); 499 | el = node ? $(node).closest('g').data('model') : null; 500 | return el; 501 | }; 502 | 503 | Viewer.prototype.is_too_big = function(tag) { 504 | var el, rbox; 505 | el = this.div.find('g[data-model="' + tag + '"]')[0]; 506 | if (el) { 507 | rbox = el.instance.rbox(); 508 | return this.wrapper.height() < rbox.height || this.wrapper.width() < rbox.width; 509 | } else { 510 | return false; 511 | } 512 | }; 513 | 514 | Viewer.prototype.show_slide = function(el) { 515 | var node; 516 | node = this.div.find('[data-model=' + el + ']')[0]; 517 | if (node) { 518 | return this.zoom_fit(node.instance); 519 | } 520 | }; 521 | 522 | Viewer.prototype.show_story = function() { 523 | if (!this.model.story) { 524 | return; 525 | } 526 | $.each(this.model.story, (function(_this) { 527 | return function(i, el) { 528 | return $doc.queue('slides', function() { 529 | return setTimeout(function() { 530 | _this.show_slide(el); 531 | return $doc.dequeue('slides'); 532 | }, Theme.slideshow); 533 | }); 534 | }; 535 | })(this)); 536 | return $doc.dequeue('slides'); 537 | }; 538 | 539 | Viewer.prototype.destroy = function() { 540 | return this.div.empty(); 541 | }; 542 | 543 | return Viewer; 544 | 545 | })(); 546 | })(jQuery, window, document); 547 | 548 | //# sourceMappingURL=viewer.js.map 549 | -------------------------------------------------------------------------------- /js/libs-min/jquery.mousewheel.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh) 2 | * Licensed under the MIT License (LICENSE.txt). 3 | * 4 | * Version: 3.1.12 5 | * 6 | * Requires: jQuery 1.2.2+ 7 | */ 8 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}); -------------------------------------------------------------------------------- /js/libs-min/jquery.scrollintoview.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery scrollintoview() plugin and :scrollable selector filter 3 | * 4 | * Version 1.8 (14 Jul 2011) 5 | * Requires jQuery 1.4 or newer 6 | * 7 | * Copyright (c) 2011 Robert Koritnik 8 | * Licensed under the terms of the MIT license 9 | * http://www.opensource.org/licenses/mit-license.php 10 | */ 11 | (function(f){var c={vertical:{x:false,y:true},horizontal:{x:true,y:false},both:{x:true,y:true},x:{x:true,y:false},y:{x:false,y:true}};var b={duration:"fast",direction:"both"};var e=/^(?:html)$/i;var g=function(k,j){j=j||(document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(k,null):k.currentStyle);var i=document.defaultView&&document.defaultView.getComputedStyle?true:false;var h={top:(parseFloat(i?j.borderTopWidth:f.css(k,"borderTopWidth"))||0),left:(parseFloat(i?j.borderLeftWidth:f.css(k,"borderLeftWidth"))||0),bottom:(parseFloat(i?j.borderBottomWidth:f.css(k,"borderBottomWidth"))||0),right:(parseFloat(i?j.borderRightWidth:f.css(k,"borderRightWidth"))||0)};return{top:h.top,left:h.left,bottom:h.bottom,right:h.right,vertical:h.top+h.bottom,horizontal:h.left+h.right}};var d=function(h){var j=f(window);var i=e.test(h[0].nodeName);return{border:i?{top:0,left:0,bottom:0,right:0}:g(h[0]),scroll:{top:(i?j:h).scrollTop(),left:(i?j:h).scrollLeft()},scrollbar:{right:i?0:h.innerWidth()-h[0].clientWidth,bottom:i?0:h.innerHeight()-h[0].clientHeight},rect:(function(){var k=h[0].getBoundingClientRect();return{top:i?0:k.top,left:i?0:k.left,bottom:i?h[0].clientHeight:k.bottom,right:i?h[0].clientWidth:k.right}})()}};f.fn.extend({scrollintoview:function(j){j=f.extend({},b,j);j.direction=c[typeof(j.direction)==="string"&&j.direction.toLowerCase()]||c.both;var n="";if(j.direction.x===true){n="horizontal"}if(j.direction.y===true){n=n?"both":"vertical"}var l=this.eq(0);var i=l.closest(":scrollable("+n+")");if(i.length>0){i=i.eq(0);var m={e:d(l),s:d(i)};var h={top:m.e.rect.top-(m.s.rect.top+m.s.border.top),bottom:m.s.rect.bottom-m.s.border.bottom-m.s.scrollbar.bottom-m.e.rect.bottom,left:m.e.rect.left-(m.s.rect.left+m.s.border.left),right:m.s.rect.right-m.s.border.right-m.s.scrollbar.right-m.e.rect.right};var k={};if(j.direction.y===true){if(h.top<0){k.scrollTop=m.s.scroll.top+h.top}else{if(h.top>0&&h.bottom<0){k.scrollTop=m.s.scroll.top+Math.min(h.top,-h.bottom)}}}if(j.direction.x===true){if(h.left<0){k.scrollLeft=m.s.scroll.left+h.left}else{if(h.left>0&&h.right<0){k.scrollLeft=m.s.scroll.left+Math.min(h.left,-h.right)}}}if(!f.isEmptyObject(k)){if(e.test(i[0].nodeName)){i=f("html,body")}i.animate(k,j.duration).eq(0).queue(function(o){f.isFunction(j.complete)&&j.complete.call(i[0]);o()})}else{f.isFunction(j.complete)&&j.complete.call(i[0])}}return this}});var a={auto:true,scroll:true,visible:false,hidden:false};f.extend(f.expr[":"],{scrollable:function(k,i,n,h){var m=c[typeof(n[3])==="string"&&n[3].toLowerCase()]||c.both;var l=(document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(k,null):k.currentStyle);var o={x:a[l.overflowX.toLowerCase()]||false,y:a[l.overflowY.toLowerCase()]||false,isRoot:e.test(k.nodeName)};if(!o.x&&!o.y&&!o.isRoot){return false}var j={height:{scroll:k.scrollHeight,client:k.clientHeight},width:{scroll:k.scrollWidth,client:k.clientWidth},scrollableX:function(){return(o.x||o.isRoot)&&this.width.scroll>this.width.client},scrollableY:function(){return(o.y||o.isRoot)&&this.height.scroll>this.height.client}};return m.y&&j.scrollableY()||m.x&&j.scrollableX()}})})(jQuery); -------------------------------------------------------------------------------- /js/libs-min/svg.export.js: -------------------------------------------------------------------------------- 1 | (function(){function whitespaced(value,add,level){if(add){var whitespace="",space=add===!0?" ":add||"";for(i=level-1;i>=0;i--)whitespace+=space;value=whitespace+value+"\n"}return value}SVG.extend(SVG.Element,{exportSvg:function(options,level){var i,il,width,height,well,clone,name=this.node.nodeName,node="";if(options=options||{},null==options.exclude||!options.exclude.call(this)){if(options=options||{},level=level||0,this instanceof SVG.Doc&&(node+=whitespaced('',options.whitespace,level),width=this.attr("width"),height=this.attr("height"),options.width&&this.attr("width",options.width),options.height&&this.attr("height",options.height)),node+=whitespaced("<"+name+this.attrToString()+">",options.whitespace,level),this instanceof SVG.Doc&&(this.attr({width:width,height:height}),node+=whitespaced("Created with svg.js [http://svgjs.com]",options.whitespace,level+1),node+=this.defs().exportSvg(options,level+1)),this instanceof SVG.Parent)for(i=0,il=this.children().length;il>i;i++)SVG.Absorbee&&this.children()[i]instanceof SVG.Absorbee?(clone=this.children()[i].node.cloneNode(!0),well=document.createElement("div"),well.appendChild(clone),node+=well.innerHTML):node+=this.children()[i].exportSvg(options,level+1);else if(this instanceof SVG.Text||this instanceof SVG.Tspan)for(i=0,il=this.node.childNodes.length;il>i;i++)node+=this.node.childNodes[i].instance instanceof SVG.Tspan?this.node.childNodes[i].instance.exportSvg(options,level+1):this.node.childNodes[i].nodeValue.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'");else SVG.ComponentTransferEffect&&this instanceof SVG.ComponentTransferEffect&&this.rgb.each(function(){node+=this.exportSvg(options,level+1)});node+=whitespaced("",options.whitespace,level)}return node},exportAttr:function(attr){return 0==arguments.length?this.data("svg-export-attr"):this.data("svg-export-attr",attr)},attrToString:function(){var key,value,attr=[],data=this.exportAttr(),exportAttrs=this.attr();if("object"==typeof data)for(key in data)"data-svg-export-attr"!=key&&(exportAttrs[key]=data[key]);for(key in exportAttrs)value=exportAttrs[key],"xlink"==key?key="xmlns:xlink":"href"==key&&(exportAttrs["xlink:href"]||(key="xlink:href")),"string"==typeof value&&(value=value.replace(/"/g,"'")),"data-svg-export-attr"!=key&&"href"!=key&&("stroke"!=key||parseFloat(exportAttrs["stroke-width"])>0)&&attr.push(key+'="'+value+'"');return attr.length?" "+attr.join(" "):""}})}).call(this); 2 | -------------------------------------------------------------------------------- /js/libs-min/svg.filter.js: -------------------------------------------------------------------------------- 1 | // svg.filter.js 0.4 - Copyright (c) 2013-2014 Wout Fierens - Licensed under the MIT license 2 | ;(function(){function t(e){if(Array.isArray(e))e=new SVG.Array(e);return e.toString().replace(/^\s+/,"").replace(/\s+$/,"").replace(/\s+/g," ")}function n(e){if(!Array.isArray(e))return e;for(var t=0,n=e.length,r=[];t-1?new SVG.Parent:new SVG.Effect;e.forEach(function(e){SVG[n+"Effect"].prototype[e]=function(){return this.parent[e].apply(this.parent,arguments).in(this)}})});["r","g","b","a"].forEach(function(e){SVG["Func"+e.toUpperCase()]=function(){this.constructor.call(this,SVG.create("feFunc"+e.toUpperCase()))};SVG["Func"+e.toUpperCase()].prototype=new SVG.Element});SVG.extend(SVG.FloodEffect,{});SVG.filter={sepiatone:[.343,.669,.119,0,0,.249,.626,.13,0,0,.172,.334,.111,0,0,0,0,0,1,0]}}).call(this); -------------------------------------------------------------------------------- /js/libs/jquery.mousewheel.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh) 2 | * Licensed under the MIT License (LICENSE.txt). 3 | * 4 | * Version: 3.1.12 5 | * 6 | * Requires: jQuery 1.2.2+ 7 | */ 8 | 9 | (function (factory) { 10 | if ( typeof define === 'function' && define.amd ) { 11 | // AMD. Register as an anonymous module. 12 | define(['jquery'], factory); 13 | } else if (typeof exports === 'object') { 14 | // Node/CommonJS style for Browserify 15 | module.exports = factory; 16 | } else { 17 | // Browser globals 18 | factory(jQuery); 19 | } 20 | }(function ($) { 21 | 22 | var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'], 23 | toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ? 24 | ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'], 25 | slice = Array.prototype.slice, 26 | nullLowestDeltaTimeout, lowestDelta; 27 | 28 | if ( $.event.fixHooks ) { 29 | for ( var i = toFix.length; i; ) { 30 | $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; 31 | } 32 | } 33 | 34 | var special = $.event.special.mousewheel = { 35 | version: '3.1.12', 36 | 37 | setup: function() { 38 | if ( this.addEventListener ) { 39 | for ( var i = toBind.length; i; ) { 40 | this.addEventListener( toBind[--i], handler, false ); 41 | } 42 | } else { 43 | this.onmousewheel = handler; 44 | } 45 | // Store the line height and page height for this particular element 46 | $.data(this, 'mousewheel-line-height', special.getLineHeight(this)); 47 | $.data(this, 'mousewheel-page-height', special.getPageHeight(this)); 48 | }, 49 | 50 | teardown: function() { 51 | if ( this.removeEventListener ) { 52 | for ( var i = toBind.length; i; ) { 53 | this.removeEventListener( toBind[--i], handler, false ); 54 | } 55 | } else { 56 | this.onmousewheel = null; 57 | } 58 | // Clean up the data we added to the element 59 | $.removeData(this, 'mousewheel-line-height'); 60 | $.removeData(this, 'mousewheel-page-height'); 61 | }, 62 | 63 | getLineHeight: function(elem) { 64 | var $elem = $(elem), 65 | $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent'](); 66 | if (!$parent.length) { 67 | $parent = $('body'); 68 | } 69 | return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16; 70 | }, 71 | 72 | getPageHeight: function(elem) { 73 | return $(elem).height(); 74 | }, 75 | 76 | settings: { 77 | adjustOldDeltas: true, // see shouldAdjustOldDeltas() below 78 | normalizeOffset: true // calls getBoundingClientRect for each event 79 | } 80 | }; 81 | 82 | $.fn.extend({ 83 | mousewheel: function(fn) { 84 | return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel'); 85 | }, 86 | 87 | unmousewheel: function(fn) { 88 | return this.unbind('mousewheel', fn); 89 | } 90 | }); 91 | 92 | 93 | function handler(event) { 94 | var orgEvent = event || window.event, 95 | args = slice.call(arguments, 1), 96 | delta = 0, 97 | deltaX = 0, 98 | deltaY = 0, 99 | absDelta = 0, 100 | offsetX = 0, 101 | offsetY = 0; 102 | event = $.event.fix(orgEvent); 103 | event.type = 'mousewheel'; 104 | 105 | // Old school scrollwheel delta 106 | if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; } 107 | if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; } 108 | if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; } 109 | if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; } 110 | 111 | // Firefox < 17 horizontal scrolling related to DOMMouseScroll event 112 | if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { 113 | deltaX = deltaY * -1; 114 | deltaY = 0; 115 | } 116 | 117 | // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy 118 | delta = deltaY === 0 ? deltaX : deltaY; 119 | 120 | // New school wheel delta (wheel event) 121 | if ( 'deltaY' in orgEvent ) { 122 | deltaY = orgEvent.deltaY * -1; 123 | delta = deltaY; 124 | } 125 | if ( 'deltaX' in orgEvent ) { 126 | deltaX = orgEvent.deltaX; 127 | if ( deltaY === 0 ) { delta = deltaX * -1; } 128 | } 129 | 130 | // No change actually happened, no reason to go any further 131 | if ( deltaY === 0 && deltaX === 0 ) { return; } 132 | 133 | // Need to convert lines and pages to pixels if we aren't already in pixels 134 | // There are three delta modes: 135 | // * deltaMode 0 is by pixels, nothing to do 136 | // * deltaMode 1 is by lines 137 | // * deltaMode 2 is by pages 138 | if ( orgEvent.deltaMode === 1 ) { 139 | var lineHeight = $.data(this, 'mousewheel-line-height'); 140 | delta *= lineHeight; 141 | deltaY *= lineHeight; 142 | deltaX *= lineHeight; 143 | } else if ( orgEvent.deltaMode === 2 ) { 144 | var pageHeight = $.data(this, 'mousewheel-page-height'); 145 | delta *= pageHeight; 146 | deltaY *= pageHeight; 147 | deltaX *= pageHeight; 148 | } 149 | 150 | // Store lowest absolute delta to normalize the delta values 151 | absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) ); 152 | 153 | if ( !lowestDelta || absDelta < lowestDelta ) { 154 | lowestDelta = absDelta; 155 | 156 | // Adjust older deltas if necessary 157 | if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { 158 | lowestDelta /= 40; 159 | } 160 | } 161 | 162 | // Adjust older deltas if necessary 163 | if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { 164 | // Divide all the things by 40! 165 | delta /= 40; 166 | deltaX /= 40; 167 | deltaY /= 40; 168 | } 169 | 170 | // Get a whole, normalized value for the deltas 171 | delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta); 172 | deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta); 173 | deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta); 174 | 175 | // Normalise offsetX and offsetY properties 176 | if ( special.settings.normalizeOffset && this.getBoundingClientRect ) { 177 | var boundingRect = this.getBoundingClientRect(); 178 | offsetX = event.clientX - boundingRect.left; 179 | offsetY = event.clientY - boundingRect.top; 180 | } 181 | 182 | // Add information to the event object 183 | event.deltaX = deltaX; 184 | event.deltaY = deltaY; 185 | event.deltaFactor = lowestDelta; 186 | event.offsetX = offsetX; 187 | event.offsetY = offsetY; 188 | // Go ahead and set deltaMode to 0 since we converted to pixels 189 | // Although this is a little odd since we overwrite the deltaX/Y 190 | // properties with normalized deltas. 191 | event.deltaMode = 0; 192 | 193 | // Add event and delta to the front of the arguments 194 | args.unshift(event, delta, deltaX, deltaY); 195 | 196 | // Clearout lowestDelta after sometime to better 197 | // handle multiple device types that give different 198 | // a different lowestDelta 199 | // Ex: trackpad = 3 and mouse wheel = 120 200 | if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); } 201 | nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); 202 | 203 | return ($.event.dispatch || $.event.handle).apply(this, args); 204 | } 205 | 206 | function nullLowestDelta() { 207 | lowestDelta = null; 208 | } 209 | 210 | function shouldAdjustOldDeltas(orgEvent, absDelta) { 211 | // If this is an older event and the delta is divisable by 120, 212 | // then we are assuming that the browser is treating this as an 213 | // older mouse wheel event and that we should divide the deltas 214 | // by 40 to try and get a more usable deltaFactor. 215 | // Side note, this actually impacts the reported scroll distance 216 | // in older browsers and can cause scrolling to be slower than native. 217 | // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. 218 | return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0; 219 | } 220 | 221 | })); 222 | -------------------------------------------------------------------------------- /js/libs/jquery.scrollintoview.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery scrollintoview() plugin and :scrollable selector filter 3 | * 4 | * Version 1.8 (14 Jul 2011) 5 | * Requires jQuery 1.4 or newer 6 | * 7 | * Copyright (c) 2011 Robert Koritnik 8 | * Licensed under the terms of the MIT license 9 | * http://www.opensource.org/licenses/mit-license.php 10 | */ 11 | 12 | (function ($) { 13 | var converter = { 14 | vertical: { x: false, y: true }, 15 | horizontal: { x: true, y: false }, 16 | both: { x: true, y: true }, 17 | x: { x: true, y: false }, 18 | y: { x: false, y: true } 19 | }; 20 | 21 | var settings = { 22 | duration: "fast", 23 | direction: "both" 24 | }; 25 | 26 | var rootrx = /^(?:html)$/i; 27 | 28 | // gets border dimensions 29 | var borders = function (domElement, styles) { 30 | styles = styles || (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(domElement, null) : domElement.currentStyle); 31 | var px = document.defaultView && document.defaultView.getComputedStyle ? true : false; 32 | var b = { 33 | top: (parseFloat(px ? styles.borderTopWidth : $.css(domElement, "borderTopWidth")) || 0), 34 | left: (parseFloat(px ? styles.borderLeftWidth : $.css(domElement, "borderLeftWidth")) || 0), 35 | bottom: (parseFloat(px ? styles.borderBottomWidth : $.css(domElement, "borderBottomWidth")) || 0), 36 | right: (parseFloat(px ? styles.borderRightWidth : $.css(domElement, "borderRightWidth")) || 0) 37 | }; 38 | return { 39 | top: b.top, 40 | left: b.left, 41 | bottom: b.bottom, 42 | right: b.right, 43 | vertical: b.top + b.bottom, 44 | horizontal: b.left + b.right 45 | }; 46 | }; 47 | 48 | var dimensions = function ($element) { 49 | var win = $(window); 50 | var isRoot = rootrx.test($element[0].nodeName); 51 | return { 52 | border: isRoot ? { top: 0, left: 0, bottom: 0, right: 0} : borders($element[0]), 53 | scroll: { 54 | top: (isRoot ? win : $element).scrollTop(), 55 | left: (isRoot ? win : $element).scrollLeft() 56 | }, 57 | scrollbar: { 58 | right: isRoot ? 0 : $element.innerWidth() - $element[0].clientWidth, 59 | bottom: isRoot ? 0 : $element.innerHeight() - $element[0].clientHeight 60 | }, 61 | rect: (function () { 62 | var r = $element[0].getBoundingClientRect(); 63 | return { 64 | top: isRoot ? 0 : r.top, 65 | left: isRoot ? 0 : r.left, 66 | bottom: isRoot ? $element[0].clientHeight : r.bottom, 67 | right: isRoot ? $element[0].clientWidth : r.right 68 | }; 69 | })() 70 | }; 71 | }; 72 | 73 | $.fn.extend({ 74 | scrollintoview: function (options) { 75 | /// Scrolls the first element in the set into view by scrolling its closest scrollable parent. 76 | /// Additional options that can configure scrolling: 77 | /// duration (default: "fast") - jQuery animation speed (can be a duration string or number of milliseconds) 78 | /// direction (default: "both") - select possible scrollings ("vertical" or "y", "horizontal" or "x", "both") 79 | /// complete (default: none) - a function to call when scrolling completes (called in context of the DOM element being scrolled) 80 | /// 81 | /// Returns the same jQuery set that this function was run on. 82 | 83 | options = $.extend({}, settings, options); 84 | options.direction = converter[typeof (options.direction) === "string" && options.direction.toLowerCase()] || converter.both; 85 | 86 | var dirStr = ""; 87 | if (options.direction.x === true) dirStr = "horizontal"; 88 | if (options.direction.y === true) dirStr = dirStr ? "both" : "vertical"; 89 | 90 | var el = this.eq(0); 91 | var scroller = el.closest(":scrollable(" + dirStr + ")"); 92 | 93 | // check if there's anything to scroll in the first place 94 | if (scroller.length > 0) 95 | { 96 | scroller = scroller.eq(0); 97 | 98 | var dim = { 99 | e: dimensions(el), 100 | s: dimensions(scroller) 101 | }; 102 | 103 | var rel = { 104 | top: dim.e.rect.top - (dim.s.rect.top + dim.s.border.top), 105 | bottom: dim.s.rect.bottom - dim.s.border.bottom - dim.s.scrollbar.bottom - dim.e.rect.bottom, 106 | left: dim.e.rect.left - (dim.s.rect.left + dim.s.border.left), 107 | right: dim.s.rect.right - dim.s.border.right - dim.s.scrollbar.right - dim.e.rect.right 108 | }; 109 | 110 | var animOptions = {}; 111 | 112 | // vertical scroll 113 | if (options.direction.y === true) 114 | { 115 | if (rel.top < 0) 116 | { 117 | animOptions.scrollTop = dim.s.scroll.top + rel.top; 118 | } 119 | else if (rel.top > 0 && rel.bottom < 0) 120 | { 121 | animOptions.scrollTop = dim.s.scroll.top + Math.min(rel.top, -rel.bottom); 122 | } 123 | } 124 | 125 | // horizontal scroll 126 | if (options.direction.x === true) 127 | { 128 | if (rel.left < 0) 129 | { 130 | animOptions.scrollLeft = dim.s.scroll.left + rel.left; 131 | } 132 | else if (rel.left > 0 && rel.right < 0) 133 | { 134 | animOptions.scrollLeft = dim.s.scroll.left + Math.min(rel.left, -rel.right); 135 | } 136 | } 137 | 138 | // scroll if needed 139 | if (!$.isEmptyObject(animOptions)) 140 | { 141 | if (rootrx.test(scroller[0].nodeName)) 142 | { 143 | scroller = $("html,body"); 144 | } 145 | scroller 146 | .animate(animOptions, options.duration) 147 | .eq(0) // we want function to be called just once (ref. "html,body") 148 | .queue(function (next) { 149 | $.isFunction(options.complete) && options.complete.call(scroller[0]); 150 | next(); 151 | }); 152 | } 153 | else 154 | { 155 | // when there's nothing to scroll, just call the "complete" function 156 | $.isFunction(options.complete) && options.complete.call(scroller[0]); 157 | } 158 | } 159 | 160 | // return set back 161 | return this; 162 | } 163 | }); 164 | 165 | var scrollValue = { 166 | auto: true, 167 | scroll: true, 168 | visible: false, 169 | hidden: false 170 | }; 171 | 172 | $.extend($.expr[":"], { 173 | scrollable: function (element, index, meta, stack) { 174 | var direction = converter[typeof (meta[3]) === "string" && meta[3].toLowerCase()] || converter.both; 175 | var styles = (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(element, null) : element.currentStyle); 176 | var overflow = { 177 | x: scrollValue[styles.overflowX.toLowerCase()] || false, 178 | y: scrollValue[styles.overflowY.toLowerCase()] || false, 179 | isRoot: rootrx.test(element.nodeName) 180 | }; 181 | 182 | // check if completely unscrollable (exclude HTML element because it's special) 183 | if (!overflow.x && !overflow.y && !overflow.isRoot) 184 | { 185 | return false; 186 | } 187 | 188 | var size = { 189 | height: { 190 | scroll: element.scrollHeight, 191 | client: element.clientHeight 192 | }, 193 | width: { 194 | scroll: element.scrollWidth, 195 | client: element.clientWidth 196 | }, 197 | // check overflow.x/y because iPad (and possibly other tablets) don't dislay scrollbars 198 | scrollableX: function () { 199 | return (overflow.x || overflow.isRoot) && this.width.scroll > this.width.client; 200 | }, 201 | scrollableY: function () { 202 | return (overflow.y || overflow.isRoot) && this.height.scroll > this.height.client; 203 | } 204 | }; 205 | return direction.y && size.scrollableY() || direction.x && size.scrollableX(); 206 | } 207 | }); 208 | })(jQuery); -------------------------------------------------------------------------------- /js/libs/svg.export.js: -------------------------------------------------------------------------------- 1 | // svg.export.js 0.1.1 - Copyright (c) 2014 Wout Fierens - Licensed under the MIT license 2 | 3 | ;(function() { 4 | 5 | // Add export method to SVG.Element 6 | SVG.extend(SVG.Element, { 7 | // Build node string 8 | exportSvg: function(options, level) { 9 | var i, il, width, height, well, clone 10 | , name = this.node.nodeName 11 | , node = '' 12 | 13 | /* ensure options */ 14 | options = options || {} 15 | 16 | if (options.exclude == null || !options.exclude.call(this)) { 17 | /* ensure defaults */ 18 | options = options || {} 19 | level = level || 0 20 | 21 | /* set context */ 22 | if (this instanceof SVG.Doc) { 23 | /* define doctype */ 24 | node += whitespaced('', options.whitespace, level) 25 | 26 | /* store current width and height */ 27 | width = this.attr('width') 28 | height = this.attr('height') 29 | 30 | /* set required size */ 31 | if (options.width) 32 | this.attr('width', options.width) 33 | if (options.height) 34 | this.attr('height', options.height) 35 | } 36 | 37 | /* open node */ 38 | node += whitespaced('<' + name + this.attrToString() + '>', options.whitespace, level) 39 | 40 | /* reset size and add description */ 41 | if (this instanceof SVG.Doc) { 42 | this.attr({ 43 | width: width 44 | , height: height 45 | }) 46 | 47 | node += whitespaced('Created with svg.js [http://svgjs.com]', options.whitespace, level + 1) 48 | /* Add defs... */ 49 | node += this.defs().exportSvg(options, level + 1); 50 | } 51 | 52 | /* add children */ 53 | if (this instanceof SVG.Parent) { 54 | for (i = 0, il = this.children().length; i < il; i++) { 55 | if (SVG.Absorbee && this.children()[i] instanceof SVG.Absorbee) { 56 | clone = this.children()[i].node.cloneNode(true) 57 | well = document.createElement('div') 58 | well.appendChild(clone) 59 | node += well.innerHTML 60 | } else { 61 | node += this.children()[i].exportSvg(options, level + 1) 62 | } 63 | } 64 | 65 | } else if (this instanceof SVG.Text || this instanceof SVG.Tspan) { 66 | for (i = 0, il = this.node.childNodes.length; i < il; i++) 67 | if (this.node.childNodes[i].instance instanceof SVG.Tspan) 68 | node += this.node.childNodes[i].instance.exportSvg(options, level + 1) 69 | else 70 | node += this.node.childNodes[i].nodeValue.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''') 71 | 72 | } else if (SVG.ComponentTransferEffect && this instanceof SVG.ComponentTransferEffect) { 73 | this.rgb.each(function() { 74 | node += this.exportSvg(options, level + 1) 75 | }) 76 | 77 | } 78 | 79 | /* close node */ 80 | node += whitespaced('', options.whitespace, level) 81 | } 82 | 83 | return node 84 | } 85 | // Set specific export attibutes 86 | , exportAttr: function(attr) { 87 | /* acts as getter */ 88 | if (arguments.length == 0) 89 | return this.data('svg-export-attr') 90 | 91 | /* acts as setter */ 92 | return this.data('svg-export-attr', attr) 93 | } 94 | // Convert attributes to string 95 | , attrToString: function() { 96 | var i, key, value 97 | , attr = [] 98 | , data = this.exportAttr() 99 | , exportAttrs = this.attr() 100 | 101 | /* ensure data */ 102 | if (typeof data == 'object') 103 | for (key in data) 104 | if (key != 'data-svg-export-attr') 105 | exportAttrs[key] = data[key] 106 | 107 | /* build list */ 108 | for (key in exportAttrs) { 109 | value = exportAttrs[key] 110 | 111 | /* enfoce explicit xlink namespace */ 112 | if (key == 'xlink') { 113 | key = 'xmlns:xlink' 114 | } else if (key == 'href') { 115 | if (!exportAttrs['xlink:href']) 116 | key = 'xlink:href' 117 | } 118 | 119 | /* normailse value */ 120 | if (typeof value === 'string') 121 | value = value.replace(/"/g,"'") 122 | 123 | /* build value */ 124 | if (key != 'data-svg-export-attr' && key != 'href') { 125 | if (key != 'stroke' || parseFloat(exportAttrs['stroke-width']) > 0) 126 | attr.push(key + '="' + value + '"') 127 | } 128 | 129 | } 130 | 131 | return attr.length ? ' ' + attr.join(' ') : '' 132 | } 133 | 134 | }) 135 | 136 | ///////////// 137 | // helpers 138 | ///////////// 139 | 140 | // Whitespaced string 141 | function whitespaced(value, add, level) { 142 | if (add) { 143 | var whitespace = '' 144 | , space = add === true ? ' ' : add || '' 145 | 146 | /* build indentation */ 147 | for (i = level - 1; i >= 0; i--) 148 | whitespace += space 149 | 150 | /* add whitespace */ 151 | value = whitespace + value + '\n' 152 | } 153 | 154 | return value; 155 | } 156 | 157 | }).call(this); 158 | -------------------------------------------------------------------------------- /js/libs/svg.filter.js: -------------------------------------------------------------------------------- 1 | // svg.filter.js 0.4 - Copyright (c) 2013-2014 Wout Fierens - Licensed under the MIT license 2 | ;(function() { 3 | 4 | // Main filter class 5 | SVG.Filter = function() { 6 | this.constructor.call(this, SVG.create('filter')) 7 | } 8 | 9 | // Inherit from SVG.Container 10 | SVG.Filter.prototype = new SVG.Parent 11 | 12 | // 13 | SVG.extend(SVG.Filter, { 14 | // Static strings 15 | source: 'SourceGraphic' 16 | , sourceAlpha: 'SourceAlpha' 17 | , background: 'BackgroundImage' 18 | , backgroundAlpha: 'BackgroundAlpha' 19 | , fill: 'FillPaint' 20 | , stroke: 'StrokePaint' 21 | // Custom put method for leaner code 22 | , put: function(element, i) { 23 | this.add(element, i) 24 | 25 | return element.attr({ 26 | in: this.source 27 | , result: element 28 | }) 29 | } 30 | // Blend effect 31 | , blend: function(in1, in2, mode) { 32 | return this.put(new SVG.BlendEffect).attr({ in: in1, in2: in2, mode: mode || 'normal' }) 33 | } 34 | // ColorMatrix effect 35 | , colorMatrix: function(type, values) { 36 | if (type == 'matrix') 37 | values = normaliseMatrix(values) 38 | 39 | return this.put(new SVG.ColorMatrixEffect).attr({ 40 | type: type 41 | , values: typeof values == 'undefined' ? null : values 42 | }) 43 | } 44 | // ConvolveMatrix effect 45 | , convolveMatrix: function(matrix) { 46 | matrix = normaliseMatrix(matrix) 47 | 48 | return this.put(new SVG.ConvolveMatrixEffect).attr({ 49 | order: Math.sqrt(matrix.split(' ').length) 50 | , kernelMatrix: matrix 51 | }) 52 | } 53 | // ComponentTransfer effect 54 | , componentTransfer: function(compontents) { 55 | var transfer = new SVG.ComponentTransferEffect 56 | 57 | /* create rgb set */ 58 | transfer.rgb = new SVG.Set 59 | 60 | /* create components */ 61 | ;(['r', 'g', 'b', 'a']).forEach(function(c) { 62 | /* create component */ 63 | transfer[c] = new SVG['Func' + c.toUpperCase()]().attr('type', 'identity') 64 | 65 | /* store component in set */ 66 | transfer.rgb.add(transfer[c]) 67 | 68 | /* add component node */ 69 | transfer.node.appendChild(transfer[c].node) 70 | }) 71 | 72 | /* set components */ 73 | if (compontents) { 74 | if (compontents.rgb) { 75 | /* set bundled components */ 76 | ;(['r', 'g', 'b']).forEach(function(c) { 77 | transfer[c].attr(compontents.rgb) 78 | }) 79 | 80 | delete compontents.rgb 81 | } 82 | 83 | /* set individual components */ 84 | for (var c in compontents) 85 | transfer[c].attr(compontents[c]) 86 | } 87 | 88 | return this.put(transfer) 89 | } 90 | // Composite effect 91 | , composite: function(in1, in2, operator) { 92 | return this.put(new SVG.CompositeEffect).attr({ in: in1, in2: in2, operator: operator }) 93 | } 94 | // Flood effect 95 | , flood: function(color) { 96 | return this.put(new SVG.FloodEffect).attr({ 'flood-color': color }) 97 | } 98 | // Offset effect 99 | , offset: function(x, y) { 100 | return this.put(new SVG.OffsetEffect).attr({ dx: x, dy: y }) 101 | } 102 | // Image effect 103 | , image: function(src) { 104 | return this.put(new SVG.ImageEffect).attr('href', src, SVG.xlink) 105 | } 106 | // Merge effect 107 | , merge: function() { 108 | // to be implemented 109 | } 110 | // Gaussian Blur effect 111 | , gaussianBlur: function() { 112 | return this.put(new SVG.GaussianBlurEffect).attr('stdDeviation', listString(Array.prototype.slice.call(arguments))) 113 | } 114 | // Default string value 115 | , toString: function() { 116 | return 'url(#' + this.attr('id') + ')' 117 | } 118 | 119 | }) 120 | 121 | // 122 | SVG.extend(SVG.Defs, { 123 | // Define filter 124 | filter: function(block) { 125 | var filter = this.put(new SVG.Filter) 126 | 127 | /* invoke passed block */ 128 | if (typeof block === 'function') 129 | block.call(filter, filter) 130 | 131 | return filter 132 | } 133 | 134 | }) 135 | 136 | // 137 | SVG.extend(SVG.Container, { 138 | // Define filter on defs 139 | filter: function(block) { 140 | return this.defs().filter(block) 141 | } 142 | 143 | }) 144 | 145 | // 146 | SVG.extend(SVG.Element, SVG.G, SVG.Nested, { 147 | // Create filter element in defs and store reference 148 | filter: function(block) { 149 | this.filterer = block instanceof SVG.Element ? 150 | block : this.doc().filter(block) 151 | 152 | this.attr('filter', this.filterer) 153 | 154 | return this.filterer 155 | } 156 | // Remove filter 157 | , unfilter: function(remove) { 158 | /* also remove the filter node */ 159 | if (this.filterer && remove === true) 160 | this.filterer.remove() 161 | 162 | /* delete reference to filterer */ 163 | delete this.filterer 164 | 165 | /* remove filter attribute */ 166 | return this.attr('filter', null) 167 | } 168 | 169 | }) 170 | 171 | // Create wrapping SVG.Effect class 172 | SVG.Effect = function() {} 173 | 174 | // Inherit from SVG.Element 175 | SVG.Effect.prototype = new SVG.Element 176 | 177 | SVG.extend(SVG.Effect, { 178 | // Set in attribute 179 | in: function(effect) { 180 | return this.attr('in', effect) 181 | } 182 | // Named result 183 | , result: function() { 184 | return this.attr('id') + 'Out' 185 | } 186 | // Stringification 187 | , toString: function() { 188 | return this.result() 189 | } 190 | 191 | }) 192 | 193 | // Create all different effects 194 | var effects = [ 195 | 'blend' 196 | , 'colorMatrix' 197 | , 'componentTransfer' 198 | , 'composite' 199 | , 'convolveMatrix' 200 | , 'diffuseLighting' 201 | , 'displacementMap' 202 | , 'flood' 203 | , 'gaussianBlur' 204 | , 'image' 205 | , 'merge' 206 | , 'morphology' 207 | , 'offset' 208 | , 'specularLighting' 209 | , 'tile' 210 | , 'turbulence' 211 | , 'distantLight' 212 | , 'pointLight' 213 | , 'spotLight' 214 | ] 215 | 216 | effects.forEach(function(effect) { 217 | /* capitalize name */ 218 | var name = effect.charAt(0).toUpperCase() + effect.slice(1) 219 | 220 | /* create class */ 221 | SVG[name + 'Effect'] = function() { 222 | this.constructor.call(this, SVG.create('fe' + name)) 223 | } 224 | 225 | /* inherit from SVG.Effect */ 226 | SVG[name + 'Effect'].prototype = ['componentTransfer'].indexOf(name) > -1 ? 227 | new SVG.Parent : new SVG.Effect 228 | 229 | /* make all effects interchainable */ 230 | effects.forEach(function(e) { 231 | 232 | SVG[name + 'Effect'].prototype[e] = function() { 233 | return this.parent[e].apply(this.parent, arguments).in(this) 234 | } 235 | 236 | }) 237 | 238 | }) 239 | 240 | // Create compontent functions 241 | ;(['r', 'g', 'b', 'a']).forEach(function(c) { 242 | /* create class */ 243 | SVG['Func' + c.toUpperCase()] = function() { 244 | this.constructor.call(this, SVG.create('feFunc' + c.toUpperCase())) 245 | } 246 | 247 | /* inherit from SVG.Element */ 248 | SVG['Func' + c.toUpperCase()].prototype = new SVG.Element 249 | 250 | }) 251 | 252 | 253 | // Effect-specific extensions 254 | SVG.extend(SVG.FloodEffect, { 255 | // implement flood-color and flood-opacity 256 | }) 257 | 258 | // Presets 259 | SVG.filter = { 260 | sepiatone: [ .343, .669, .119, 0, 0 261 | , .249, .626, .130, 0, 0 262 | , .172, .334, .111, 0, 0 263 | , .000, .000, .000, 1, 0 ] 264 | } 265 | 266 | // Helpers 267 | function normaliseMatrix(matrix) { 268 | /* convert possible array value to string */ 269 | if (Array.isArray(matrix)) 270 | matrix = new SVG.Array(matrix) 271 | 272 | /* ensure there are no leading, tailing or double spaces */ 273 | return matrix.toString().replace(/^\s+/, '').replace(/\s+$/, '').replace(/\s+/g, ' ') 274 | } 275 | 276 | function listString(list) { 277 | if (!Array.isArray(list)) 278 | return list 279 | 280 | for (var i = 0, l = list.length, s = []; i < l; i++) 281 | s.push(list[i]) 282 | 283 | return s.join(' ') 284 | } 285 | 286 | }).call(this); -------------------------------------------------------------------------------- /view.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tectogram 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | --------------------------------------------------------------------------------