~johnsca/charms/trusty/cloudfoundry/better-basic-reconciler-status

« back to all changes in this revision

Viewing changes to reconciler/ui/static/semantic/uncompressed/modules/chatroom.js

  • Committer: Whit Morriss
  • Date: 2014-10-13 06:50:17 UTC
  • mto: (132.2.1 reconciler) (145.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 156.
  • Revision ID: whit.morriss@canonical.com-20141013065017-0feo2ku3yllymkol
reorg reconciler

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * # Semantic - Chatroom
 
3
 * http://github.com/jlukic/semantic-ui/
 
4
 *
 
5
 *
 
6
 * Copyright 2014 Contributors
 
7
 * Released under the MIT license
 
8
 * http://opensource.org/licenses/MIT
 
9
 *
 
10
 */
 
11
 
 
12
;(function ($, window, document, undefined) {
 
13
 
 
14
$.fn.chatroom = function(parameters) {
 
15
  var
 
16
    $allModules    = $(this),
 
17
    moduleSelector = $allModules.selector || '',
 
18
 
 
19
    time           = new Date().getTime(),
 
20
    performance    = [],
 
21
 
 
22
    query          = arguments[0],
 
23
    methodInvoked  = (typeof query == 'string'),
 
24
    queryArguments = [].slice.call(arguments, 1),
 
25
    returnedValue
 
26
  ;
 
27
  $(this)
 
28
    .each(function() {
 
29
      var
 
30
        settings  = $.extend(true, {}, $.fn.chatroom.settings, parameters),
 
31
 
 
32
        className = settings.className,
 
33
        namespace = settings.namespace,
 
34
        selector  = settings.selector,
 
35
        error     = settings.error,
 
36
 
 
37
        $module         = $(this),
 
38
 
 
39
        $expandButton   = $module.find(selector.expandButton),
 
40
        $userListButton = $module.find(selector.userListButton),
 
41
 
 
42
        $userList       = $module.find(selector.userList),
 
43
        $room           = $module.find(selector.room),
 
44
        $userCount      = $module.find(selector.userCount),
 
45
 
 
46
        $log            = $module.find(selector.log),
 
47
        $message        = $module.find(selector.message),
 
48
 
 
49
        $messageInput   = $module.find(selector.messageInput),
 
50
        $messageButton  = $module.find(selector.messageButton),
 
51
 
 
52
        instance        = $module.data('module'),
 
53
        element         = this,
 
54
 
 
55
        html            = '',
 
56
        users           = {},
 
57
 
 
58
        channel,
 
59
        loggedInUser,
 
60
 
 
61
        message,
 
62
        count,
 
63
 
 
64
        height,
 
65
 
 
66
        pusher,
 
67
        module
 
68
      ;
 
69
 
 
70
      module = {
 
71
 
 
72
        width: {
 
73
          log      : $log.width(),
 
74
          userList : $userList.outerWidth()
 
75
        },
 
76
 
 
77
        initialize: function() {
 
78
 
 
79
          // check error conditions
 
80
          if(Pusher === undefined) {
 
81
            module.error(error.pusher);
 
82
          }
 
83
          if(settings.key === undefined || settings.channelName === undefined) {
 
84
            module.error(error.key);
 
85
            return false;
 
86
          }
 
87
          else if( !(settings.endpoint.message || settings.endpoint.authentication) ) {
 
88
            module.error(error.endpoint);
 
89
            return false;
 
90
          }
 
91
 
 
92
          // define pusher
 
93
          pusher                       = new Pusher(settings.key);
 
94
          Pusher.channel_auth_endpoint = settings.endpoint.authentication;
 
95
 
 
96
          channel = pusher.subscribe(settings.channelName);
 
97
 
 
98
          channel.bind('pusher:subscription_succeeded', module.user.list.create);
 
99
          channel.bind('pusher:subscription_error', module.error);
 
100
          channel.bind('pusher:member_added', module.user.joined);
 
101
          channel.bind('pusher:member_removed', module.user.left);
 
102
          channel.bind('update_messages', module.message.receive);
 
103
 
 
104
          $.each(settings.customEvents, function(label, value) {
 
105
            channel.bind(label, value);
 
106
          });
 
107
 
 
108
          // bind module events
 
109
          $userListButton
 
110
            .on('click.' +  namespace, module.event.toggleUserList)
 
111
          ;
 
112
          $expandButton
 
113
            .on('click.'   +  namespace, module.event.toggleExpand)
 
114
          ;
 
115
          $messageInput
 
116
            .on('keydown.' +  namespace, module.event.input.keydown)
 
117
            .on('keyup.'   +  namespace, module.event.input.keyup)
 
118
          ;
 
119
          $messageButton
 
120
            .on('mouseenter.' +  namespace, module.event.hover)
 
121
            .on('mouseleave.' +  namespace, module.event.hover)
 
122
            .on('click.' +  namespace, module.event.submit)
 
123
          ;
 
124
          // scroll to bottom of chat log
 
125
          $log
 
126
            .animate({
 
127
              scrollTop: $log.prop('scrollHeight')
 
128
            }, 400)
 
129
          ;
 
130
          $module
 
131
            .data('module', module)
 
132
            .addClass(className.loading)
 
133
          ;
 
134
 
 
135
        },
 
136
 
 
137
        // refresh module
 
138
        refresh: function() {
 
139
          // reset width calculations
 
140
          $userListButton
 
141
            .removeClass(className.active)
 
142
          ;
 
143
          module.width = {
 
144
            log      : $log.width(),
 
145
            userList : $userList.outerWidth()
 
146
          };
 
147
          if( $userListButton.hasClass(className.active) ) {
 
148
            module.user.list.hide();
 
149
          }
 
150
          $module.data('module', module);
 
151
        },
 
152
 
 
153
        user: {
 
154
 
 
155
          updateCount: function() {
 
156
            if(settings.userCount) {
 
157
              users = $module.data('users');
 
158
              count = 0;
 
159
              $.each(users, function() {
 
160
                count++;
 
161
              });
 
162
              $userCount
 
163
                .html( settings.templates.userCount(count) )
 
164
              ;
 
165
            }
 
166
          },
 
167
 
 
168
          // add user to user list
 
169
          joined: function(member) {
 
170
            users = $module.data('users');
 
171
            if(member.id != 'anonymous' && users[ member.id ] === undefined ) {
 
172
              users[ member.id ] = member.info;
 
173
              if(settings.randomColor && member.info.color === undefined) {
 
174
                member.info.color = settings.templates.color(member.id);
 
175
              }
 
176
              html = settings.templates.userList(member.info);
 
177
              if(member.info.isAdmin) {
 
178
                $(html)
 
179
                  .prependTo($userList)
 
180
                ;
 
181
              }
 
182
              else {
 
183
                $(html)
 
184
                  .appendTo($userList)
 
185
                ;
 
186
              }
 
187
              if(settings.partingMessages) {
 
188
                $log
 
189
                  .append( settings.templates.joined(member.info) )
 
190
                ;
 
191
                module.message.scroll.test();
 
192
              }
 
193
              module.user.updateCount();
 
194
            }
 
195
          },
 
196
 
 
197
          // remove user from user list
 
198
          left: function(member) {
 
199
            users = $module.data('users');
 
200
            if(member !== undefined && member.id !== 'anonymous') {
 
201
              delete users[ member.id ];
 
202
              $module
 
203
                .data('users', users)
 
204
              ;
 
205
              $userList
 
206
                .find('[data-id='+ member.id + ']')
 
207
                  .remove()
 
208
              ;
 
209
              if(settings.partingMessages) {
 
210
                $log
 
211
                  .append( settings.templates.left(member.info) )
 
212
                ;
 
213
                module.message.scroll.test();
 
214
              }
 
215
              module.user.updateCount();
 
216
            }
 
217
          },
 
218
 
 
219
          list: {
 
220
 
 
221
            // receives list of members and generates user list
 
222
            create: function(members) {
 
223
              users = {};
 
224
              members.each(function(member) {
 
225
                if(member.id !== 'anonymous' && member.id !== 'undefined') {
 
226
                  if(settings.randomColor && member.info.color === undefined) {
 
227
                    member.info.color = settings.templates.color(member.id);
 
228
                  }
 
229
                  // sort list with admin first
 
230
                  html = (member.info.isAdmin)
 
231
                    ? settings.templates.userList(member.info) + html
 
232
                    : html + settings.templates.userList(member.info)
 
233
                  ;
 
234
                  users[ member.id ] = member.info;
 
235
                }
 
236
              });
 
237
              $module
 
238
                .data('users', users)
 
239
                .data('user', users[members.me.id] )
 
240
                .removeClass(className.loading)
 
241
              ;
 
242
              $userList
 
243
                .html(html)
 
244
              ;
 
245
              module.user.updateCount();
 
246
              $.proxy(settings.onJoin, $userList.children())();
 
247
            },
 
248
 
 
249
            // shows user list
 
250
            show: function() {
 
251
              $log
 
252
                .animate({
 
253
                  width: (module.width.log - module.width.userList)
 
254
                }, {
 
255
                  duration : settings.speed,
 
256
                  easing   : settings.easing,
 
257
                  complete : module.message.scroll.move
 
258
                })
 
259
              ;
 
260
            },
 
261
 
 
262
            // hides user list
 
263
            hide: function() {
 
264
              $log
 
265
                .stop()
 
266
                .animate({
 
267
                  width: (module.width.log)
 
268
                }, {
 
269
                  duration : settings.speed,
 
270
                  easing   : settings.easing,
 
271
                  complete : module.message.scroll.move
 
272
                })
 
273
              ;
 
274
            }
 
275
 
 
276
          }
 
277
 
 
278
        },
 
279
 
 
280
        message: {
 
281
 
 
282
          // handles scrolling of chat log
 
283
          scroll: {
 
284
            test: function() {
 
285
              height = $log.prop('scrollHeight') - $log.height();
 
286
              if( Math.abs($log.scrollTop() - height) < settings.scrollArea) {
 
287
                module.message.scroll.move();
 
288
              }
 
289
            },
 
290
 
 
291
            move: function() {
 
292
              height = $log.prop('scrollHeight') - $log.height();
 
293
              $log
 
294
                .scrollTop(height)
 
295
              ;
 
296
            }
 
297
          },
 
298
 
 
299
          // sends chat message
 
300
          send: function(message) {
 
301
            if( !module.utils.emptyString(message) ) {
 
302
              $.api({
 
303
                url    : settings.endpoint.message,
 
304
                method : 'POST',
 
305
                data   : {
 
306
                  'message': {
 
307
                    content   : message,
 
308
                    timestamp : new Date().getTime()
 
309
                  }
 
310
                }
 
311
              });
 
312
            }
 
313
          },
 
314
 
 
315
          // receives chat response and processes
 
316
          receive: function(response) {
 
317
            message      = response.data;
 
318
            users        = $module.data('users');
 
319
            loggedInUser = $module.data('user');
 
320
            if(users[ message.userID] !== undefined) {
 
321
              // logged in user's messages already pushed instantly
 
322
              if(loggedInUser === undefined || loggedInUser.id != message.userID) {
 
323
                message.user = users[ message.userID ];
 
324
                module.message.display(message);
 
325
              }
 
326
            }
 
327
          },
 
328
 
 
329
          // displays message in chat log
 
330
          display: function(message) {
 
331
            $log
 
332
              .append( settings.templates.message(message) )
 
333
            ;
 
334
            module.message.scroll.test();
 
335
            $.proxy(settings.onMessage, $log.children().last() )();
 
336
          }
 
337
 
 
338
        },
 
339
 
 
340
        expand: function() {
 
341
          $module
 
342
            .addClass(className.expand)
 
343
          ;
 
344
          $.proxy(settings.onExpand, $module )();
 
345
          module.refresh();
 
346
        },
 
347
 
 
348
        contract: function() {
 
349
          $module
 
350
            .removeClass(className.expand)
 
351
          ;
 
352
          $.proxy(settings.onContract, $module )();
 
353
          module.refresh();
 
354
        },
 
355
 
 
356
        event: {
 
357
 
 
358
          input: {
 
359
 
 
360
            keydown: function(event) {
 
361
              if(event.which == 13) {
 
362
                $messageButton
 
363
                  .addClass(className.down)
 
364
                ;
 
365
              }
 
366
            },
 
367
 
 
368
            keyup: function(event) {
 
369
              if(event.which == 13) {
 
370
                $messageButton
 
371
                  .removeClass(className.down)
 
372
                ;
 
373
                module.event.submit();
 
374
              }
 
375
            }
 
376
 
 
377
          },
 
378
 
 
379
          // handles message form submit
 
380
          submit: function() {
 
381
            var
 
382
              message      = $messageInput.val(),
 
383
              loggedInUser = $module.data('user')
 
384
            ;
 
385
            if(loggedInUser !== undefined && !module.utils.emptyString(message)) {
 
386
              module.message.send(message);
 
387
              // display immediately
 
388
              module.message.display({
 
389
                user: loggedInUser,
 
390
                text: message
 
391
              });
 
392
              module.message.scroll.move();
 
393
              $messageInput
 
394
                .val('')
 
395
              ;
 
396
 
 
397
            }
 
398
          },
 
399
 
 
400
          // handles button click on expand button
 
401
          toggleExpand: function() {
 
402
            if( !$module.hasClass(className.expand) ) {
 
403
              $expandButton
 
404
                .addClass(className.active)
 
405
              ;
 
406
              module.expand();
 
407
            }
 
408
            else {
 
409
              $expandButton
 
410
                .removeClass(className.active)
 
411
              ;
 
412
              module.contract();
 
413
            }
 
414
          },
 
415
 
 
416
          // handles button click on user list button
 
417
          toggleUserList: function() {
 
418
            if( !$log.is(':animated') ) {
 
419
              if( !$userListButton.hasClass(className.active) ) {
 
420
                $userListButton
 
421
                  .addClass(className.active)
 
422
                ;
 
423
                module.user.list.show();
 
424
              }
 
425
              else {
 
426
                $userListButton
 
427
                  .removeClass('active')
 
428
                ;
 
429
                module.user.list.hide();
 
430
              }
 
431
            }
 
432
 
 
433
          }
 
434
        },
 
435
 
 
436
        utils: {
 
437
 
 
438
          emptyString: function(string) {
 
439
            if(typeof string == 'string') {
 
440
              return (string.search(/\S/) == -1);
 
441
            }
 
442
            return false;
 
443
          }
 
444
 
 
445
        },
 
446
 
 
447
      setting: function(name, value) {
 
448
        if(value !== undefined) {
 
449
          if( $.isPlainObject(name) ) {
 
450
            $.extend(true, settings, name);
 
451
          }
 
452
          else {
 
453
            settings[name] = value;
 
454
          }
 
455
        }
 
456
        else {
 
457
          return settings[name];
 
458
        }
 
459
      },
 
460
      internal: function(name, value) {
 
461
        if( $.isPlainObject(name) ) {
 
462
          $.extend(true, module, name);
 
463
        }
 
464
        else if(value !== undefined) {
 
465
          module[name] = value;
 
466
        }
 
467
        else {
 
468
          return module[name];
 
469
        }
 
470
      },
 
471
      debug: function() {
 
472
        if(settings.debug) {
 
473
          if(settings.performance) {
 
474
            module.performance.log(arguments);
 
475
          }
 
476
          else {
 
477
            module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
 
478
            module.debug.apply(console, arguments);
 
479
          }
 
480
        }
 
481
      },
 
482
      verbose: function() {
 
483
        if(settings.verbose && settings.debug) {
 
484
          if(settings.performance) {
 
485
            module.performance.log(arguments);
 
486
          }
 
487
          else {
 
488
            module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
 
489
            module.verbose.apply(console, arguments);
 
490
          }
 
491
        }
 
492
      },
 
493
      error: function() {
 
494
        module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
 
495
        module.error.apply(console, arguments);
 
496
      },
 
497
      performance: {
 
498
        log: function(message) {
 
499
          var
 
500
            currentTime,
 
501
            executionTime,
 
502
            previousTime
 
503
          ;
 
504
          if(settings.performance) {
 
505
            currentTime   = new Date().getTime();
 
506
            previousTime  = time || currentTime;
 
507
            executionTime = currentTime - previousTime;
 
508
            time          = currentTime;
 
509
            performance.push({
 
510
              'Element'        : element,
 
511
              'Name'           : message[0],
 
512
              'Arguments'      : [].slice.call(message, 1) || '',
 
513
              'Execution Time' : executionTime
 
514
            });
 
515
          }
 
516
          clearTimeout(module.performance.timer);
 
517
          module.performance.timer = setTimeout(module.performance.display, 100);
 
518
        },
 
519
        display: function() {
 
520
          var
 
521
            title = settings.name + ':',
 
522
            totalTime = 0
 
523
          ;
 
524
          time = false;
 
525
          clearTimeout(module.performance.timer);
 
526
          $.each(performance, function(index, data) {
 
527
            totalTime += data['Execution Time'];
 
528
          });
 
529
          title += ' ' + totalTime + 'ms';
 
530
          if(moduleSelector) {
 
531
            title += ' \'' + moduleSelector + '\'';
 
532
          }
 
533
          if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
 
534
            console.groupCollapsed(title);
 
535
            if(console.table) {
 
536
              console.table(performance);
 
537
            }
 
538
            else {
 
539
              $.each(performance, function(index, data) {
 
540
                console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
 
541
              });
 
542
            }
 
543
            console.groupEnd();
 
544
          }
 
545
          performance = [];
 
546
        }
 
547
      },
 
548
      invoke: function(query, passedArguments, context) {
 
549
        var
 
550
          maxDepth,
 
551
          found
 
552
        ;
 
553
        passedArguments = passedArguments || queryArguments;
 
554
        context         = element         || context;
 
555
        if(typeof query == 'string' && instance !== undefined) {
 
556
          query    = query.split(/[\. ]/);
 
557
          maxDepth = query.length - 1;
 
558
          $.each(query, function(depth, value) {
 
559
            if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
 
560
              instance = instance[value];
 
561
            }
 
562
            else if( instance[value] !== undefined ) {
 
563
              found = instance[value];
 
564
            }
 
565
            else {
 
566
              module.error(error.method, query);
 
567
            }
 
568
          });
 
569
        }
 
570
        if ( $.isFunction( found ) ) {
 
571
          return found.apply(context, passedArguments);
 
572
        }
 
573
        return found || false;
 
574
      }
 
575
    };
 
576
 
 
577
    if(methodInvoked) {
 
578
      if(instance === undefined) {
 
579
        module.initialize();
 
580
      }
 
581
      module.invoke(query);
 
582
    }
 
583
    else {
 
584
      if(instance !== undefined) {
 
585
        module.destroy();
 
586
      }
 
587
      module.initialize();
 
588
    }
 
589
  })
 
590
;
 
591
  return (returnedValue !== undefined)
 
592
    ? returnedValue
 
593
    : this
 
594
  ;
 
595
};
 
596
 
 
597
  $.fn.chatroom.settings = {
 
598
 
 
599
    name            : 'Chat',
 
600
    debug           : false,
 
601
    namespace       : 'chat',
 
602
 
 
603
    channel         : 'present-chat',
 
604
 
 
605
    onJoin          : function(){},
 
606
    onMessage       : function(){},
 
607
    onExpand        : function(){},
 
608
    onContract      : function(){},
 
609
 
 
610
    customEvents    : {},
 
611
 
 
612
    partingMessages : false,
 
613
    userCount       : true,
 
614
    randomColor     : true,
 
615
 
 
616
    speed           : 300,
 
617
    easing          : 'easeOutQuint',
 
618
 
 
619
    // pixels from bottom of chat log that should trigger auto scroll to bottom
 
620
    scrollArea      : 9999,
 
621
 
 
622
    endpoint        : {
 
623
      message        : false,
 
624
      authentication : false
 
625
    },
 
626
 
 
627
    error: {
 
628
      method   : 'The method you called is not defined',
 
629
      endpoint : 'Please define a message and authentication endpoint.',
 
630
      key      : 'You must specify a pusher key and channel.',
 
631
      pusher   : 'You must include the Pusher library.'
 
632
    },
 
633
 
 
634
    className   : {
 
635
      expand  : 'expand',
 
636
      active  : 'active',
 
637
      hover   : 'hover',
 
638
      down    : 'down',
 
639
      loading : 'loading'
 
640
    },
 
641
 
 
642
    selector    : {
 
643
      userCount      : '.actions .message',
 
644
      userListButton : '.actions .list.button',
 
645
      expandButton   : '.actions .expand.button',
 
646
      room           : '.room',
 
647
      userList       : '.room .list',
 
648
      log            : '.room .log',
 
649
      message        : '.room .log .message',
 
650
      author         : '.room log .message .author',
 
651
      messageInput   : '.talk input',
 
652
      messageButton  : '.talk .send.button'
 
653
    },
 
654
 
 
655
    templates: {
 
656
 
 
657
      userCount: function(number) {
 
658
        return number + ' users in chat';
 
659
      },
 
660
 
 
661
      color: function(userID) {
 
662
        var
 
663
          colors = [
 
664
            '#000000',
 
665
            '#333333',
 
666
            '#666666',
 
667
            '#999999',
 
668
            '#CC9999',
 
669
            '#CC6666',
 
670
            '#CC3333',
 
671
            '#993333',
 
672
            '#663333',
 
673
            '#CC6633',
 
674
            '#CC9966',
 
675
            '#CC9933',
 
676
            '#999966',
 
677
            '#CCCC66',
 
678
            '#99CC66',
 
679
            '#669933',
 
680
            '#669966',
 
681
            '#33A3CC',
 
682
            '#336633',
 
683
            '#33CCCC',
 
684
            '#339999',
 
685
            '#336666',
 
686
            '#336699',
 
687
            '#6666CC',
 
688
            '#9966CC',
 
689
            '#333399',
 
690
            '#663366',
 
691
            '#996699',
 
692
            '#993366',
 
693
            '#CC6699'
 
694
          ]
 
695
        ;
 
696
        return colors[ Math.floor( Math.random() * colors.length) ];
 
697
      },
 
698
 
 
699
      message: function(message) {
 
700
        var
 
701
          html = ''
 
702
        ;
 
703
        if(message.user.isAdmin) {
 
704
          message.user.color = '#55356A';
 
705
          html += '<div class="admin message">';
 
706
          html += '<span class="quirky ui flag team"></span>';
 
707
        }
 
708
        /*
 
709
        else if(message.user.isPro) {
 
710
          html += '<div class="indent message">';
 
711
          html += '<span class="quirky ui flag pro"></span>';
 
712
        }
 
713
        */
 
714
        else {
 
715
          html += '<div class="message">';
 
716
        }
 
717
        html += '<p>';
 
718
        if(message.user.color !== undefined) {
 
719
          html += '<span class="author" style="color: ' + message.user.color + ';">' + message.user.name + '</span>: ';
 
720
        }
 
721
        else {
 
722
          html += '<span class="author">' + message.user.name + '</span>: ';
 
723
        }
 
724
        html += ''
 
725
          +   message.text
 
726
          + ' </p>'
 
727
          + '</div>'
 
728
        ;
 
729
        return html;
 
730
      },
 
731
 
 
732
      joined: function(member) {
 
733
        return (typeof member.name !== undefined)
 
734
          ? '<div class="status">' + member.name + ' has joined the chat.</div>'
 
735
          : false
 
736
        ;
 
737
      },
 
738
      left: function(member) {
 
739
        return (typeof member.name !== undefined)
 
740
          ? '<div class="status">' + member.name + ' has left the chat.</div>'
 
741
          : false
 
742
        ;
 
743
      },
 
744
 
 
745
      userList: function(member) {
 
746
        var
 
747
          html = ''
 
748
        ;
 
749
        if(member.isAdmin) {
 
750
          member.color = '#55356A';
 
751
        }
 
752
        html +=  ''
 
753
          + '<div class="user" data-id="' + member.id + '">'
 
754
          + ' <div class="image">'
 
755
          + '   <img src="' + member.avatarURL + '">'
 
756
          + ' </div>'
 
757
        ;
 
758
        if(member.color !== undefined) {
 
759
          html += ' <p><a href="/users/' + member.id + '" target="_blank" style="color: ' + member.color + ';">' + member.name + '</a></p>';
 
760
        }
 
761
        else {
 
762
          html += ' <p><a href="/users/' + member.id + '" target="_blank">' + member.name + '</a></p>';
 
763
        }
 
764
        html += '</div>';
 
765
        return html;
 
766
      }
 
767
 
 
768
    }
 
769
 
 
770
  };
 
771
 
 
772
})( jQuery, window , document );