parlement 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +16 -0
- data/README +36 -3
- data/Rakefile +8 -12
- data/app/controllers/account_controller.rb +2 -0
- data/app/controllers/elt_controller.rb +1 -5
- data/app/controllers/subscriber_controller.rb +1 -1
- data/app/helpers/elt_helper.rb +30 -10
- data/app/models/elt.rb +2 -1
- data/app/models/mail.rb +41 -41
- data/app/models/mail_notify.rb +27 -10
- data/app/views/account/_login.rhtml +9 -7
- data/app/views/account/_show.rhtml +4 -4
- data/app/views/elt/_elt.rhtml +52 -51
- data/app/views/elt/_list.rhtml +22 -14
- data/app/views/elt/new.rhtml +1 -1
- data/app/views/elt/show.rhtml +15 -16
- data/app/views/layouts/top.rhtml +13 -1
- data/app/views/person/show.rhtml +1 -7
- data/config/boot.rb +32 -7
- data/config/database.yml +3 -0
- data/config/environment.rb +3 -1
- data/config/environments/development.rb +1 -1
- data/db/ROOT/parlement/ddRing.txt +14 -0
- data/db/ROOT/parlement/top-politics.txt +12 -0
- data/db/ROOT/perso.txt +1 -1
- data/db/development_structure.sql +30 -16
- data/db/schema.rb +18 -10
- data/db/schema.sql +34 -34
- data/public/javascripts/application.js +2 -0
- data/public/javascripts/blank.gif +0 -0
- data/public/javascripts/borders.js +687 -0
- data/public/javascripts/controls.js +95 -30
- data/public/javascripts/dragdrop.js +161 -21
- data/public/javascripts/effects.js +310 -211
- data/public/javascripts/ie7-load.htc +1 -0
- data/public/javascripts/prototype.js +228 -28
- data/test/fixtures/attachments.yml +3 -0
- data/test/fixtures/mail/mail_ruby +1 -0
- data/test/fixtures/people.yml +14 -0
- data/test/functional/account_controller_test.rb +3 -2
- data/test/unit/mail_notify_test.rb +2 -0
- data/test/unit/mail_test.rb +59 -6
- data/test/unit/person_test.rb +1 -1
- data/vendor/plugins/engines/CHANGELOG +92 -0
- data/vendor/plugins/engines/MIT-LICENSE +21 -0
- data/vendor/plugins/engines/README +325 -39
- data/vendor/plugins/engines/generators/engine/USAGE +26 -0
- data/vendor/plugins/engines/generators/engine/engine_generator.rb +199 -0
- data/vendor/plugins/engines/generators/engine/templates/README +85 -0
- data/vendor/plugins/engines/generators/engine/templates/init_engine.erb +13 -0
- data/vendor/plugins/engines/generators/engine/templates/install.erb +4 -0
- data/vendor/plugins/engines/generators/engine/templates/lib/engine.erb +6 -0
- data/vendor/plugins/engines/generators/engine/templates/licenses/GPL +18 -0
- data/vendor/plugins/engines/generators/engine/templates/licenses/LGPL +19 -0
- data/vendor/plugins/engines/generators/engine/templates/licenses/MIT +22 -0
- data/vendor/plugins/engines/generators/engine/templates/licenses/None +1 -0
- data/vendor/plugins/engines/generators/engine/templates/public/javascripts/engine.js +0 -0
- data/vendor/plugins/engines/generators/engine/templates/public/stylesheets/engine.css +0 -0
- data/vendor/plugins/engines/generators/engine/templates/tasks/engine.rake +0 -0
- data/vendor/plugins/engines/generators/engine/templates/test/test_helper.erb +13 -0
- data/vendor/plugins/engines/init.rb +18 -3
- data/vendor/plugins/engines/lib/bundles/require_resource.rb +124 -0
- data/vendor/plugins/engines/lib/bundles.rb +77 -0
- data/vendor/plugins/engines/lib/{action_mailer_extensions.rb → engines/action_mailer_extensions.rb} +15 -36
- data/vendor/plugins/engines/lib/{action_view_extensions.rb → engines/action_view_extensions.rb} +40 -33
- data/vendor/plugins/engines/lib/engines/active_record_extensions.rb +19 -0
- data/vendor/plugins/engines/lib/engines/dependencies_extensions.rb +118 -0
- data/vendor/plugins/engines/lib/engines/migration_extensions.rb +53 -0
- data/vendor/plugins/engines/lib/{ruby_extensions.rb → engines/ruby_extensions.rb} +14 -28
- data/vendor/plugins/engines/lib/engines/testing_extensions.rb +323 -0
- data/vendor/plugins/engines/lib/engines.rb +258 -148
- data/vendor/plugins/engines/tasks/engines.rake +161 -0
- data/vendor/plugins/engines/test/action_view_extensions_test.rb +9 -0
- data/vendor/plugins/engines/test/ruby_extensions_test.rb +24 -3
- data/vendor/plugins/guid/README.TXT +14 -4
- data/vendor/plugins/guid/init.rb +9 -2
- data/vendor/plugins/guid/lib/uuidtools.rb +22 -15
- data/vendor/plugins/login_engine/CHANGELOG +14 -0
- data/vendor/plugins/login_engine/README +93 -7
- data/vendor/plugins/login_engine/app/controllers/user_controller.rb +30 -20
- data/vendor/plugins/login_engine/app/helpers/user_helper.rb +1 -1
- data/vendor/plugins/login_engine/app/views/user/forgot_password.rhtml +2 -2
- data/vendor/plugins/login_engine/db/migrate/001_initial_schema.rb +25 -0
- data/vendor/plugins/login_engine/install.rb +4 -0
- data/vendor/plugins/login_engine/lib/login_engine/authenticated_system.rb +11 -5
- data/vendor/plugins/login_engine/lib/login_engine/authenticated_user.rb +15 -9
- data/vendor/plugins/login_engine/lib/login_engine.rb +7 -3
- data/vendor/plugins/login_engine/test/functional/user_controller_test.rb +22 -19
- data/vendor/plugins/login_engine/test/test_helper.rb +4 -8
- data/vendor/plugins/login_engine/test/unit/user_test.rb +31 -11
- metadata +60 -57
- data/app/models/attachment.rb +0 -6
- data/public/attachment/file/architecture.png +0 -0
- data/public/attachment/file/architecture.svg +0 -8972
- data/public/attachment/file/security.svg +0 -8960
- data/public/engine_files/login_engine/stylesheets/login_engine.css +0 -81
- data/public/oldREADME +0 -190
- data/public/stylesheets/default.css +0 -235
- data/public/stylesheets/live_tree.css +0 -62
- data/public/stylesheets/scaffold.css +0 -74
- data/script/about +0 -3
- data/script/benchmarker +0 -19
- data/script/breakpointer +0 -3
- data/script/console +0 -3
- data/script/create_db +0 -7
- data/script/destroy +0 -3
- data/script/generate +0 -3
- data/script/performance/benchmarker +0 -3
- data/script/performance/profiler +0 -3
- data/script/plugin +0 -3
- data/script/process/reaper +0 -3
- data/script/process/spawner +0 -3
- data/script/process/spinner +0 -3
- data/script/profiler +0 -34
- data/script/runner +0 -3
- data/script/server +0 -3
- data/test/unit/user_test.rb +0 -94
- data/vendor/plugins/engines/lib/dependencies_extensions.rb +0 -56
- data/vendor/plugins/engines/lib/testing_extensions.rb +0 -33
- data/vendor/plugins/login_engine/db/schema.rb +0 -25
- data/vendor/plugins/login_engine/test/fixtures/templates/users.yml +0 -41
- /data/public/images/{eltBackground.png → eltBackground.jng} +0 -0
@@ -6,8 +6,6 @@
|
|
6
6
|
//
|
7
7
|
// See scriptaculous.js for full license.
|
8
8
|
|
9
|
-
/* ------------- element ext -------------- */
|
10
|
-
|
11
9
|
// converts rgb() and #xxx to #xxxxxx format,
|
12
10
|
// returns self (or first argument) if not convertable
|
13
11
|
String.prototype.parseColor = function() {
|
@@ -22,33 +20,29 @@ String.prototype.parseColor = function() {
|
|
22
20
|
}
|
23
21
|
}
|
24
22
|
return(color.length==7 ? color : (arguments[0] || this));
|
25
|
-
}
|
23
|
+
}
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
text+=children[i].nodeValue;
|
35
|
-
} else {
|
36
|
-
if((!children[i].className.match(classtest)) && children[i].hasChildNodes())
|
37
|
-
text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass);
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
|
-
return text;
|
25
|
+
/*--------------------------------------------------------------------------*/
|
26
|
+
|
27
|
+
Element.collectTextNodes = function(element) {
|
28
|
+
return $A($(element).childNodes).collect( function(node) {
|
29
|
+
return (node.nodeType==3 ? node.nodeValue :
|
30
|
+
(node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
|
31
|
+
}).flatten().join('');
|
42
32
|
}
|
43
33
|
|
44
|
-
Element.
|
45
|
-
|
46
|
-
|
34
|
+
Element.collectTextNodesIgnoreClass = function(element, className) {
|
35
|
+
return $A($(element).childNodes).collect( function(node) {
|
36
|
+
return (node.nodeType==3 ? node.nodeValue :
|
37
|
+
((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
|
38
|
+
Element.collectTextNodesIgnoreClass(node, className) : ''));
|
39
|
+
}).flatten().join('');
|
47
40
|
}
|
48
41
|
|
49
|
-
Element.setContentZoom = function(element, percent) {
|
42
|
+
Element.setContentZoom = function(element, percent) {
|
43
|
+
element = $(element);
|
50
44
|
Element.setStyle(element, {fontSize: (percent/100) + 'em'});
|
51
|
-
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
|
45
|
+
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
|
52
46
|
}
|
53
47
|
|
54
48
|
Element.getOpacity = function(element){
|
@@ -75,18 +69,35 @@ Element.setOpacity = function(element, value){
|
|
75
69
|
Element.setStyle(element,
|
76
70
|
{ filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
|
77
71
|
'alpha(opacity='+value*100+')' });
|
78
|
-
}
|
72
|
+
}
|
79
73
|
}
|
80
74
|
|
81
75
|
Element.getInlineOpacity = function(element){
|
82
76
|
return $(element).style.opacity || '';
|
83
77
|
}
|
84
78
|
|
85
|
-
Element.childrenWithClassName = function(element, className) {
|
86
|
-
return $A($(element).getElementsByTagName('*'))
|
87
|
-
|
79
|
+
Element.childrenWithClassName = function(element, className, findFirst) {
|
80
|
+
return [$A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) {
|
81
|
+
return c.className ? Element.hasClassName(c, className) : false;
|
82
|
+
})].flatten();
|
88
83
|
}
|
89
84
|
|
85
|
+
Element.forceRerendering = function(element) {
|
86
|
+
try {
|
87
|
+
element = $(element);
|
88
|
+
var n = document.createTextNode(' ');
|
89
|
+
element.appendChild(n);
|
90
|
+
element.removeChild(n);
|
91
|
+
} catch(e) { }
|
92
|
+
};
|
93
|
+
|
94
|
+
['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
|
95
|
+
'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(
|
96
|
+
function(f) { Element.Methods[f] = Element[f]; }
|
97
|
+
);
|
98
|
+
|
99
|
+
/*--------------------------------------------------------------------------*/
|
100
|
+
|
90
101
|
Array.prototype.call = function() {
|
91
102
|
var args = arguments;
|
92
103
|
this.each(function(f){ f.apply(this, args) });
|
@@ -129,6 +140,20 @@ var Effect = {
|
|
129
140
|
$A(elements).each( function(element, index) {
|
130
141
|
new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
|
131
142
|
});
|
143
|
+
},
|
144
|
+
PAIRS: {
|
145
|
+
'slide': ['SlideDown','SlideUp'],
|
146
|
+
'blind': ['BlindDown','BlindUp'],
|
147
|
+
'appear': ['Appear','Fade']
|
148
|
+
},
|
149
|
+
toggle: function(element, effect) {
|
150
|
+
element = $(element);
|
151
|
+
effect = (effect || 'appear').toLowerCase();
|
152
|
+
var options = Object.extend({
|
153
|
+
queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
|
154
|
+
}, arguments[2] || {});
|
155
|
+
Effect[element.visible() ?
|
156
|
+
Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
|
132
157
|
}
|
133
158
|
};
|
134
159
|
|
@@ -166,16 +191,22 @@ Effect.Transitions.full = function(pos) {
|
|
166
191
|
|
167
192
|
/* ------------- core effects ------------- */
|
168
193
|
|
169
|
-
Effect.
|
170
|
-
|
194
|
+
Effect.ScopedQueue = Class.create();
|
195
|
+
Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
|
196
|
+
initialize: function() {
|
197
|
+
this.effects = [];
|
198
|
+
this.interval = null;
|
199
|
+
},
|
171
200
|
_each: function(iterator) {
|
172
201
|
this.effects._each(iterator);
|
173
202
|
},
|
174
|
-
interval: null,
|
175
203
|
add: function(effect) {
|
176
204
|
var timestamp = new Date().getTime();
|
177
205
|
|
178
|
-
|
206
|
+
var position = (typeof effect.options.queue == 'string') ?
|
207
|
+
effect.options.queue : effect.options.queue.position;
|
208
|
+
|
209
|
+
switch(position) {
|
179
210
|
case 'front':
|
180
211
|
// move unstarted effects after this effect
|
181
212
|
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
|
@@ -191,7 +222,10 @@ Effect.Queue = {
|
|
191
222
|
|
192
223
|
effect.startOn += timestamp;
|
193
224
|
effect.finishOn += timestamp;
|
194
|
-
|
225
|
+
|
226
|
+
if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
|
227
|
+
this.effects.push(effect);
|
228
|
+
|
195
229
|
if(!this.interval)
|
196
230
|
this.interval = setInterval(this.loop.bind(this), 40);
|
197
231
|
},
|
@@ -206,32 +240,45 @@ Effect.Queue = {
|
|
206
240
|
var timePos = new Date().getTime();
|
207
241
|
this.effects.invoke('loop', timePos);
|
208
242
|
}
|
243
|
+
});
|
244
|
+
|
245
|
+
Effect.Queues = {
|
246
|
+
instances: $H(),
|
247
|
+
get: function(queueName) {
|
248
|
+
if(typeof queueName != 'string') return queueName;
|
249
|
+
|
250
|
+
if(!this.instances[queueName])
|
251
|
+
this.instances[queueName] = new Effect.ScopedQueue();
|
252
|
+
|
253
|
+
return this.instances[queueName];
|
254
|
+
}
|
255
|
+
}
|
256
|
+
Effect.Queue = Effect.Queues.get('global');
|
257
|
+
|
258
|
+
Effect.DefaultOptions = {
|
259
|
+
transition: Effect.Transitions.sinoidal,
|
260
|
+
duration: 1.0, // seconds
|
261
|
+
fps: 25.0, // max. 25fps due to Effect.Queue implementation
|
262
|
+
sync: false, // true for combining
|
263
|
+
from: 0.0,
|
264
|
+
to: 1.0,
|
265
|
+
delay: 0.0,
|
266
|
+
queue: 'parallel'
|
209
267
|
}
|
210
|
-
Object.extend(Effect.Queue, Enumerable);
|
211
268
|
|
212
269
|
Effect.Base = function() {};
|
213
270
|
Effect.Base.prototype = {
|
214
271
|
position: null,
|
215
|
-
setOptions: function(options) {
|
216
|
-
this.options = Object.extend({
|
217
|
-
transition: Effect.Transitions.sinoidal,
|
218
|
-
duration: 1.0, // seconds
|
219
|
-
fps: 25.0, // max. 25fps due to Effect.Queue implementation
|
220
|
-
sync: false, // true for combining
|
221
|
-
from: 0.0,
|
222
|
-
to: 1.0,
|
223
|
-
delay: 0.0,
|
224
|
-
queue: 'parallel'
|
225
|
-
}, options || {});
|
226
|
-
},
|
227
272
|
start: function(options) {
|
228
|
-
this.
|
273
|
+
this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
|
229
274
|
this.currentFrame = 0;
|
230
275
|
this.state = 'idle';
|
231
276
|
this.startOn = this.options.delay*1000;
|
232
277
|
this.finishOn = this.startOn + (this.options.duration*1000);
|
233
278
|
this.event('beforeStart');
|
234
|
-
if(!this.options.sync)
|
279
|
+
if(!this.options.sync)
|
280
|
+
Effect.Queues.get(typeof this.options.queue == 'string' ?
|
281
|
+
'global' : this.options.queue.scope).add(this);
|
235
282
|
},
|
236
283
|
loop: function(timePos) {
|
237
284
|
if(timePos >= this.startOn) {
|
@@ -269,7 +316,9 @@ Effect.Base.prototype = {
|
|
269
316
|
}
|
270
317
|
},
|
271
318
|
cancel: function() {
|
272
|
-
if(!this.options.sync)
|
319
|
+
if(!this.options.sync)
|
320
|
+
Effect.Queues.get(typeof this.options.queue == 'string' ?
|
321
|
+
'global' : this.options.queue.scope).remove(this);
|
273
322
|
this.state = 'finished';
|
274
323
|
},
|
275
324
|
event: function(eventName) {
|
@@ -307,43 +356,57 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
|
|
307
356
|
this.element = $(element);
|
308
357
|
// make this work on IE on elements without 'layout'
|
309
358
|
if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
|
310
|
-
|
359
|
+
this.element.setStyle({zoom: 1});
|
311
360
|
var options = Object.extend({
|
312
|
-
from:
|
361
|
+
from: this.element.getOpacity() || 0.0,
|
313
362
|
to: 1.0
|
314
363
|
}, arguments[1] || {});
|
315
364
|
this.start(options);
|
316
365
|
},
|
317
366
|
update: function(position) {
|
318
|
-
|
367
|
+
this.element.setOpacity(position);
|
319
368
|
}
|
320
369
|
});
|
321
370
|
|
322
|
-
Effect.
|
323
|
-
Object.extend(Object.extend(Effect.
|
324
|
-
initialize: function(element
|
325
|
-
this.element
|
326
|
-
|
327
|
-
|
328
|
-
|
371
|
+
Effect.Move = Class.create();
|
372
|
+
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
|
373
|
+
initialize: function(element) {
|
374
|
+
this.element = $(element);
|
375
|
+
var options = Object.extend({
|
376
|
+
x: 0,
|
377
|
+
y: 0,
|
378
|
+
mode: 'relative'
|
379
|
+
}, arguments[1] || {});
|
380
|
+
this.start(options);
|
329
381
|
},
|
330
382
|
setup: function() {
|
331
383
|
// Bug in Opera: Opera returns the "real" position of a static element or
|
332
384
|
// relative element that does not have top/left explicitly set.
|
333
385
|
// ==> Always set top and left for position relative elements in your stylesheets
|
334
386
|
// (to 0 if you do not need them)
|
335
|
-
|
336
|
-
this.
|
337
|
-
this.
|
387
|
+
this.element.makePositioned();
|
388
|
+
this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
|
389
|
+
this.originalTop = parseFloat(this.element.getStyle('top') || '0');
|
390
|
+
if(this.options.mode == 'absolute') {
|
391
|
+
// absolute movement, so we need to calc deltaX and deltaY
|
392
|
+
this.options.x = this.options.x - this.originalLeft;
|
393
|
+
this.options.y = this.options.y - this.originalTop;
|
394
|
+
}
|
338
395
|
},
|
339
396
|
update: function(position) {
|
340
|
-
|
341
|
-
|
342
|
-
|
397
|
+
this.element.setStyle({
|
398
|
+
left: this.options.x * position + this.originalLeft + 'px',
|
399
|
+
top: this.options.y * position + this.originalTop + 'px'
|
343
400
|
});
|
344
401
|
}
|
345
402
|
});
|
346
403
|
|
404
|
+
// for backwards compatibility
|
405
|
+
Effect.MoveBy = function(element, toTop, toLeft) {
|
406
|
+
return new Effect.Move(element,
|
407
|
+
Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
|
408
|
+
};
|
409
|
+
|
347
410
|
Effect.Scale = Class.create();
|
348
411
|
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
|
349
412
|
initialize: function(element, percent) {
|
@@ -361,7 +424,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
|
|
361
424
|
},
|
362
425
|
setup: function() {
|
363
426
|
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
|
364
|
-
this.elementPositioning =
|
427
|
+
this.elementPositioning = this.element.getStyle('position');
|
365
428
|
|
366
429
|
this.originalStyle = {};
|
367
430
|
['top','left','width','height','fontSize'].each( function(k) {
|
@@ -371,7 +434,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
|
|
371
434
|
this.originalTop = this.element.offsetTop;
|
372
435
|
this.originalLeft = this.element.offsetLeft;
|
373
436
|
|
374
|
-
var fontSize =
|
437
|
+
var fontSize = this.element.getStyle('font-size') || '100%';
|
375
438
|
['em','px','%'].each( function(fontSizeType) {
|
376
439
|
if(fontSize.indexOf(fontSizeType)>0) {
|
377
440
|
this.fontSize = parseFloat(fontSize);
|
@@ -393,11 +456,11 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
|
|
393
456
|
update: function(position) {
|
394
457
|
var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
|
395
458
|
if(this.options.scaleContent && this.fontSize)
|
396
|
-
|
459
|
+
this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
|
397
460
|
this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
|
398
461
|
},
|
399
462
|
finish: function(position) {
|
400
|
-
if (this.restoreAfterFinish)
|
463
|
+
if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
|
401
464
|
},
|
402
465
|
setDimensions: function(height, width) {
|
403
466
|
var d = {};
|
@@ -414,7 +477,7 @@ Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
|
|
414
477
|
if(this.options.scaleX) d.left = -leftd + 'px';
|
415
478
|
}
|
416
479
|
}
|
417
|
-
|
480
|
+
this.element.setStyle(d);
|
418
481
|
}
|
419
482
|
});
|
420
483
|
|
@@ -427,25 +490,25 @@ Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype),
|
|
427
490
|
},
|
428
491
|
setup: function() {
|
429
492
|
// Prevent executing on elements not in the layout flow
|
430
|
-
if(
|
493
|
+
if(this.element.getStyle('display')=='none') { this.cancel(); return; }
|
431
494
|
// Disable background image during the effect
|
432
495
|
this.oldStyle = {
|
433
|
-
backgroundImage:
|
434
|
-
|
496
|
+
backgroundImage: this.element.getStyle('background-image') };
|
497
|
+
this.element.setStyle({backgroundImage: 'none'});
|
435
498
|
if(!this.options.endcolor)
|
436
|
-
this.options.endcolor =
|
499
|
+
this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
|
437
500
|
if(!this.options.restorecolor)
|
438
|
-
this.options.restorecolor =
|
501
|
+
this.options.restorecolor = this.element.getStyle('background-color');
|
439
502
|
// init color calculations
|
440
503
|
this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
|
441
504
|
this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
|
442
505
|
},
|
443
506
|
update: function(position) {
|
444
|
-
|
507
|
+
this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
|
445
508
|
return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
|
446
509
|
},
|
447
510
|
finish: function() {
|
448
|
-
|
511
|
+
this.element.setStyle(Object.extend(this.oldStyle, {
|
449
512
|
backgroundColor: this.options.restorecolor
|
450
513
|
}));
|
451
514
|
}
|
@@ -479,85 +542,91 @@ Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
|
|
479
542
|
/* ------------- combination effects ------------- */
|
480
543
|
|
481
544
|
Effect.Fade = function(element) {
|
482
|
-
|
545
|
+
element = $(element);
|
546
|
+
var oldOpacity = element.getInlineOpacity();
|
483
547
|
var options = Object.extend({
|
484
|
-
from:
|
548
|
+
from: element.getOpacity() || 1.0,
|
485
549
|
to: 0.0,
|
486
|
-
afterFinishInternal: function(effect) {
|
550
|
+
afterFinishInternal: function(effect) {
|
487
551
|
if(effect.options.to!=0) return;
|
488
|
-
|
489
|
-
|
490
|
-
}, arguments[1] || {});
|
552
|
+
effect.element.hide();
|
553
|
+
effect.element.setStyle({opacity: oldOpacity});
|
554
|
+
}}, arguments[1] || {});
|
491
555
|
return new Effect.Opacity(element,options);
|
492
556
|
}
|
493
557
|
|
494
558
|
Effect.Appear = function(element) {
|
559
|
+
element = $(element);
|
495
560
|
var options = Object.extend({
|
496
|
-
from: (
|
561
|
+
from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
|
497
562
|
to: 1.0,
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
},
|
563
|
+
// force Safari to render floated elements properly
|
564
|
+
afterFinishInternal: function(effect) {
|
565
|
+
effect.element.forceRerendering();
|
566
|
+
},
|
567
|
+
beforeSetup: function(effect) {
|
568
|
+
effect.element.setOpacity(effect.options.from);
|
569
|
+
effect.element.show();
|
570
|
+
}}, arguments[1] || {});
|
502
571
|
return new Effect.Opacity(element,options);
|
503
572
|
}
|
504
573
|
|
505
574
|
Effect.Puff = function(element) {
|
506
575
|
element = $(element);
|
507
|
-
var oldStyle = { opacity:
|
576
|
+
var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') };
|
508
577
|
return new Effect.Parallel(
|
509
578
|
[ new Effect.Scale(element, 200,
|
510
579
|
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
|
511
580
|
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
|
512
581
|
Object.extend({ duration: 1.0,
|
513
|
-
beforeSetupInternal: function(effect) {
|
514
|
-
|
515
|
-
afterFinishInternal: function(effect) {
|
516
|
-
|
517
|
-
|
582
|
+
beforeSetupInternal: function(effect) {
|
583
|
+
effect.effects[0].element.setStyle({position: 'absolute'}); },
|
584
|
+
afterFinishInternal: function(effect) {
|
585
|
+
effect.effects[0].element.hide();
|
586
|
+
effect.effects[0].element.setStyle(oldStyle); }
|
518
587
|
}, arguments[1] || {})
|
519
588
|
);
|
520
589
|
}
|
521
590
|
|
522
591
|
Effect.BlindUp = function(element) {
|
523
592
|
element = $(element);
|
524
|
-
|
593
|
+
element.makeClipping();
|
525
594
|
return new Effect.Scale(element, 0,
|
526
595
|
Object.extend({ scaleContent: false,
|
527
596
|
scaleX: false,
|
528
597
|
restoreAfterFinish: true,
|
529
|
-
afterFinishInternal: function(effect) {
|
530
|
-
|
598
|
+
afterFinishInternal: function(effect) {
|
599
|
+
effect.element.hide();
|
600
|
+
effect.element.undoClipping();
|
601
|
+
}
|
531
602
|
}, arguments[1] || {})
|
532
603
|
);
|
533
604
|
}
|
534
605
|
|
535
606
|
Effect.BlindDown = function(element) {
|
536
607
|
element = $(element);
|
537
|
-
var
|
538
|
-
var elementDimensions = Element.getDimensions(element);
|
608
|
+
var elementDimensions = element.getDimensions();
|
539
609
|
return new Effect.Scale(element, 100,
|
540
610
|
Object.extend({ scaleContent: false,
|
541
611
|
scaleX: false,
|
542
612
|
scaleFrom: 0,
|
543
613
|
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
|
544
614
|
restoreAfterFinish: true,
|
545
|
-
afterSetup: function(effect) {
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
}
|
550
|
-
afterFinishInternal: function(effect) {
|
551
|
-
|
552
|
-
|
553
|
-
}}
|
615
|
+
afterSetup: function(effect) {
|
616
|
+
effect.element.makeClipping();
|
617
|
+
effect.element.setStyle({height: '0px'});
|
618
|
+
effect.element.show();
|
619
|
+
},
|
620
|
+
afterFinishInternal: function(effect) {
|
621
|
+
effect.element.undoClipping();
|
622
|
+
}
|
554
623
|
}, arguments[1] || {})
|
555
624
|
);
|
556
625
|
}
|
557
626
|
|
558
627
|
Effect.SwitchOff = function(element) {
|
559
628
|
element = $(element);
|
560
|
-
var oldOpacity =
|
629
|
+
var oldOpacity = element.getInlineOpacity();
|
561
630
|
return new Effect.Appear(element, {
|
562
631
|
duration: 0.4,
|
563
632
|
from: 0,
|
@@ -566,13 +635,16 @@ Effect.SwitchOff = function(element) {
|
|
566
635
|
new Effect.Scale(effect.element, 1, {
|
567
636
|
duration: 0.3, scaleFromCenter: true,
|
568
637
|
scaleX: false, scaleContent: false, restoreAfterFinish: true,
|
569
|
-
beforeSetup: function(effect) {
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
638
|
+
beforeSetup: function(effect) {
|
639
|
+
effect.element.makePositioned();
|
640
|
+
effect.element.makeClipping();
|
641
|
+
},
|
642
|
+
afterFinishInternal: function(effect) {
|
643
|
+
effect.element.hide();
|
644
|
+
effect.element.undoClipping();
|
645
|
+
effect.element.undoPositioned();
|
646
|
+
effect.element.setStyle({opacity: oldOpacity});
|
647
|
+
}
|
576
648
|
})
|
577
649
|
}
|
578
650
|
});
|
@@ -581,99 +653,110 @@ Effect.SwitchOff = function(element) {
|
|
581
653
|
Effect.DropOut = function(element) {
|
582
654
|
element = $(element);
|
583
655
|
var oldStyle = {
|
584
|
-
top:
|
585
|
-
left:
|
586
|
-
opacity:
|
656
|
+
top: element.getStyle('top'),
|
657
|
+
left: element.getStyle('left'),
|
658
|
+
opacity: element.getInlineOpacity() };
|
587
659
|
return new Effect.Parallel(
|
588
|
-
[ new Effect.
|
660
|
+
[ new Effect.Move(element, {x: 0, y: 100, sync: true }),
|
589
661
|
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
|
590
662
|
Object.extend(
|
591
663
|
{ duration: 0.5,
|
592
|
-
beforeSetup: function(effect) {
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
664
|
+
beforeSetup: function(effect) {
|
665
|
+
effect.effects[0].element.makePositioned();
|
666
|
+
},
|
667
|
+
afterFinishInternal: function(effect) {
|
668
|
+
effect.effects[0].element.hide();
|
669
|
+
effect.effects[0].element.undoPositioned();
|
670
|
+
effect.effects[0].element.setStyle(oldStyle);
|
671
|
+
}
|
597
672
|
}, arguments[1] || {}));
|
598
673
|
}
|
599
674
|
|
600
675
|
Effect.Shake = function(element) {
|
601
676
|
element = $(element);
|
602
677
|
var oldStyle = {
|
603
|
-
top:
|
604
|
-
left:
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
}}
|
678
|
+
top: element.getStyle('top'),
|
679
|
+
left: element.getStyle('left') };
|
680
|
+
return new Effect.Move(element,
|
681
|
+
{ x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
|
682
|
+
new Effect.Move(effect.element,
|
683
|
+
{ x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
|
684
|
+
new Effect.Move(effect.element,
|
685
|
+
{ x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
|
686
|
+
new Effect.Move(effect.element,
|
687
|
+
{ x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
|
688
|
+
new Effect.Move(effect.element,
|
689
|
+
{ x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
|
690
|
+
new Effect.Move(effect.element,
|
691
|
+
{ x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
|
692
|
+
effect.element.undoPositioned();
|
693
|
+
effect.element.setStyle(oldStyle);
|
694
|
+
}}) }}) }}) }}) }}) }});
|
620
695
|
}
|
621
696
|
|
622
697
|
Effect.SlideDown = function(element) {
|
623
698
|
element = $(element);
|
624
|
-
|
699
|
+
element.cleanWhitespace();
|
625
700
|
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
|
626
|
-
var oldInnerBottom =
|
627
|
-
var elementDimensions =
|
701
|
+
var oldInnerBottom = $(element.firstChild).getStyle('bottom');
|
702
|
+
var elementDimensions = element.getDimensions();
|
628
703
|
return new Effect.Scale(element, 100, Object.extend({
|
629
704
|
scaleContent: false,
|
630
705
|
scaleX: false,
|
631
706
|
scaleFrom: 0,
|
632
707
|
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
|
633
708
|
restoreAfterFinish: true,
|
634
|
-
afterSetup: function(effect) {
|
635
|
-
|
636
|
-
|
637
|
-
if(window.opera)
|
638
|
-
|
639
|
-
|
640
|
-
show(
|
641
|
-
afterUpdateInternal: function(effect) {
|
642
|
-
|
643
|
-
(effect.dims[0] - effect.element.clientHeight) + 'px' });
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
undoPositioned
|
648
|
-
|
709
|
+
afterSetup: function(effect) {
|
710
|
+
effect.element.makePositioned();
|
711
|
+
effect.element.firstChild.makePositioned();
|
712
|
+
if(window.opera) effect.element.setStyle({top: ''});
|
713
|
+
effect.element.makeClipping();
|
714
|
+
effect.element.setStyle({height: '0px'});
|
715
|
+
effect.element.show(); },
|
716
|
+
afterUpdateInternal: function(effect) {
|
717
|
+
effect.element.firstChild.setStyle({bottom:
|
718
|
+
(effect.dims[0] - effect.element.clientHeight) + 'px' });
|
719
|
+
},
|
720
|
+
afterFinishInternal: function(effect) {
|
721
|
+
effect.element.undoClipping();
|
722
|
+
// IE will crash if child is undoPositioned first
|
723
|
+
if(/MSIE/.test(navigator.userAgent)){
|
724
|
+
effect.element.undoPositioned();
|
725
|
+
effect.element.firstChild.undoPositioned();
|
726
|
+
}else{
|
727
|
+
effect.element.firstChild.undoPositioned();
|
728
|
+
effect.element.undoPositioned();
|
729
|
+
}
|
730
|
+
effect.element.firstChild.setStyle({bottom: oldInnerBottom}); }
|
649
731
|
}, arguments[1] || {})
|
650
732
|
);
|
651
733
|
}
|
652
734
|
|
653
735
|
Effect.SlideUp = function(element) {
|
654
736
|
element = $(element);
|
655
|
-
|
656
|
-
var oldInnerBottom =
|
737
|
+
element.cleanWhitespace();
|
738
|
+
var oldInnerBottom = $(element.firstChild).getStyle('bottom');
|
657
739
|
return new Effect.Scale(element, 0,
|
658
740
|
Object.extend({ scaleContent: false,
|
659
741
|
scaleX: false,
|
660
742
|
scaleMode: 'box',
|
661
743
|
scaleFrom: 100,
|
662
744
|
restoreAfterFinish: true,
|
663
|
-
beforeStartInternal: function(effect) {
|
664
|
-
|
665
|
-
|
666
|
-
if(window.opera)
|
667
|
-
|
668
|
-
show(
|
669
|
-
afterUpdateInternal: function(effect) {
|
670
|
-
|
671
|
-
(effect.dims[0] - effect.element.clientHeight) + 'px' }); }
|
672
|
-
afterFinishInternal: function(effect) {
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
745
|
+
beforeStartInternal: function(effect) {
|
746
|
+
effect.element.makePositioned();
|
747
|
+
effect.element.firstChild.makePositioned();
|
748
|
+
if(window.opera) effect.element.setStyle({top: ''});
|
749
|
+
effect.element.makeClipping();
|
750
|
+
effect.element.show(); },
|
751
|
+
afterUpdateInternal: function(effect) {
|
752
|
+
effect.element.firstChild.setStyle({bottom:
|
753
|
+
(effect.dims[0] - effect.element.clientHeight) + 'px' }); },
|
754
|
+
afterFinishInternal: function(effect) {
|
755
|
+
effect.element.hide();
|
756
|
+
effect.element.undoClipping();
|
757
|
+
effect.element.firstChild.undoPositioned();
|
758
|
+
effect.element.undoPositioned();
|
759
|
+
effect.element.setStyle({bottom: oldInnerBottom}); }
|
677
760
|
}, arguments[1] || {})
|
678
761
|
);
|
679
762
|
}
|
@@ -682,11 +765,11 @@ Effect.SlideUp = function(element) {
|
|
682
765
|
Effect.Squish = function(element) {
|
683
766
|
return new Effect.Scale(element, window.opera ? 1 : 0,
|
684
767
|
{ restoreAfterFinish: true,
|
685
|
-
beforeSetup: function(effect) {
|
686
|
-
makeClipping(effect.element); }
|
687
|
-
afterFinishInternal: function(effect) {
|
688
|
-
hide(effect.element);
|
689
|
-
undoClipping(effect.element); }
|
768
|
+
beforeSetup: function(effect) {
|
769
|
+
effect.element.makeClipping(effect.element); },
|
770
|
+
afterFinishInternal: function(effect) {
|
771
|
+
effect.element.hide(effect.element);
|
772
|
+
effect.element.undoClipping(effect.element); }
|
690
773
|
});
|
691
774
|
}
|
692
775
|
|
@@ -694,7 +777,7 @@ Effect.Grow = function(element) {
|
|
694
777
|
element = $(element);
|
695
778
|
var options = Object.extend({
|
696
779
|
direction: 'center',
|
697
|
-
|
780
|
+
moveTransition: Effect.Transitions.sinoidal,
|
698
781
|
scaleTransition: Effect.Transitions.sinoidal,
|
699
782
|
opacityTransition: Effect.Transitions.full
|
700
783
|
}, arguments[1] || {});
|
@@ -703,9 +786,9 @@ Effect.Grow = function(element) {
|
|
703
786
|
left: element.style.left,
|
704
787
|
height: element.style.height,
|
705
788
|
width: element.style.width,
|
706
|
-
opacity:
|
789
|
+
opacity: element.getInlineOpacity() };
|
707
790
|
|
708
|
-
var dims =
|
791
|
+
var dims = element.getDimensions();
|
709
792
|
var initialMoveX, initialMoveY;
|
710
793
|
var moveX, moveY;
|
711
794
|
|
@@ -737,27 +820,32 @@ Effect.Grow = function(element) {
|
|
737
820
|
break;
|
738
821
|
}
|
739
822
|
|
740
|
-
return new Effect.
|
823
|
+
return new Effect.Move(element, {
|
824
|
+
x: initialMoveX,
|
825
|
+
y: initialMoveY,
|
741
826
|
duration: 0.01,
|
742
|
-
beforeSetup: function(effect) {
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
}
|
827
|
+
beforeSetup: function(effect) {
|
828
|
+
effect.element.hide();
|
829
|
+
effect.element.makeClipping();
|
830
|
+
effect.element.makePositioned();
|
831
|
+
},
|
747
832
|
afterFinishInternal: function(effect) {
|
748
833
|
new Effect.Parallel(
|
749
834
|
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
|
750
|
-
new Effect.
|
835
|
+
new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
|
751
836
|
new Effect.Scale(effect.element, 100, {
|
752
837
|
scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
|
753
838
|
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
|
754
839
|
], Object.extend({
|
755
|
-
beforeSetup: function(effect) {
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
840
|
+
beforeSetup: function(effect) {
|
841
|
+
effect.effects[0].element.setStyle({height: '0px'});
|
842
|
+
effect.effects[0].element.show();
|
843
|
+
},
|
844
|
+
afterFinishInternal: function(effect) {
|
845
|
+
effect.effects[0].element.undoClipping();
|
846
|
+
effect.effects[0].element.undoPositioned();
|
847
|
+
effect.effects[0].element.setStyle(oldStyle);
|
848
|
+
}
|
761
849
|
}, options)
|
762
850
|
)
|
763
851
|
}
|
@@ -768,7 +856,7 @@ Effect.Shrink = function(element) {
|
|
768
856
|
element = $(element);
|
769
857
|
var options = Object.extend({
|
770
858
|
direction: 'center',
|
771
|
-
|
859
|
+
moveTransition: Effect.Transitions.sinoidal,
|
772
860
|
scaleTransition: Effect.Transitions.sinoidal,
|
773
861
|
opacityTransition: Effect.Transitions.none
|
774
862
|
}, arguments[1] || {});
|
@@ -777,9 +865,9 @@ Effect.Shrink = function(element) {
|
|
777
865
|
left: element.style.left,
|
778
866
|
height: element.style.height,
|
779
867
|
width: element.style.width,
|
780
|
-
opacity:
|
868
|
+
opacity: element.getInlineOpacity() };
|
781
869
|
|
782
|
-
var dims =
|
870
|
+
var dims = element.getDimensions();
|
783
871
|
var moveX, moveY;
|
784
872
|
|
785
873
|
switch (options.direction) {
|
@@ -807,13 +895,16 @@ Effect.Shrink = function(element) {
|
|
807
895
|
return new Effect.Parallel(
|
808
896
|
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
|
809
897
|
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
|
810
|
-
new Effect.
|
898
|
+
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
|
811
899
|
], Object.extend({
|
812
|
-
beforeStartInternal: function(effect) {
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
900
|
+
beforeStartInternal: function(effect) {
|
901
|
+
effect.effects[0].element.makePositioned();
|
902
|
+
effect.effects[0].element.makeClipping(); },
|
903
|
+
afterFinishInternal: function(effect) {
|
904
|
+
effect.effects[0].element.hide();
|
905
|
+
effect.effects[0].element.undoClipping();
|
906
|
+
effect.effects[0].element.undoPositioned();
|
907
|
+
effect.effects[0].element.setStyle(oldStyle); }
|
817
908
|
}, options)
|
818
909
|
);
|
819
910
|
}
|
@@ -821,13 +912,13 @@ Effect.Shrink = function(element) {
|
|
821
912
|
Effect.Pulsate = function(element) {
|
822
913
|
element = $(element);
|
823
914
|
var options = arguments[1] || {};
|
824
|
-
var oldOpacity =
|
915
|
+
var oldOpacity = element.getInlineOpacity();
|
825
916
|
var transition = options.transition || Effect.Transitions.sinoidal;
|
826
917
|
var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
|
827
918
|
reverser.bind(transition);
|
828
919
|
return new Effect.Opacity(element,
|
829
920
|
Object.extend(Object.extend({ duration: 3.0, from: 0,
|
830
|
-
afterFinishInternal: function(effect) {
|
921
|
+
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
|
831
922
|
}, options), {transition: reverser}));
|
832
923
|
}
|
833
924
|
|
@@ -846,9 +937,17 @@ Effect.Fold = function(element) {
|
|
846
937
|
new Effect.Scale(element, 1, {
|
847
938
|
scaleContent: false,
|
848
939
|
scaleY: false,
|
849
|
-
afterFinishInternal: function(effect) {
|
850
|
-
|
851
|
-
|
852
|
-
|
940
|
+
afterFinishInternal: function(effect) {
|
941
|
+
effect.element.hide();
|
942
|
+
effect.element.undoClipping();
|
943
|
+
effect.element.setStyle(oldStyle);
|
944
|
+
} });
|
853
945
|
}}, arguments[1] || {}));
|
854
946
|
}
|
947
|
+
|
948
|
+
Element.Methods.visualEffect = function(element, effect, options) {
|
949
|
+
s = effect.gsub(/_/, '-').camelize();
|
950
|
+
effect_class = s.charAt(0).toUpperCase() + s.substring(1);
|
951
|
+
new Effect[effect_class](element, options);
|
952
|
+
return $(element);
|
953
|
+
};
|