├── .gitignore ├── LICENSE ├── README.md ├── braench └── petal-braench.js ├── codon └── petal-codon.js ├── evtmonitor └── petal-evtmonitor.js ├── router └── petal-router.js ├── samples ├── codon.html ├── evtmonitor.html ├── graph-in-div.html ├── modal-dialog.html ├── router-extra.js ├── router.html ├── ui-template.html └── visualization.html ├── state └── petal-state.js ├── third_party ├── angular-ui-select │ ├── bower.json │ ├── index.html │ └── index.js └── angular2 │ └── first.html ├── ui-template └── petal-ui.js ├── upload ├── README.md ├── manage.py ├── nodejs │ ├── README.md │ ├── api.js │ └── uploader.js ├── static │ ├── index.html │ ├── jquery-2.1.4.min.js │ └── petal-upload.js └── upload │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── visualization ├── README ├── petal-interactions.js └── petal-modules.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 dna2github 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # petalJS 2 | 3 | Version 0.1.5 4 | 5 | A set of JavaScript utils for web development 6 | 7 | ## Canvas Hypergraph Visualizer 8 | 9 | A basement of canvas hypergraph visualizer. 10 | 11 | - node-link style 12 | - euler diagram for node depth (1 (2 (3))) 13 | - auto adjust for node position change 14 | - node non-overlap check 15 | - parent node size 16 | 17 | ![Codon Example](https://github.com/dna2github/dna2petal/wiki/img/codon_sample_1.png) 18 | 19 | ## AngularJS 2 with ES5 (JavaScript) 20 | 21 | An example to write Angular 2 without TypeScript 22 | 23 | - Inject a service to a directive 24 | - Pass data via element attribute 25 | - Apply data binding 26 | 27 | ## Event Monitor 28 | 29 | Basically to count triggered events. 30 | 31 | ```js 32 | $petal.evtmonitor.switchOn() 33 | ``` 34 | 35 | ```js 36 | function click(evt) { 37 | console.log($petal.evtmonitor.count(evt.target, click)); 38 | } 39 | $('#test').click(click); 40 | ``` 41 | 42 | ## Graph with Div 43 | 44 | Visualization for graph with `
` and customized DOM elements. 45 | 46 | In a graph, there will be some links between nodes. It visualize 47 | `a source node points to a target node` as `a big
contains a 48 | small
` (see an example in the sample folder: samples/graph-in-div.html ). 49 | 50 | Why not use SVG or Canvas? The anwser is to keep things simple. This 51 | method does not require complex location (x,y) calculating and just 52 | shows a graph with boxes. 53 | 54 | 55 | ``` 56 | A -> B, A -> C 57 | -------------- 58 | | A | 59 | | ---------- | 60 | | | B | | 61 | | ---------- | 62 | | ---------- | 63 | | | C | | 64 | | ---------- | 65 | -------------- 66 | ``` 67 | 68 | ## Large File Uploader 69 | 70 | Apply HTML5 File API to realize a uploader that support large file (tested with GB level file). 71 | The implementation is compatible with a morden browser like IE 10+, Chrome, Firefox, Safari and Opera. 72 | 73 | ```bash 74 | python mange.py runserver 127.0.0.1:8080 75 | ``` 76 | 77 | Then go to browser and type `http://127.0.0.1:8080/static/index.html` 78 | 79 | ## Template 80 | 81 | Make coding web site as doing with desktop application. 82 | 83 | ```html 84 | 85 |
86 | Name:
87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
AB
loading...loading...
96 |
97 | XYZ 98 |
99 |
100 |
101 |
102 | ``` 103 | 104 | ```js 105 | // index.js 106 | // @include jQuery 107 | 108 | // load template HTML 109 | $petal.ui.load('partial', 'partial.html', false); 110 | // create component with the template 111 | var control = $petal.ui.create('partial'); 112 | 113 | // link the element with tag="txt_name" to an object 114 | $(control.dom.txt_name).val("hello world"); 115 | // tag="]link" yields an array of elements with name "link" 116 | $(control.dom.link[0]).click(function () { alert("0"); }); 117 | $(control.dom.link[1]).click(function () { alert("1"); }); 118 | $(control.dom.link[2]).click(function () { alert("2"); }); 119 | // tag="+item" makes a sub template named "item" 120 | var item = $petal.ui.createT(control.template.item); 121 | $(item.dom.txt_a).text("hello"); 122 | $(item.dom.txt_b).text("world"); 123 | $(contorl.dom.items).append(item.self); 124 | $(control.dom.nest.dom.test).text('seprate world!'); 125 | $(document.body).append(control.self); 126 | ``` 127 | 128 | ## Visualization 129 | 130 | mouse hold, combo click, select frame, mouse gesture, touch to mouse 131 | 132 | `PetalModule` A function to load javascript file dynamically in DOM. 133 | 134 | `PetalInteraction` A function to wrap mouse events. 135 | 136 | - `comboclick` click for N times ( N > 2 ) 137 | - `mousehold` hold for N ms 138 | - `mouseframe` select a frame by drag-n-drop 139 | - `mousegesture` record mouse move trace 140 | 141 | `PetalMobileInteraction` A function to wrap touch events, mapping them to mouse events. 142 | 143 | - `touchpinch` pinch with multiple fingers 144 | - touchstart ==> mousedown 145 | - touchmove ==> mousemove 146 | - touchend ==> mouseup 147 | 148 | ## State Machine 149 | 150 | `$petal.state.PetalMachine` A class to define workflow in a state machine. 151 | 152 | - `register` Register a state named as `id` in the machine. When the state is activated from another one, `event_in` will be triggered; Going out of the state will make `event_out` take place; if `commit` is true, it means that once the state is activated, it should transfer to another state immediately. The whole process from State A to State B as below: 153 | 154 | ```js 155 | /* A --> B */ 156 | remain = A.event_out(B, extraData); 157 | result = B.event_in (A, extraData, remain); 158 | ``` 159 | 160 | - `unregister` Remove a state by `id`. 161 | - `connect` Make a path from a state `from` to another one `to` with specified `condition`; if the inverse way is also available, `directed` should be false. 162 | - `disconnect` Remove the path from a state `from` to another `to`; if remove the inverse way also, `directed` should be false. 163 | - `initialize` `jump` Set current state to a specified one immediately. 164 | - `transfer` Transfer current state to another one `id`. Extra `data` are passed through the process. If `checkcond` is false, it makes the current state transfer to another forcedly. 165 | - `wander` Randomly select one state that current state can reach for (with condition satisfied) and transfer current state to that state. 166 | 167 | Examples for how to use the state machine: 168 | 169 | - Fast try: 170 | 171 | ```js 172 | var m = new $petal.state.PetalMachine(); 173 | m.register("1", function() {alert("in:p1");}, function() {alert("out:p1");}); 174 | m.register("2", function() {alert("in:p2");}, function() {alert("out:p2");}); 175 | m.register("3", function() {alert("in:p3");}, function() {alert("out:p3");}); 176 | m.register("4", function() {alert("in:p4");}, function() {alert("out:p4");}); 177 | 178 | m.connect("1", "2", null); 179 | m.connect("1", "3", null); 180 | m.connect("2", "2", null); 181 | m.connect("2", "4", null); 182 | m.connect("3", "1", null); 183 | m.connect("3", "4", null); 184 | m.connect("4", "1", null); 185 | 186 | m.initialize("1"); 187 | m.transfer("4"); // no effect, stay at "1" 188 | m.transfer("3"); // goto "3" 189 | var i;for(i=0;i<10;i++) m.wander(); 190 | ``` 191 | 192 | - Modal Dialog: /sampels/modal-dialog.html 193 | 194 | ## Router 195 | 196 | `$petal.router` An instance to route the URL for web application with single page. 197 | 198 | The router will split `window.location.hash` into two parts. One starts with '#' and the other is for query which begin with '?'. The fomer part will be tested by the rules registered in the router, load necessary JavaScript resources and invoke an initial function. 199 | 200 | ``` 201 | url = #(hash); 202 | query = ?(hash); 203 | 204 | foreach rule in router.rules 205 | rule.patern.test(url); 206 | if pass 207 | load(rule.jses); 208 | rule.init(); 209 | return; 210 | ``` 211 | 212 | - `loadjs` Load a JavaScript resource `js` and then invoke `callback`; if `force` is true and the specified JavaScript resource is loaded, it will make the resource reloaded. 213 | - `loadjses` Load several JavaScript resources in an array of `js` and then invoke `callback'. 214 | - `unloadjs` Unload a specified JavaScript resource `js` and then invoke `clean`. 215 | - `ruleIn` Register a rule with `name` as ID, `patern`, an array `js` to declare what JavaScript resources needed and a function `init`. 216 | - `ruleOut` Remove a rule by `name`. 217 | - `refresh` Do routing once; attach to `window` to monitor URL changes as below: 218 | 219 | ```js 220 | window.onhashchange = $petal.router.refresh; 221 | ``` 222 | 223 | Examples for how to use the router: 224 | 225 | - Fast try: 226 | 227 | ```js 228 | $petal.router.ruleIn('home', '^#?/?$', null, 229 | function() { 230 | // redirect to real home 231 | window.location.hash = '/home'; 232 | }); 233 | $petal.router.ruleIn('home', '^#/home$', null, 234 | function() { 235 | alert('hello world!'); 236 | }); 237 | $petal.router.ruleIn('number', '^#/number/([0-9]+)$', null, 238 | function(url, num) { 239 | alert(num); 240 | }); 241 | $petal.router.ruleIn('word', '^#/word/([A-Za-z]+])$' null, 242 | function(url, word, query) { // e.g. #/word/hello?world 243 | alert(word+'\n'+query); 244 | }); 245 | window.onhashchange = $petal.router.refresh; 246 | $petal.router.refresh(); 247 | ``` 248 | 249 | - Router: /sampels/router.html (+ /samples/router-extra.js) 250 | 251 | -------------------------------------------------------------------------------- /braench/petal-braench.js: -------------------------------------------------------------------------------- 1 | /** 2 | @author: Seven Lju 3 | @date: 2015-09-20 4 | 5 | a generator for visulizing graph with
. 6 | for canvas and svg, it is hard to manipulate and take much time on 7 | calculating layout. a simple and clean visualization can be fit for 8 | desktop and mobile browser. 9 | 10 | A -> B, A -> C 11 | -------------- 12 | | A | 13 | | ---------- | 14 | | | B | | 15 | | ---------- | 16 | | ---------- | 17 | | | C | | 18 | | ---------- | 19 | -------------- 20 | */ 21 | 'use strict;' 22 | 23 | function $braench(config) { 24 | 25 | /* 26 | config { 27 | maxNested: if exceeds, will display outside the boxes. (should not be 1) 28 | graph: [ 29 | [id, to_list] 30 | ] 31 | callback { 32 | dom: function (node: {index, id, toList, children, graph, flatGraph}) return dom(default=div) 33 | } 34 | } 35 | */ 36 | 37 | if (!config) config = {}; 38 | if (!config.callback) config.callback = {}; 39 | if (!config.maxNested) config.maxNested = 0; 40 | 41 | if (!config.graph) config.graph = []; 42 | 43 | var cache_flat_graph = null; 44 | 45 | var exports = { 46 | config: function () { 47 | return config; 48 | }, 49 | graph: function () { 50 | return config.graph; 51 | }, 52 | generate: function () { 53 | cache_flat_graph = _generate_flat_graph(config.graph); 54 | return exports; 55 | }, 56 | divtree: function () { 57 | return _generate_div_tree(config.graph, cache_flat_graph); 58 | } 59 | }; 60 | 61 | return exports; 62 | 63 | function _generate_flat_graph (graph) { 64 | if (!graph.length) return []; 65 | 66 | var result = [], visited = []; 67 | var n = graph.length, i; 68 | for (i=0; i= n) return false; 82 | visited[i] = true; 83 | 84 | var queue = [ [i, result, 1] ]; 85 | while (queue.length > 0) { 86 | var node_parent_deep = queue.shift(); 87 | var node = node_parent_deep[0], 88 | parent = node_parent_deep[1], 89 | deep = node_parent_deep[2]; 90 | var id = graph[node][0], to_list = graph[node][1]; 91 | 92 | var current = [node]; 93 | current._braench_type = 'tree'; 94 | if (to_list.length == 0 || config.maxNested <= 1 || deep < config.maxNested) { 95 | parent.push(current); 96 | } else { 97 | // to avoid too many
nested 98 | parent.push(node); 99 | result.push(current); 100 | deep = 1; 101 | } 102 | 103 | if (!to_list.length) continue; 104 | 105 | for (var m=to_list.length, j=0, k=0; j B ---- 172 | | / \ 173 | | / v 174 | | A --> C ----> E ---- 175 | | |^ \ \ 176 | | \\---- D -\ v | 177 | | \ ^ --> F | 178 | | \ | ^ | 179 | \ --> G -----/ / 180 | \ /^ / 181 | ------/ \--------- 182 | 183 | var demo = $braench({ 184 | graph: [ 185 | ['A', [1,2,6]], // A->B,C,G 186 | ['B', [4]], // B->E 187 | ['C', [4]], // C->E 188 | ['D', [0,5]], // D->A,F 189 | ['E', [5,6]], // E->F,G 190 | ['F', []], 191 | ['G', [1,3,5]] // G->B,D,F 192 | ], 193 | maxNested: 3 194 | }); 195 | document.body.appendChild(demo.generate().divtree()); 196 | */ 197 | -------------------------------------------------------------------------------- /codon/petal-codon.js: -------------------------------------------------------------------------------- 1 | /** 2 | @author: Seven Lju 3 | @date: 2016-04-29 4 | */ 5 | 'use strict'; 6 | 7 | (function (window, document) { 8 | 9 | function pointLookAt(sx, sy, tx, ty) { 10 | var dxgt0 = (tx - sx > 0), 11 | dygt0 = (ty - sy >= 0); 12 | if (tx - sx == 0) { 13 | if (dygt0) return Math.PI / 2; 14 | return -Math.PI / 2; 15 | } 16 | var alpha = Math.atan((ty - sy) / (tx - sx)); 17 | if (!dxgt0 && dygt0) alpha += Math.PI; 18 | else if (!dxgt0 && !dygt0) alpha -= Math.PI; 19 | return alpha; 20 | } 21 | 22 | function pointSidePoint(sx, sy, alpha, direction, length) { 23 | var cosa = Math.cos(alpha + direction), 24 | sina = Math.sin(alpha + direction); 25 | return [sx + length * cosa, sy + length * sina]; 26 | } 27 | 28 | function pointDistance(sx, sy, tx, ty) { 29 | var dx = tx - sx, dy = ty - sy; 30 | return Math.sqrt(dx * dx + dy * dy); 31 | } 32 | 33 | function rectNodeCenter(rect) { 34 | return [rect[0] + rect[2]/2.0, rect[1] + rect[3]/2.0]; 35 | } 36 | 37 | const CODE_NODE = 0, CODE_LINK = 1; 38 | 39 | /* 40 | obj = {name, view, parent_view, code, extra} 41 | view = [x, y, w, h] 42 | code = 0: node, 1: link 43 | */ 44 | var size = [0, 0], 45 | view = [0, 0, 1, 1], 46 | zoom = 1.0, 47 | translate = [0, 0], 48 | pen = null, 49 | all_objs = [], 50 | visible_objs = []; 51 | 52 | function codonPaper(canvas) { 53 | // initialize for canvas 54 | pen = canvas.getContext('2d'); 55 | size[0] = canvas.clientWidth; 56 | size[1] = canvas.clientHeight; 57 | view[2] = size[0]; 58 | view[3] = size[1]; 59 | return this; 60 | } 61 | 62 | function codonZoom(scale) { 63 | if (!scale) { 64 | zoom = 1.0; 65 | } else { 66 | zoom *= scale; 67 | } 68 | view[0] = view[0] + size[0] * (1 - zoom) / 2.0; 69 | view[1] = view[1] + size[1] * (1 - zoom) / 2.0; 70 | view[2] = size[0] * zoom; 71 | view[3] = size[1] * zoom; 72 | return this; 73 | } 74 | 75 | function codonTranslate(dx, dy) { 76 | if (dx === undefined || dy === undefined) { 77 | view[0] = view[1] = 0.0; 78 | tranlsate[0] = translate[1] = 0.0; 79 | return; 80 | } 81 | view[0] += dx; 82 | view[1] += dy; 83 | translate[0] += dx; 84 | translate[1] += dy; 85 | return this; 86 | } 87 | 88 | function codonRectViewHits(view, objview) { 89 | // check rect intersects 90 | if (view[0] > objview[0] + objview[2]) return false; 91 | if (view[0] + view[2] < objview[0]) return false; 92 | if (view[1] > objview[1] + objview[3]) return false; 93 | if (view[1] + view[3] < objview[1]) return false; 94 | return true; 95 | } 96 | 97 | function codonObjs(objs) { 98 | all_objs = []; 99 | for (var n = objs.length, i = 0; i < n; i++) { 100 | all_objs.push(objs[i]); 101 | } 102 | return this; 103 | } 104 | 105 | function codonObjsRef(objs) { 106 | all_objs = objs; 107 | return this; 108 | } 109 | 110 | function codonGetNodeRef(index) { 111 | return all_objs[index]; 112 | } 113 | 114 | function codonGetVisibleNodeRef(index) { 115 | return visible_objs[index]; 116 | } 117 | 118 | function codonVisibleObjs() { 119 | var cur, p1, p2; 120 | visible_objs = []; 121 | for (var n = all_objs.length, i = 0; i < n; i++) { 122 | cur = all_objs[i]; 123 | if (cur.code === CODE_LINK) { 124 | // recalc link rect 125 | p1 = rectNodeCenter(cur.extra[1].view); 126 | p2 = rectNodeCenter(cur.extra[2].view); 127 | cur.view = [p1[0], p1[1], p2[0] - p1[0], p2[1] - p1[1]]; 128 | if (cur.view[2] < 0) { 129 | cur.view[0] += cur.view[2]; 130 | cur.view[2] = -cur.view[2]; 131 | } 132 | if (cur.view[3] < 0) { 133 | cur.view[1] += cur.view[3]; 134 | cur.view[3] = -cur.view[3]; 135 | } 136 | } 137 | if (codonRectViewHits(view, cur.view)) 138 | visible_objs.push(cur); 139 | } 140 | return this; 141 | } 142 | 143 | // TODO paint order 144 | function codonPaintOrder() { 145 | return this; 146 | } 147 | 148 | function _moveDueToParent(parent_obj) { 149 | if (!parent_obj.children) return; 150 | if (parent_obj._move_) { 151 | var n, i, cur, offset; 152 | offset = [ 153 | parent_obj.view[0] - parent_obj._move_.origin_view[0], 154 | parent_obj.view[1] - parent_obj._move_.origin_view[1], 155 | parent_obj.view[2] - parent_obj._move_.origin_view[2], 156 | parent_obj.view[3] - parent_obj._move_.origin_view[3] 157 | ]; 158 | for (n = parent_obj.children.length, i = 0; i < n; i++) { 159 | cur = parent_obj.children[i]; 160 | if (!cur._move_) { 161 | cur._move_ = {}; 162 | cur._move_.origin_view = [cur.view[0], cur.view[1], cur.view[2], cur.view[3]]; 163 | cur.view[0] += offset[0] + offset[2] / 2.0; 164 | cur.view[1] += offset[1] + offset[3] / 2.0; 165 | cur._move_.target_view = [cur.view[0], cur.view[1], cur.view[2], cur.view[3]]; 166 | } 167 | } 168 | } 169 | for (n = parent_obj.children.length, i = 0; i < n; i++) { 170 | cur = parent_obj.children[i]; 171 | _moveDueToParent(cur); 172 | } 173 | } 174 | 175 | function _adjustLevel(parent_obj) { 176 | // fit parent size for children position changes 177 | if (!parent_obj.children) return; 178 | if (!parent_obj.view) return; 179 | var n, i, t, cur, area = null; 180 | for (n = parent_obj.children.length, i = 0; i < n; i++) { 181 | cur = parent_obj.children[i]; 182 | if (area) { 183 | if (area[0] > cur.view[0]) area[0] = cur.view[0]; 184 | if (area[1] > cur.view[1]) area[1] = cur.view[1]; 185 | t = cur.view[0] + cur.view[2]; 186 | if (area[2] < t) area[2] = t; 187 | t = cur.view[1] + cur.view[3]; 188 | if (area[3] < t) area[3] = t; 189 | } else { 190 | area = [ 191 | cur.view[0], 192 | cur.view[1], 193 | cur.view[0] + cur.view[2], 194 | cur.view[1] + cur.view[3] 195 | ]; 196 | } 197 | } 198 | var padding = [20, 20, 20, 20]; 199 | parent_obj.view = [ 200 | area[0] - padding[0], 201 | area[1] - padding[1], 202 | area[2] - area[0] + padding[0] + padding[2], 203 | area[3] - area[1] + padding[1] + padding[3] 204 | ]; 205 | } 206 | 207 | function _rearrangeLevel(objs, base_obj) { 208 | var n, 209 | i, 210 | complete = [base_obj], 211 | cross = [], 212 | cur; 213 | for (n = objs.length, i = 0; i < n; i++) { 214 | cur = objs[i]; 215 | if (cur === base_obj) continue; 216 | if (!codonRectViewHits(base_obj.view, cur.view)) continue; 217 | cross.push(cur); 218 | } 219 | var low, 220 | high, 221 | expand_search = true, 222 | reduce_max_times, 223 | cur_center, 224 | cur_try_view, 225 | base_center = rectNodeCenter(base_obj.view); 226 | while (cross.length) { 227 | cur = cross.pop(); 228 | cur_center = rectNodeCenter(cur.view); 229 | cur_try_view = cur.view; 230 | // find available place for maximum move 231 | low = 1.0; 232 | high = 1.0; 233 | reduce_max_times = 0; 234 | do { 235 | for (n = complete.length, i = 0; i < n; i++) { 236 | if (codonRectViewHits(cur_try_view, complete[i].view)) break; 237 | } 238 | if (n <= i) { // some intersects 239 | expand_search = false; 240 | break; 241 | } 242 | cur_try_view = [ 243 | base_center[0] + (cur_center[0] - base_center[0]) * 2 - cur.view[2] / 2.0, 244 | base_center[1] + (cur_center[1] - base_center[1]) * 2 - cur.view[3] / 2.0, 245 | cur.view[2], cur.view[3] 246 | ]; 247 | cur_center = rectNodeCenter(cur_try_view); 248 | low = high; 249 | high *= 2.0; 250 | reduce_max_times = Math.floor( 251 | pointDistance( 252 | cur_center[0], 253 | cur_center[1], 254 | base_center[0], 255 | base_center[1] 256 | ) / pointDistance(0, 0, cur_try_view[2], cur_try_view[3]) / 2.0 257 | ) + 2; 258 | } while (expand_search); 259 | // find available place for nearer move 260 | if (low > 1) low /= 2.0; 261 | while (reduce_max_times > 0) { 262 | // cur_center should not changed for this loop 263 | cur_try_view = [ 264 | base_center[0] + (cur_center[0] - base_center[0]) * (low + high) / 2.0 - cur.view[2] / 2.0, 265 | base_center[1] + (cur_center[1] - base_center[1]) * (low + high) / 2.0 - cur.view[3] / 2.0, 266 | cur.view[2], cur.view[3] 267 | ] 268 | for (n = complete.length, i = 0; i < n; i++) { 269 | if (codonRectViewHits(cur_try_view, complete[i].view)) break; 270 | } 271 | if (n > i) { 272 | low = (low + high) / 2.0; 273 | } else { 274 | high = (low + high) / 2.0; 275 | reduce_max_times --; 276 | if (!reduce_max_times) { 277 | cur_try_view = [ 278 | base_center[0] + (cur_center[0] - base_center[0]) * low - cur.view[2] / 2.0, 279 | base_center[1] + (cur_center[1] - base_center[1]) * low - cur.view[3] / 2.0, 280 | cur.view[2], cur.view[3] 281 | ] 282 | } 283 | } 284 | } 285 | if (!cur._move_) { 286 | cur._move_ = {}; 287 | cur._move_.origin_view = [cur.view[0], cur.view[1], cur.view[2], cur.view[3]]; 288 | } 289 | cur.view = cur_try_view; 290 | cur._move_.target_view = [cur.view[0], cur.view[1], cur.view[2], cur.view[3]]; 291 | } 292 | } 293 | 294 | function codonNodeMove(node, x, y) { 295 | var root = {parent:null, children:[]}, 296 | n, 297 | i, 298 | cur; 299 | for (n = all_objs.length, i = 0; i < n; i++) { 300 | cur = all_objs[i]; 301 | if (!cur.parent && cur.code === CODE_NODE) { 302 | root.children.push(cur); 303 | } 304 | } 305 | 306 | node._move_ = {}; 307 | node._move_.origin_view = [node.view[0], node.view[1], node.view[2], node.view[3]]; 308 | node.view[0] = x; 309 | node.view[1] = y; 310 | node._move_.target_view = [node.view[0], node.view[1], node.view[2], node.view[3]]; 311 | var parent; 312 | parent = node.parent || root; 313 | cur = node; 314 | while (parent) { 315 | _rearrangeLevel(parent.children, cur); 316 | _adjustLevel(parent); 317 | cur = parent; 318 | parent = parent.parent; 319 | if (cur !== root && !parent) parent = root; 320 | } 321 | 322 | for (n = root.children.length, i = 0; i < n; i++) { 323 | _moveDueToParent(root.children[i]); 324 | } 325 | // then need codonVisibleObjs() 326 | // codonRepaint() 327 | return this; 328 | } 329 | 330 | function _drawNode(obj) { 331 | pen.fillStyle = '#ddd'; 332 | pen.fillRect(obj.view[0], obj.view[1], obj.view[2], obj.view[3]); 333 | pen.strokeStyle = '#777'; 334 | pen.strokeRect(obj.view[0], obj.view[1], obj.view[2], obj.view[3]); 335 | // draw text 336 | if (obj.name) { 337 | pen.font = '12px calibri'; 338 | pen.fillStyle = 'black'; 339 | pen.textAlign = 'center'; 340 | // var metrics = context.measureText(string); 341 | pen.fillText(obj.name, obj.view[0] + obj.view[2] / 2.0, obj.view[1] + obj.view[3] + 12); 342 | } 343 | } 344 | 345 | function _drawLink(obj) { 346 | var dflag = obj.extra[0], 347 | p1 = rectNodeCenter(obj.extra[1].view), 348 | p2 = rectNodeCenter(obj.extra[2].view), 349 | pc = [(p1[0] + p2[0]) / 2.0, (p1[1] + p2[1]) / 2.0]; 350 | if (dflag & 0x2) { 351 | pen.strokeStyle = '#000'; 352 | } else { 353 | pen.strokeStyle = '#ccc'; 354 | } 355 | pen.beginPath(); 356 | pen.moveTo(p1[0], p1[1]); 357 | pen.lineTo(pc[0], pc[1]); 358 | pen.stroke(); 359 | if (dflag & 0x1) { 360 | pen.strokeStyle = '#000'; 361 | } else { 362 | pen.strokeStyle = '#ccc'; 363 | } 364 | pen.beginPath(); 365 | pen.moveTo(pc[0], pc[1]); 366 | pen.lineTo(p2[0], p2[1]); 367 | pen.stroke(); 368 | //pen.quadraticCurveTo(p2[0], p2[1], p3[0], p3[1]); 369 | //pen.bezierCurveTo(p2[0], p2[1], p3[0], p3[1], p4[0], p4[1]); 370 | } 371 | 372 | // window.requestAnimationFrame(codonRepaint) 373 | function codonRepaint(frame) { 374 | var cur = null; 375 | pen.clearRect(0, 0, size[0], size[1]); 376 | for (var n = visible_objs.length, i = 0; i < n; i++) { 377 | cur = visible_objs[i]; 378 | switch (cur.code) { 379 | case CODE_NODE: 380 | _drawNode(cur); 381 | break; 382 | case CODE_LINK: 383 | _drawLink(cur); 384 | break; 385 | } 386 | } 387 | } 388 | 389 | function codonAnimateMove(frames) { 390 | if (frames === undefined) frames = 10; 391 | var ifr = frames; 392 | window.requestAnimationFrame(_paint); 393 | function _paint(frame) { 394 | if (ifr < 0) { 395 | // post-process 396 | for (var n = all_objs.length, i = 0; i < n; i++) { 397 | cur = all_objs[i]; 398 | if (cur._move_) { 399 | cur._move_ = null; 400 | delete cur._move_; 401 | } 402 | } 403 | codonVisibleObjs(); 404 | codonRepaint(); 405 | return; 406 | } 407 | var cur, tv, ov; 408 | for (var n = visible_objs.length, i = 0; i < n; i++) { 409 | cur = visible_objs[i]; 410 | if (!cur._move_) continue; 411 | ov = cur._move_.origin_view; 412 | tv = cur._move_.target_view; 413 | cur.view[0] = tv[0] - (tv[0] - ov[0]) * (ifr / frames); 414 | cur.view[1] = tv[1] - (tv[1] - ov[1]) * (ifr / frames); 415 | } 416 | codonRepaint(); 417 | ifr --; 418 | window.requestAnimationFrame(_paint); 419 | } 420 | return this; 421 | } 422 | 423 | window.$codon = { 424 | Paper: codonPaper, 425 | set: codonObjs, 426 | node: codonGetNodeRef, 427 | setRef: codonObjsRef, 428 | strip: codonVisibleObjs, 429 | order: codonPaintOrder, 430 | repaint: codonRepaint, 431 | move: codonNodeMove, 432 | zoom: codonZoom, 433 | translate: codonTranslate, 434 | cross: codonRectViewHits, 435 | moveAnimate: codonAnimateMove, 436 | debug: { 437 | link: _drawLink, 438 | node: _drawNode 439 | } 440 | } 441 | 442 | })(window, document); 443 | -------------------------------------------------------------------------------- /evtmonitor/petal-evtmonitor.js: -------------------------------------------------------------------------------- 1 | /* 2 | @author: Seven Lju 3 | @date: 2016-03-18 4 | 5 | DOM Event Monitor by Overriding 6 | EventTarget.prototype.addEventListener 7 | with global object identifier feature via defining 8 | Object.prototype.__oid__ 9 | */ 10 | var $petal; 11 | if(!$petal) $petal = {}; 12 | 13 | (function ($petal) { 14 | 15 | (function() { 16 | var _id = 1; 17 | Object.defineProperty(Object.prototype, "__oid_w__", { 18 | writable: true 19 | }); 20 | Object.defineProperty(Object.prototype, "__oid__", { 21 | get: function() { 22 | if (!this.__oid_w__) 23 | this.__oid_w__ = _id++; 24 | return this.__oid_w__; 25 | }, 26 | }); 27 | })(); 28 | 29 | var original_addEventListener = EventTarget.prototype.addEventListener; 30 | var map_listener = { 31 | config: { 32 | count: true 33 | } 34 | }; 35 | 36 | function new_addEventListener(type, listener, options) { 37 | return original_addEventListener.call( 38 | this, 39 | type, 40 | wrapper(this, listener, type, map_listener), 41 | options 42 | ); 43 | } 44 | 45 | function mapid(obj, listener) { 46 | return obj.__oid__ + '_' + listener.__oid__; 47 | } 48 | 49 | function wrapper(target, listener, type, __map__) { 50 | var __id__ = mapid(target, listener); 51 | var __item__ = __map__[__id__]; 52 | if (!__item__) { 53 | __item__ = {}; 54 | __map__[__id__] = __item__; 55 | } 56 | __item__.count = 0; 57 | __item__.type = type; 58 | return function (evt) { 59 | if (__item__.callback) __item__.callback(evt); 60 | if (__map__.config.count) __item__.count ++; 61 | listener(evt); 62 | }; 63 | } 64 | 65 | function switch_off() { 66 | EventTarget.prototype.addEventListener = original_addEventListener; 67 | // TODO registered wrapper(listener)=>listener 68 | } 69 | 70 | function switch_on() { 71 | EventTarget.prototype.addEventListener = new_addEventListener; 72 | // TODO registered listener=>wrapper(listener) 73 | } 74 | 75 | $petal.evtmonitor = { 76 | config: function () { 77 | return map_listener.config; 78 | }, 79 | count: function (target, listener) { 80 | var item = map_listener[mapid(target, listener)]; 81 | if (!item) return -1; 82 | return item.count; 83 | }, 84 | type: function (target, listener) { 85 | var item = map_listener[mapid(target, listener)]; 86 | if (!item) return null; 87 | return item.type; 88 | }, 89 | addCleanEventListener: function (target, type, listener, options) { 90 | return original_addEventListener.call( 91 | target, 92 | type, 93 | listener, 94 | options 95 | ); 96 | }, 97 | switchOn: switch_on, 98 | switchOff: switch_off 99 | }; 100 | 101 | })($petal); 102 | -------------------------------------------------------------------------------- /router/petal-router.js: -------------------------------------------------------------------------------- 1 | /* 2 | @author: Seven Lju 3 | @date: 2014-03-27 4 | 5 | a uri router via url hash for one page web applications 6 | */ 7 | var $petal; 8 | if($petal == null) $petal = {}; 9 | 10 | (function($petal, $win, $doc) { 11 | 12 | var loadedJS = []; // {name, act} 13 | 14 | function _indexOf(array, key, val) { 15 | if(val == null) { 16 | val = key; key = null; 17 | } 18 | if(key == null) { 19 | return array.indexOf(val); 20 | } 21 | var m,i,n = array.length; for(i=0;i=0) { 38 | query = url.substring(i+1); 39 | url = url.substring(0,i); 40 | } 41 | for(i=0;i=n) { 96 | if(callback) callback(); 97 | } else { 98 | var load = false; 99 | load = self.loadjs(nextjs, seq, force); 100 | nextjs = js[++i]; 101 | if(!load) { 102 | // loaded 103 | seq(); 104 | } 105 | } 106 | } 107 | seq(); 108 | } 109 | PetalRouter.prototype.ruleIn = function(name, patern, js, init) { 110 | this.paterns.push({ 111 | name : name, 112 | patern : patern, 113 | js : js, 114 | init : init 115 | }); 116 | }; 117 | PetalRouter.prototype.ruleOut = function(name) { 118 | var i,n=this.paterns.length; for(i=0;i 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /samples/evtmonitor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/graph-in-div.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /samples/modal-dialog.html: -------------------------------------------------------------------------------- 1 | 2 | Modal Dialog 3 | 4 | 5 | 6 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /samples/router-extra.js: -------------------------------------------------------------------------------- 1 | function lower(str) { 2 | return str.toLowerCase(); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /samples/router.html: -------------------------------------------------------------------------------- 1 | 2 | Router 3 | 4 |
5 | 6 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /samples/ui-template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /samples/visualization.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Visualization Lab 4 | 5 | 6 | 7 |
8 | 9 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /state/petal-state.js: -------------------------------------------------------------------------------- 1 | /* 2 | @author: Seven Lju 3 | @date: 2014-03-27 4 | 5 | a state machine to make clear workflow. 6 | e.g. define active -----> processing 7 | ^ | 8 | \-------------| 9 | acitve: {}.disabled = false 10 | processing: {}.disabled = true 11 | $(button).click(function () { 12 | state(button).set('processing'); 13 | // do something 14 | state(button).transfer('active'); 15 | }); 16 | */ 17 | var $petal; 18 | if($petal == null) $petal = {}; 19 | 20 | (function($petal) { // START: Module $petal.state 21 | 22 | /* common function */ 23 | function PetalState(id, event_in, event_out, commit) { 24 | if(commit==null) commit = false; 25 | 26 | this.id = id; 27 | this.event_in = event_in; 28 | this.event_out = event_out; 29 | this.commit = commit; 30 | 31 | // item: {id: string, where: PetalState, condition: PetalCondition} 32 | this.to = new PetalStateSet(); 33 | } 34 | PetalState.prototype.come = function(prev, data, remain) { 35 | // remain = prev.event_out(this, data); 36 | if(!this.event_in) return null; 37 | return this.event_in(prev, data, remain); 38 | }; 39 | PetalState.prototype.go = function(next, data) { 40 | if(!this.event_out) return null; 41 | return this.event_out(next, data); 42 | }; 43 | 44 | function PetalCondition(from, to, condition, directed) { 45 | if(directed==null) directed = true; 46 | 47 | this.from = from; 48 | this.to = to; 49 | this.condition = condition; 50 | this.directed = directed; 51 | } 52 | PetalCondition.prototype.match = function(from, to) { 53 | if(this.from == from && this.to == to) return true; 54 | if(!this.directed && this.from == to && this.to == from) return true; 55 | return false; 56 | }; 57 | PetalCondition.prototype.check = function(data) { 58 | if(!this.condition) return true; // no condition 59 | return this.condition(this.from, this.to, data); 60 | }; 61 | 62 | function PetalStateSet() { 63 | this.states = []; 64 | } 65 | PetalStateSet.prototype.get = function(id) { 66 | var index=-1,i,n=this.states.length; for(i=0;i" 5 | ], 6 | "description": "", 7 | "main": "", 8 | "license": "MIT", 9 | "homepage": "", 10 | "ignore": [ 11 | "**/.*", 12 | "node_modules", 13 | "bower_components", 14 | "test", 15 | "tests" 16 | ], 17 | "dependencies": { 18 | "angular": "^1.5.7", 19 | "angular-ui-select": "^0.18.0", 20 | "bootstrap": "^3.3.6", 21 | "angular-sanitize": "^1.5.7" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /third_party/angular-ui-select/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Scroll Window 4 | 5 | 6 | 7 | 8 |
9 |

10 | - scroll-window -
11 | do pagination for ui-select; 12 | scroll upwards to load previous page; 13 | scroll downwards to load next page. 14 |

15 |

16 | scroll-window: list source
17 | scroll-window-selected: default selected item
18 | scroll-window-size: page size
19 |

20 |

21 | bower install 22 | index.html 23 |

24 |
25 |
26 | 33 | 35 | {{$select.selected.name}} 36 | ({{$select.selected.id}}) 37 | 38 | 43 |
44 | 45 | id:
47 | name: 49 |
50 |
51 |
52 |
53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /third_party/angular-ui-select/index.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app', ['ui.select', 'ngSanitize']); 2 | 3 | var test_list = []; 4 | 5 | app.controller('pageIndex', ['$scope', function ($scope) { 6 | $scope.test_list = test_list; 7 | for (var i=50-1; i>=0; i--) { 8 | $scope.test_list.push({id:i, name:'test'+i}); 9 | } 10 | $scope.selected = $scope.test_list[25]; //$scope.test_list[25]; 11 | $scope.disabled = false; 12 | }]); 13 | 14 | app.directive('scrollWindow', function () { 15 | return { 16 | link: function ($scope, $elem, $attr) { 17 | var $select = $scope.$select, 18 | source = $scope.$eval($attr.scrollWindow), 19 | size = parseInt($attr.scrollWindowSize || 20), 20 | state = { 21 | upable: false, 22 | downable: true, 23 | upindex: 0, 24 | downindex: 0, 25 | data: [] 26 | }, 27 | selected = $scope.$eval($attr.scrollWindowSelected); 28 | initScrollWindow($elem, $select, source, size, state, selected); 29 | $scope.$watchCollection($attr.scrollWindow, function () { 30 | source = $scope.$eval($attr.scrollWindow); 31 | initScrollWindow($elem, $select, source, size, state, selected); 32 | }); 33 | } 34 | }; 35 | 36 | function initScrollWindow($elem, $select, source, size, state, selected) { 37 | if (!source) source = []; 38 | source = source.slice(); 39 | if (source.length <= size) { 40 | source.forEach(function (item) { $select.items.push(item)}); 41 | $select.refreshItems(); 42 | } else { 43 | if (!selected) { 44 | // selected === null, load from top 45 | state = loadWindow( 46 | $select, source, 0, state.downindex, size, true); 47 | } else { 48 | // currently only support one select 49 | var mid = lookup(source, selected); 50 | state.upindex = mid - (~~((size - 1) / 2)); 51 | if (state.upindex < 0) state.upindex = 0; 52 | state.downindex = state.upindex + size; 53 | if (state.downindex >= source.length) state.downindex = source.length - 1; 54 | state = loadWindow( 55 | $select, source, state.upindex, state.downindex, 0, true); 56 | $select.ngModel.$viewValue = $select.items[mid]; 57 | } 58 | $elem.unbind('scroll'); 59 | $elem.bind('scroll', function () { 60 | var percent = 61 | $elem.prop('scrollTop') / 62 | Math.abs($elem.prop('scrollHeight') - $elem.prop('offsetHeight')); 63 | var showSize = state.downindex - state.upindex, 64 | eachHeight = 0, 65 | oldState = null; 66 | if (showSize > 0) { 67 | eachHeight = $elem.prop('scrollHeight') / showSize; 68 | } 69 | // scroll one page toward top 70 | if (percent >= 1 && state.downable) { 71 | oldState = state; 72 | state = loadWindow( 73 | $select, source, state.upindex, state.downindex, size, true); 74 | } 75 | // scroll one page toward bottom 76 | if (percent <= 0 && state.upable) { 77 | oldState = state; 78 | state = loadWindow( 79 | $select, source, state.upindex, state.downindex, size, false); 80 | $select.activeIndex += oldState.upindex - state.upindex; 81 | setTimeout(function () { 82 | $elem.prop( 83 | 'scrollTop', 84 | $elem.prop('scrollTop') + 85 | (oldState.upindex - state.upindex) * eachHeight 86 | ); 87 | }, 0); 88 | } 89 | }); 90 | } 91 | } 92 | 93 | function loadWindow($select, items, upindex, downindex, size, downscroll) { 94 | var upable = true, 95 | downable = true; 96 | if (downscroll) { 97 | downindex += size; 98 | } else { 99 | upindex -= size; 100 | } 101 | if (upindex < 0) upindex = 0; 102 | if (downindex >= items.length) downindex = items.length - 1; 103 | if (downindex < 0) downindex = 0; 104 | if (upindex === 0) upable = false; 105 | if (downindex === items.length - 1) downable = false; 106 | $select.items = items.slice(upindex, downindex + 1); 107 | $select.refreshItems($select.items); 108 | return { 109 | upable: upable, 110 | downable: downable, 111 | upindex: upindex, 112 | downindex: downindex, 113 | data: $select._items 114 | }; 115 | } 116 | 117 | function lookup(items, item) { 118 | for (var i = 0, n = items.length; i < n; i++) { 119 | if (angular.equals(items[i], item)) return i; 120 | } 121 | // should not be here 122 | return -1; 123 | } 124 | }); 125 | -------------------------------------------------------------------------------- /third_party/angular2/first.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Angular 2 without TypeScript 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 74 | Loading... 75 | 76 | 77 | -------------------------------------------------------------------------------- /ui-template/petal-ui.js: -------------------------------------------------------------------------------- 1 | /* 2 | @author: Seven Lju 3 | @date: 2015-02-18 4 | 5 | a template reader for web application. 6 | */ 7 | var $petal; 8 | if($petal == null) $petal = {}; 9 | 10 | (function($petal, $win, $doc) { 11 | 12 | var ajax = { 13 | _nop: function () {}, 14 | resource: function (name, path, async) { 15 | if (async !== true) async = false; 16 | return $.ajax({ 17 | url: path, 18 | method: 'GET', 19 | async: async 20 | }); 21 | } 22 | }; 23 | 24 | var component = { 25 | designView: false, 26 | cache: {}, 27 | load: function (name, path, async) { 28 | if (component.cache[name]) return null; 29 | return ajax.resource(name, path, async).done(function (html) { 30 | component.cache[name] = html; 31 | }); 32 | }, 33 | _appendDom: function (dom, elements, templates) { 34 | var id = $(dom).attr('tag'); 35 | if (!id) { 36 | component._searchDom(dom, elements, templates); 37 | return; 38 | } 39 | switch (id.charCodeAt(0)) { 40 | case 93: // ']', array element 41 | id = id.substring(1); 42 | if (!$.isArray(elements[id])) elements[id] = []; 43 | elements[id].push(dom); 44 | component._searchDom(dom, elements, templates); 45 | break; 46 | case 64: // '@', nest 47 | var subelements = {}, subtemplates = {}; 48 | id = id.substring(1); 49 | elements[id] = { 50 | self: dom, 51 | dom: subelements, 52 | template: subtemplates 53 | } 54 | component._searchDom(dom, subelements, subtemplates); 55 | break; 56 | case 43: // '+', template 57 | id = id.substring(1); 58 | if (!component.designView) { 59 | $(dom).removeAttr('tag'); 60 | if (templates[id]) { 61 | templates[id] += $(dom).prop('outerHTML'); 62 | } else { 63 | templates[id] = $(dom).prop('outerHTML'); 64 | } 65 | $(dom).remove(); 66 | break; 67 | } 68 | // if in design view, we can see the template as a dom 69 | // in browser; thus here should not have a break 70 | default: 71 | if (elements[id]) { 72 | if (!elements[id].length) { 73 | elements[id] = [elements[id], dom]; 74 | } else { 75 | elements[id].push(dom); 76 | } 77 | } else { 78 | elements[id] = dom; 79 | } 80 | component._searchDom(dom, elements, templates); 81 | } 82 | }, 83 | _searchDom: function (dom, elements, templates) { 84 | var ch = $(dom).children(); 85 | var n = ch.length; 86 | if (n <= 0) return; 87 | var i; 88 | for (i=0; i 95 | Name:
96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 |
AB
loading...loading...
105 |
106 | XYZ 107 |
108 |
109 |
110 |
111 | 112 | index.js 113 | $petal.ui.load('partial', 'partial.html', false); 114 | var control = $petal.ui.create('partial'); 115 | $(control.dom.txt_name).val("hello world"); 116 | $(control.dom.link[0]).click(function () { alert("0"); }); 117 | $(control.dom.link[1]).click(function () { alert("1"); }); 118 | $(control.dom.link[2]).click(function () { alert("2"); }); 119 | var item = $petal.ui.createT(control.template.item); 120 | $(item.dom.txt_a).text("hello"); 121 | $(item.dom.txt_b).text("world"); 122 | $(control.dom.items).append(item.self); 123 | $(control.dom.nest.dom.test).text('seprate world!'); 124 | $(document.body).append(control.self); 125 | */ 126 | createT: function (template, control) { 127 | if (!template) return null; 128 | if (!control) control = {}; 129 | var dom = $(template); 130 | return component.scan(dom, control); 131 | }, 132 | create: function (name, control) { 133 | return component.createT(component.cache[name], control); 134 | }, 135 | scan: function (dom, control) { 136 | if (!dom) return null; 137 | if (!control) control = {}; 138 | var elements = {}, templates = {}; 139 | if (dom.length === 1) { 140 | component._searchDom(dom, elements, templates); 141 | } else { 142 | for (var i = 0, n = dom.length; i < n; i++) { 143 | component._searchDom($(dom[i]), elements, templates); 144 | } 145 | } 146 | control.self = dom; 147 | control.dom = elements; 148 | control.template = templates; 149 | return control; 150 | }, 151 | empty: function (id) { 152 | var i, n, ch; 153 | ch = component.dom(id).children(); 154 | n = ch.length; 155 | for (i=0; i: { '@N': 0, : ... } 18 | // : { mtime, hash, size, filename, dup_hash, ... } 19 | }, 20 | }, 21 | }; 22 | 23 | const storage = { 24 | file: { 25 | baseDir: '', 26 | move: async (username, tmpfile, filename) => { 27 | // TODO: gurantee filename do not contains '..' 28 | let finalname = i_path.join(storage.file.baseDir, username, filename); 29 | let dirname = i_path.dirname(finalname); 30 | await helper.mkdir(dirname); 31 | await helper.rename(tmpfile, finalname); 32 | }, 33 | list: async (username, dirname) => { 34 | let finalname = i_path.join(storage.file.baseDir, username, dirname); 35 | return await helper.readDirectory(finalname); 36 | }, 37 | }, 38 | }; 39 | 40 | function getStorage() { 41 | let parts = system.upload.storage.split('://'); 42 | let protocol = parts[0]; 43 | let dirname = parts[1]; 44 | if (!dirname) dirname = system.upload.tmpdir; 45 | dirname = i_path.resolve(dirname); 46 | let storage_obj = storage[protocol] || storage['file']; 47 | storage_obj.baseDir = dirname; 48 | return storage_obj; 49 | } 50 | 51 | function validatePath(filename) { 52 | return !( 53 | filename === '..' || 54 | filename.endsWith('/..') || 55 | filename.startsWith('../') || 56 | filename.indexOf('/../') >= 0 57 | ); 58 | } 59 | 60 | function toByteArray(arr) { 61 | var n = arr.length; 62 | var b = new Uint8Array(n); 63 | for (var i = 0; i < n; i++) { 64 | b[i] = arr[i].charCodeAt(0); 65 | } 66 | arr = null; 67 | return b; 68 | } 69 | 70 | function cleanup() { 71 | Object.keys(system.files.uploading).forEach((username) => { 72 | if (username === '@N') return; 73 | let profile = system.files.uploading[username]; 74 | let count = 0; 75 | Object.keys(profile).forEach((uid) => { 76 | if (uid === '@N') return; 77 | let file_obj = profile[uid]; 78 | if (!file_obj) { 79 | delete profile[uid]; 80 | return; 81 | } 82 | if (file_obj.status === 'closed') { 83 | delete profile[uid]; 84 | return; 85 | } 86 | count ++; 87 | }); 88 | if (!count) { 89 | delete system.files.uploading[username]; 90 | } 91 | }); 92 | } 93 | 94 | function guranteeUuid(profile) { 95 | let uid = i_uuid.v4(); 96 | while (profile[uid]) { 97 | uid = i_uuid.v4(); 98 | } 99 | profile[uid] = {}; 100 | return uid; 101 | } 102 | 103 | const helper = { 104 | lstat: async (filename) => { 105 | return new Promise((r, e) => { 106 | i_fs.lstat(filename, (err, stat) => { 107 | if (err) return e(err); 108 | r(stat); 109 | }); 110 | }); 111 | }, // lstat 112 | rename: async (filename, new_filename) => { 113 | return new Promise((r, e) => { 114 | i_fs.rename(filename, new_filename, (err) => { 115 | if (err) return e(err); 116 | r(); 117 | }); 118 | }); 119 | }, // rename 120 | unlink: async (filename) => { 121 | return new Promise((r, e) => { 122 | i_fs.unlink(filename, (err) => { 123 | if (err) return e(err); 124 | r(); 125 | }); 126 | }); 127 | }, //unlink 128 | readdir: async (dirname) => { 129 | return new Promise((r, e) => { 130 | i_fs.readdir(dirname, (err, list) => { 131 | if (err) return e(err); 132 | r(list); 133 | }); 134 | }); 135 | }, //readdir 136 | readDirectory: async (dirname) => { 137 | let list = await helper.readdir(dirname); 138 | for (let i = 0, n = list.length; i < n; i++) { 139 | let item = list[i]; 140 | let filename = i_path.join(dirname, item); 141 | let stat = await helper.lstat(filename); 142 | if (stat.isDirectory()) { 143 | list[i] = list[i] + i_path.sep; 144 | } 145 | } 146 | return list; 147 | }, // readDirectory 148 | mkdir: async (dirname) => { 149 | let parent_dirname = i_path.dirname(dirname); 150 | let stat, ok; 151 | ok = false; 152 | try { 153 | stat = await helper.lstat(parent_dirname); 154 | ok = stat.isDirectory(); 155 | } catch(e) { 156 | // no such file or directory 157 | await helper.mkdir(parent_dirname); 158 | ok = true; 159 | } 160 | if (!ok) return Promise.reject(); 161 | try { 162 | stat = await helper.lstat(dirname); 163 | if (stat.isDirectory()) return Promise.resolve(); 164 | return Promise.reject(); 165 | } catch (e) { 166 | // no such directory 167 | } 168 | return new Promise((r, e) => { 169 | i_fs.mkdir(dirname, (err) => { 170 | if (err) return e(err); 171 | r(); 172 | }); 173 | }); 174 | }, // mkdir 175 | open: async (filename, flags) => { 176 | return new Promise((r, e) => { 177 | i_fs.open(filename, flags, (err, fd) => { 178 | if (err) return e(err); 179 | r(fd); 180 | }); 181 | }); 182 | }, // open 183 | close: async (fd) => { 184 | return new Promise((r, e) => { 185 | i_fs.close(fd, (err) => { 186 | if (err) return e(err); 187 | r(); 188 | }); 189 | }); 190 | }, // close 191 | write: async (fd, buf, size, offset) => { 192 | return new Promise((r, e) => { 193 | i_fs.write(fd, buf, 0, size, offset, (err, n) => { 194 | if (err) return e(err); 195 | r(n); 196 | }); 197 | }); 198 | }, // write 199 | openOrCreate: async (filename) => { 200 | try { 201 | return await helper.open(filename, 'r+'); 202 | } catch(e) { 203 | return await helper.open(filename, 'wx'); 204 | } 205 | }, // open_or_create 206 | saveData: async (filename, offset, size, buf) => { 207 | let dirname = i_path.dirname(filename); 208 | await helper.mkdir(dirname); 209 | let fd; 210 | if (offset === 0) { 211 | fd = await helper.open(filename, 'w'); 212 | } else { 213 | fd = await helper.open(filename, 'r+'); 214 | } 215 | let n = await helper.write(fd, buf, size, offset); 216 | fd && await helper.close(fd); 217 | return n; 218 | }, // saveData 219 | }; 220 | 221 | const api = { 222 | list: async (req, res, options) => { 223 | let username = options.json.username; 224 | let path = options.json.path; 225 | 226 | if (!path) path = '/'; 227 | let storage_obj = getStorage(); 228 | let list = await storage_obj.list(username, path); 229 | i_utils.Web.rjson(res, { 230 | list, base: path || '/' 231 | }); 232 | }, 233 | open: async (req, res, options) => { 234 | let username = options.json.username; 235 | let filename = options.json.filename; 236 | let filesize = parseInt(options.json.filesize); 237 | 238 | if (!filename || !filesize) return i_utils.Web.e400(res); 239 | // TODO: limit filename length 240 | if (!validatePath(filename)) return i_utils.Web.e400(res); 241 | if (system.files.uploading['@N'] >= system.upload.maxUpN) return i_utils.Web.e403(res); 242 | let profile = system.files.uploading[username]; 243 | if (!profile) { 244 | profile = { '@N': 0 }; 245 | system.files.uploading[username] = profile; 246 | } 247 | if (profile['@N'] >= system.upload.maxUpNpU) return i_utils.Web.e403(res); 248 | system.files.uploading['@N'] ++; 249 | profile['@N'] ++; 250 | 251 | let uid = guranteeUuid(profile); 252 | let file_obj = profile[uid]; 253 | file_obj.mtime = new Date().getTime(); 254 | file_obj.active_mtime = new Date().getTime(); 255 | file_obj.size = filesize; 256 | file_obj.filename = filename; // TODO: normalize filename 257 | file_obj.status = 'opened'; 258 | // hash, dup_hash 259 | res.end(`{ "file_id": "${uid}" }`); 260 | }, 261 | close: async (req, res, options) => { 262 | let username = options.json.username; 263 | let uid = options.json.file_id; 264 | let cancel = !!options.json.cancel; 265 | 266 | if (!uid) return i_utils.Web.e400(res); 267 | let profile = system.files.uploading[username]; 268 | if (!profile) return i_utils.Web.e400(res); 269 | if (uid === '@N') return i_utils.Web.e403(res); 270 | let file_obj = profile[uid]; 271 | if (!file_obj) return i_utils.Web.e400(res); 272 | if (cancel) { 273 | let filename = i_path.join(system.upload.tmpdir, username, uid); 274 | try { await helper.unlink(filename); } catch(err) {} 275 | } else if (file_obj.status !== 'error') { 276 | // TODO: calculate file hash, dup_hash and file size for check 277 | let tmpfile = i_path.join(system.upload.tmpdir, username, uid); 278 | await getStorage().move(username, tmpfile, file_obj.filename); 279 | } 280 | file_obj.active_mtime = new Date().getTime(); 281 | profile['@N'] --; 282 | system.files.uploading['@N'] --; 283 | file_obj.status = 'closed'; 284 | // to defeat DoS attack 285 | // where open and close many files to create many file objects in memory 286 | if (Object.keys(profile).length > system.upload.maxUpNpU + 1) { 287 | cleanup(); 288 | } 289 | res.end(`{ "file_id": "${uid}" }`); 290 | }, 291 | data: async (req, res, options) => { 292 | let username = options.json.username; 293 | let uid = options.json.file_id; 294 | if (!uid) return i_utils.Web.e400(res); 295 | let profile = system.files.uploading[username]; 296 | if (!profile) return i_utils.Web.e400(res); 297 | if (uid === '@N') return i_utils.Web.e403(res); 298 | let file_obj = profile[uid]; 299 | if (!file_obj) return i_utils.Web.e400(res); 300 | if (file_obj.size < options.json.file_offset) return i_utils.Web.e403(res); 301 | if (options.json.data.length > system.upload.maxSlice) return i_utils.Web.e403(res); 302 | let filename = i_path.join(system.upload.tmpdir, username, uid); 303 | await helper.saveData(filename, options.json.file_offset, options.json.data.length, toByteArray(options.json.data)); 304 | res.end(`{ "file_id": "${uid}" }`); 305 | }, 306 | }; 307 | 308 | i_utils.Web.require_login_batch(api); 309 | 310 | module.exports = api; 311 | -------------------------------------------------------------------------------- /upload/nodejs/uploader.js: -------------------------------------------------------------------------------- 1 | (function (window, document) { 2 | 3 | function Uploader(auth) { 4 | this.file = null; 5 | this.auth = auth; 6 | this.step = 2*1024*1024; // 2MB 7 | this.offset = 0; 8 | this.paused = true; 9 | } 10 | Uploader.prototype = { 11 | initFileReader: function () { 12 | var _this = this; 13 | this.reader = new FileReader(); 14 | this.reader.addEventListener('loadend', event_reader_loadend); 15 | function event_reader_loadend(e) { 16 | if (e.target.readyState === FileReader.DONE) { 17 | // TODO: if (_this.offset === 0) check dup 18 | _this.uploadBlob(_this.file_id, _this.file.size, _this.offset, e.target.result).then(function () { 19 | console.log('[upload complete] partial', _this.offset); 20 | _this.offset += _this.step; 21 | if (_this.offset >= _this.file.size) { 22 | console.log('[upload complete]'); 23 | ajax({ 24 | url: '/api/upload/close', 25 | method: 'POST', 26 | json: Object.assign({ 27 | file_id: _this.file_id, 28 | }, _this.auth) 29 | }); 30 | return; 31 | } 32 | if (!_this.paused) _this.reader.readAsBinaryString(_this.file.slice(_this.offset, _this.offset + _this.step)); 33 | }, function (err) { 34 | console.log(err, '[transfer error] paused'); 35 | _this.paused = true; 36 | }); 37 | } 38 | } 39 | }, 40 | uploadBlob: function (file_id, size, offset, data) { 41 | var _this = this; 42 | return new Promise(function (r, e) { 43 | ajax({ 44 | url: '/api/upload/data', 45 | method: 'POST', 46 | json: Object.assign({ 47 | data: data, 48 | file_id: file_id, 49 | file_offset: offset, 50 | file_size: size 51 | }, env.user) 52 | }, function () { 53 | console.log('[upload blob] done'); r(); 54 | }, function () { 55 | console.log('[upload blob] error'); e(); 56 | }); 57 | }); 58 | }, 59 | uploadFile: function (file) { 60 | console.log('[uploading]', this.file); 61 | var _this = this; 62 | _this.file = file; 63 | _this.file_id = null; 64 | _this.offset = 0; 65 | _this.step = 2*1024*1024; // 2MB 66 | ajax({ 67 | url: '/api/upload/open', 68 | method: 'POST', 69 | json: Object.assign({ 70 | filename: _this.file.name, 71 | filesize: _this.file.size 72 | }, _this.auth) 73 | }, function (data) { 74 | var json = JSON.parse(data); 75 | _this.paused = false; 76 | _this.file_id = json.file_id; 77 | // IE 10+: readAsArrayBuffer 78 | _this.initFileReader(); 79 | _this.reader.readAsBinaryString(_this.file.slice(0, _this.step)); 80 | }, function (err) { 81 | console.log('[open] error'); 82 | }); 83 | }, 84 | pause: function () { 85 | this.paused = true; 86 | }, 87 | resume: function () { 88 | this.paused = false; 89 | this.reader.readAsBinaryString(this.file.slice(this.offset, this.offset + this.step)); 90 | }, 91 | cancel: function () { 92 | this.offset = 0; 93 | this.paused = true; 94 | ajax({ 95 | url: '/api/upload/close', 96 | method: 'POST', 97 | json: Object.assign({ 98 | file_id: this.file_id, 99 | cancel: true, 100 | }, this.auth) 101 | }); 102 | this.file_id = null; 103 | } 104 | }; 105 | 106 | window.LargeFileUploader = Uploader; 107 | })(window, document); 108 | -------------------------------------------------------------------------------- /upload/static/index.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | Blob File Uploader 8 | 9 | 10 | 11 | 12 |
13 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /upload/static/jquery-2.1.4.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ 2 | !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ 3 | return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("