Skip to content
Browse files

Merge branch 'master' of https://github.com/SOF-TEAM/web-demo

  • Loading branch information...
2 parents d61dbfd + 71d3688 commit ae0c64f593c03ef44620f2181fbb260e6209d6f5 @jsebasct jsebasct committed Apr 14, 2013
Showing with 19,581 additions and 0 deletions.
  1. +44 −0 webapp3/assets/7c286c99/detailview/styles.css
  2. BIN webapp3/assets/7c286c99/gridview/bg.gif
  3. BIN webapp3/assets/7c286c99/gridview/delete.png
  4. BIN webapp3/assets/7c286c99/gridview/down.gif
  5. +457 −0 webapp3/assets/7c286c99/gridview/jquery.yiigridview.js
  6. BIN webapp3/assets/7c286c99/gridview/loading.gif
  7. +125 −0 webapp3/assets/7c286c99/gridview/styles.css
  8. BIN webapp3/assets/7c286c99/gridview/up.gif
  9. BIN webapp3/assets/7c286c99/gridview/update.png
  10. BIN webapp3/assets/7c286c99/gridview/view.png
  11. BIN webapp3/assets/7c286c99/listview/down.gif
  12. +169 −0 webapp3/assets/7c286c99/listview/jquery.yiilistview.js
  13. BIN webapp3/assets/7c286c99/listview/loading.gif
  14. +56 −0 webapp3/assets/7c286c99/listview/styles.css
  15. BIN webapp3/assets/7c286c99/listview/up.gif
  16. BIN webapp3/assets/ee277cf4/autocomplete/indicator.gif
  17. +48 −0 webapp3/assets/ee277cf4/autocomplete/jquery.autocomplete.css
  18. +116 −0 webapp3/assets/ee277cf4/jquery.ajaxqueue.js
  19. +813 −0 webapp3/assets/ee277cf4/jquery.autocomplete.js
  20. +1,137 −0 webapp3/assets/ee277cf4/jquery.ba-bbq.js
  21. +18 −0 webapp3/assets/ee277cf4/jquery.ba-bbq.min.js
  22. +39 −0 webapp3/assets/ee277cf4/jquery.bgiframe.js
  23. +92 −0 webapp3/assets/ee277cf4/jquery.cookie.js
  24. +1 −0 webapp3/assets/ee277cf4/jquery.history.js
  25. +9,472 −0 webapp3/assets/ee277cf4/jquery.js
  26. +258 −0 webapp3/assets/ee277cf4/jquery.maskedinput.js
  27. +7 −0 webapp3/assets/ee277cf4/jquery.maskedinput.min.js
  28. +148 −0 webapp3/assets/ee277cf4/jquery.metadata.js
  29. +2 −0 webapp3/assets/ee277cf4/jquery.min.js
  30. +536 −0 webapp3/assets/ee277cf4/jquery.multifile.js
  31. +392 −0 webapp3/assets/ee277cf4/jquery.rating.js
  32. +110 −0 webapp3/assets/ee277cf4/jquery.treeview.async.js
  33. +37 −0 webapp3/assets/ee277cf4/jquery.treeview.edit.js
  34. +256 −0 webapp3/assets/ee277cf4/jquery.treeview.js
  35. +52 −0 webapp3/assets/ee277cf4/jquery.yii.js
  36. +426 −0 webapp3/assets/ee277cf4/jquery.yiiactiveform.js
  37. +49 −0 webapp3/assets/ee277cf4/jquery.yiitab.js
  38. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-bg_flat_0_aaaaaa_40x100.png
  39. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-bg_flat_75_ffffff_40x100.png
  40. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-bg_glass_55_fbf9ee_1x400.png
  41. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-bg_glass_65_ffffff_1x400.png
  42. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-bg_glass_75_dadada_1x400.png
  43. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-bg_glass_75_e6e6e6_1x400.png
  44. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-bg_glass_95_fef1ec_1x400.png
  45. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png
  46. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-icons_222222_256x240.png
  47. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-icons_2e83ff_256x240.png
  48. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-icons_454545_256x240.png
  49. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-icons_888888_256x240.png
  50. BIN webapp3/assets/ee277cf4/jui/css/base/images/ui-icons_cd0a0a_256x240.png
  51. +10 −0 webapp3/assets/ee277cf4/jui/css/base/jquery-ui.css
  52. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.accordion.css
  53. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.autocomplete.css
  54. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.button.css
  55. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.core.css
  56. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.datepicker.css
  57. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.dialog.css
  58. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.menu.css
  59. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.progressbar.css
  60. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.resizable.css
  61. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.selectable.css
  62. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.slider.css
  63. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.spinner.css
  64. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.tabs.css
  65. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.theme.css
  66. +5 −0 webapp3/assets/ee277cf4/jui/css/base/jquery.ui.tooltip.css
  67. +5 −0 webapp3/assets/ee277cf4/jui/js/jquery-ui-i18n.min.js
  68. +6 −0 webapp3/assets/ee277cf4/jui/js/jquery-ui.min.js
  69. +510 −0 webapp3/assets/ee277cf4/punycode.js
  70. +2 −0 webapp3/assets/ee277cf4/punycode.min.js
  71. BIN webapp3/assets/ee277cf4/rating/delete.gif
  72. +12 −0 webapp3/assets/ee277cf4/rating/jquery.rating.css
  73. BIN webapp3/assets/ee277cf4/rating/star.gif
  74. BIN webapp3/assets/ee277cf4/treeview/images/ajax-loader.gif
  75. BIN webapp3/assets/ee277cf4/treeview/images/file.gif
  76. BIN webapp3/assets/ee277cf4/treeview/images/folder-closed.gif
  77. BIN webapp3/assets/ee277cf4/treeview/images/folder.gif
  78. BIN webapp3/assets/ee277cf4/treeview/images/minus.gif
  79. BIN webapp3/assets/ee277cf4/treeview/images/plus.gif
  80. BIN webapp3/assets/ee277cf4/treeview/images/treeview-black-line.gif
  81. BIN webapp3/assets/ee277cf4/treeview/images/treeview-black.gif
  82. BIN webapp3/assets/ee277cf4/treeview/images/treeview-default-line.gif
  83. BIN webapp3/assets/ee277cf4/treeview/images/treeview-default.gif
  84. BIN webapp3/assets/ee277cf4/treeview/images/treeview-famfamfam-line.gif
  85. BIN webapp3/assets/ee277cf4/treeview/images/treeview-famfamfam.gif
  86. BIN webapp3/assets/ee277cf4/treeview/images/treeview-gray-line.gif
  87. BIN webapp3/assets/ee277cf4/treeview/images/treeview-gray.gif
  88. BIN webapp3/assets/ee277cf4/treeview/images/treeview-red-line.gif
  89. BIN webapp3/assets/ee277cf4/treeview/images/treeview-red.gif
  90. +74 −0 webapp3/assets/ee277cf4/treeview/jquery.treeview.css
  91. +58 −0 webapp3/assets/ee277cf4/yiitab/jquery.yiitab.css
  92. +35 −0 webapp3/assets/f0451159/css/ie.css
  93. +528 −0 webapp3/assets/f0451159/css/main.css
  94. +29 −0 webapp3/assets/f0451159/css/print.css
  95. +235 −0 webapp3/assets/f0451159/css/screen.css
  96. BIN webapp3/assets/f0451159/images/logo.png
  97. BIN webapp3/assets/f0451159/js/fancybox/blank.gif
  98. BIN webapp3/assets/f0451159/js/fancybox/fancy_close.png
  99. BIN webapp3/assets/f0451159/js/fancybox/fancy_loading.png
  100. BIN webapp3/assets/f0451159/js/fancybox/fancy_nav_left.png
  101. BIN webapp3/assets/f0451159/js/fancybox/fancy_nav_right.png
  102. BIN webapp3/assets/f0451159/js/fancybox/fancy_shadow_e.png
  103. BIN webapp3/assets/f0451159/js/fancybox/fancy_shadow_n.png
  104. BIN webapp3/assets/f0451159/js/fancybox/fancy_shadow_ne.png
  105. BIN webapp3/assets/f0451159/js/fancybox/fancy_shadow_nw.png
  106. BIN webapp3/assets/f0451159/js/fancybox/fancy_shadow_s.png
  107. BIN webapp3/assets/f0451159/js/fancybox/fancy_shadow_se.png
  108. BIN webapp3/assets/f0451159/js/fancybox/fancy_shadow_sw.png
  109. BIN webapp3/assets/f0451159/js/fancybox/fancy_shadow_w.png
  110. BIN webapp3/assets/f0451159/js/fancybox/fancy_title_left.png
  111. BIN webapp3/assets/f0451159/js/fancybox/fancy_title_main.png
  112. BIN webapp3/assets/f0451159/js/fancybox/fancy_title_over.png
  113. BIN webapp3/assets/f0451159/js/fancybox/fancy_title_right.png
  114. BIN webapp3/assets/f0451159/js/fancybox/fancybox-x.png
  115. BIN webapp3/assets/f0451159/js/fancybox/fancybox-y.png
  116. BIN webapp3/assets/f0451159/js/fancybox/fancybox.png
  117. +363 −0 webapp3/assets/f0451159/js/fancybox/jquery.fancybox-1.3.1.css
  118. +44 −0 webapp3/assets/f0451159/js/fancybox/jquery.fancybox-1.3.1.pack.js
  119. +11 −0 webapp3/assets/f0451159/js/jquery.tooltip-1.2.6.min.js
  120. +79 −0 webapp3/assets/f0451159/js/main.js
  121. +66 −0 webapp3/assets/f311f752/pager.css
  122. BIN webapp3/css/bg.gif
  123. +164 −0 webapp3/css/form.css
  124. +36 −0 webapp3/css/ie.css
  125. +229 −0 webapp3/css/main.css
  126. +29 −0 webapp3/css/print.css
  127. +238 −0 webapp3/css/screen.css
  128. +15 −0 webapp3/index-test.php
  129. +13 −0 webapp3/index.php
  130. +1 −0 webapp3/protected/.htaccess
  131. +23 −0 webapp3/protected/components/Controller.php
  132. +33 −0 webapp3/protected/components/UserIdentity.php
  133. +37 −0 webapp3/protected/config/console.php
  134. +90 −0 webapp3/protected/config/main.php
  135. +17 −0 webapp3/protected/config/test.php
  136. +42 −0 webapp3/protected/controllers/MessageController.php
  137. +173 −0 webapp3/protected/controllers/PolerasController.php
  138. +109 −0 webapp3/protected/controllers/SiteController.php
  139. +38 −0 webapp3/protected/controllers/VentaController.php
  140. +28 −0 webapp3/protected/data/schema.mysql.sql
  141. +28 −0 webapp3/protected/data/schema.sqlite.sql
  142. BIN webapp3/protected/data/testdrive.db
  143. +61 −0 webapp3/protected/extensions/AutoComplete.php
  144. +42 −0 webapp3/protected/models/ContactForm.php
  145. +77 −0 webapp3/protected/models/LoginForm.php
  146. +115 −0 webapp3/protected/models/Poleras.php
  147. +28 −0 webapp3/protected/modules/help/HelpModule.php
  148. +9 −0 webapp3/protected/modules/help/controllers/DefaultController.php
  149. +14 −0 webapp3/protected/modules/help/views/default/index.php
  150. +215 −0 webapp3/protected/runtime/application.log
  151. +5 −0 webapp3/protected/runtime/gii-1.1.13/CrudCode.php
  152. +9 −0 webapp3/protected/runtime/gii-1.1.13/ModelCode.php
  153. +25 −0 webapp3/protected/tests/WebTestCase.php
  154. +10 −0 webapp3/protected/tests/bootstrap.php
  155. +47 −0 webapp3/protected/tests/functional/SiteTest.php
  156. +13 −0 webapp3/protected/tests/phpunit.xml
  157. +6 −0 webapp3/protected/views/layouts/column1.php
  158. +22 −0 webapp3/protected/views/layouts/column2.php
  159. +60 −0 webapp3/protected/views/layouts/main.php
  160. +8 −0 webapp3/protected/views/message/helloWorld.php
  161. +9 −0 webapp3/protected/views/message/index.php
  162. +42 −0 webapp3/protected/views/poleras/_form.php
  163. +35 −0 webapp3/protected/views/poleras/_search.php
  164. +21 −0 webapp3/protected/views/poleras/_view.php
  165. +55 −0 webapp3/protected/views/poleras/admin.php
  166. +18 −0 webapp3/protected/views/poleras/create.php
  167. +20 −0 webapp3/protected/views/poleras/index.php
  168. +21 −0 webapp3/protected/views/poleras/update.php
  169. +28 −0 webapp3/protected/views/poleras/view.php
  170. +85 −0 webapp3/protected/views/site/contact.php
  171. +15 −0 webapp3/protected/views/site/error.php
  172. +20 −0 webapp3/protected/views/site/index.php
  173. +53 −0 webapp3/protected/views/site/login.php
  174. +12 −0 webapp3/protected/views/site/pages/about.php
  175. +1 −0 webapp3/protected/views/site/pages/venta.php
  176. +7 −0 webapp3/protected/views/venta/index.php
  177. +4 −0 webapp3/protected/yiic
  178. +16 −0 webapp3/protected/yiic.bat
  179. +7 −0 webapp3/protected/yiic.php
  180. +1 −0 webapp3/themes/classic/views/.htaccess
View
44 webapp3/assets/7c286c99/detailview/styles.css
@@ -0,0 +1,44 @@
+table.detail-view .null
+{
+ color: pink;
+}
+
+table.detail-view
+{
+ background: white;
+ border-collapse: collapse;
+ width: 100%;
+ margin: 0;
+}
+
+table.detail-view th, table.detail-view td
+{
+ font-size: 0.9em;
+ border: 1px white solid;
+ padding: 0.3em 0.6em;
+ vertical-align: top;
+}
+
+table.detail-view th
+{
+ text-align: right;
+ width: 160px;
+}
+
+table.detail-view tr.odd
+{
+ background:#E5F1F4;
+}
+
+table.detail-view tr.even
+{
+ background:#F8F8F8;
+}
+
+table.detail-view tr.odd th
+{
+}
+
+table.detail-view tr.even th
+{
+}
View
BIN webapp3/assets/7c286c99/gridview/bg.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN webapp3/assets/7c286c99/gridview/delete.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN webapp3/assets/7c286c99/gridview/down.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
457 webapp3/assets/7c286c99/gridview/jquery.yiigridview.js
@@ -0,0 +1,457 @@
+/**
+ * jQuery Yii GridView plugin file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2010 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+(function ($) {
+ var selectCheckedRows, methods,
+ gridSettings = [];
+ /**
+ * 1. Selects rows that have checkbox checked (only checkbox that is connected with selecting a row)
+ * 2. Check if "check all" need to be checked/unchecked
+ * @return object the jQuery object
+ */
+ selectCheckedRows = function (gridId) {
+ var settings = gridSettings[gridId],
+ table = $('#' + gridId).children('.' + settings.tableClass);
+
+ table.children('tbody').find('input.select-on-check').filter(':checked').each(function () {
+ $(this).closest('tr').addClass('selected');
+ });
+
+ table.children('thead').find('th input').filter('[type="checkbox"]').each(function () {
+ var name = this.name.substring(0, this.name.length - 4) + '[]', //.. remove '_all' and add '[]''
+ $checks = $("input[name='" + name + "']", table);
+ this.checked = $checks.length > 0 && $checks.length === $checks.filter(':checked').length;
+ });
+ return this;
+ };
+
+ methods = {
+ /**
+ * yiiGridView set function.
+ * @param options map settings for the grid view. Available options are as follows:
+ * - ajaxUpdate: array, IDs of the containers whose content may be updated by ajax response
+ * - ajaxVar: string, the name of the GET variable indicating the ID of the element triggering the AJAX request
+ * - pagerClass: string, the CSS class for the pager container
+ * - tableClass: string, the CSS class for the table
+ * - selectableRows: integer, the number of rows that can be selected
+ * - updateSelector: string, the selector for choosing which elements can trigger ajax requests
+ * - beforeAjaxUpdate: function, the function to be called before ajax request is sent
+ * - afterAjaxUpdate: function, the function to be called after ajax response is received
+ * - ajaxUpdateError: function, the function to be called if an ajax error occurs
+ * - selectionChanged: function, the function to be called after the row selection is changed
+ * @return object the jQuery object
+ */
+ init: function (options) {
+ var settings = $.extend({
+ ajaxUpdate: [],
+ ajaxVar: 'ajax',
+ pagerClass: 'pager',
+ loadingClass: 'loading',
+ filterClass: 'filters',
+ tableClass: 'items',
+ selectableRows: 1
+ // updateSelector: '#id .pager a, '#id .grid thead th a',
+ // beforeAjaxUpdate: function (id) {},
+ // afterAjaxUpdate: function (id, data) {},
+ // selectionChanged: function (id) {},
+ // url: 'ajax request URL'
+ }, options || {});
+
+ settings.tableClass = settings.tableClass.replace(/\s+/g, '.');
+
+ return this.each(function () {
+ var eventType,
+ $grid = $(this),
+ id = $grid.attr('id'),
+ pagerSelector = '#' + id + ' .' + settings.pagerClass.replace(/\s+/g, '.') + ' a',
+ sortSelector = '#' + id + ' .' + settings.tableClass + ' thead th a.sort-link',
+ inputSelector = '#' + id + ' .' + settings.filterClass + ' input, ' + '#' + id + ' .' + settings.filterClass + ' select';
+
+ settings.updateSelector = settings.updateSelector
+ .replace('{page}', pagerSelector)
+ .replace('{sort}', sortSelector);
+ settings.filterSelector = settings.filterSelector
+ .replace('{filter}', inputSelector);
+
+ gridSettings[id] = settings;
+
+ if (settings.ajaxUpdate.length > 0) {
+ $(document).on('click.yiiGridView', settings.updateSelector, function () {
+ // Check to see if History.js is enabled for our Browser
+ if (settings.enableHistory && window.History.enabled) {
+ // Ajaxify this link
+ var url = $(this).attr('href').split('?'),
+ params = $.deparam.querystring('?'+url[1]);
+
+ delete params[settings.ajaxVar];
+ window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url[0], params)));
+ } else {
+ $('#' + id).yiiGridView('update', {url: $(this).attr('href')});
+ }
+ return false;
+ });
+ }
+
+ $(document).on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) {
+ if (event.type === 'keydown') {
+ if( event.keyCode !== 13) {
+ return; // only react to enter key
+ } else {
+ eventType = 'keydown';
+ }
+ } else {
+ // prevent processing for both keydown and change events
+ if (eventType === 'keydown') {
+ eventType = '';
+ return;
+ }
+ }
+ var data = $(settings.filterSelector).serialize();
+ if (settings.pageVar !== undefined) {
+ data += '&' + settings.pageVar + '=1';
+ }
+ if (settings.enableHistory && settings.ajaxUpdate !== false && window.History.enabled) {
+ // Ajaxify this link
+ var url = $('#' + id).yiiGridView('getUrl'),
+ params = $.deparam.querystring($.param.querystring(url, data));
+
+ delete params[settings.ajaxVar];
+ window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url.substr(0, url.indexOf('?')), params)));
+ } else {
+ $('#' + id).yiiGridView('update', {data: data});
+ }
+ });
+
+ if (settings.enableHistory && settings.ajaxUpdate !== false && window.History.enabled) {
+ $(window).bind('statechange', function() { // Note: We are using statechange instead of popstate
+ var State = window.History.getState(); // Note: We are using History.getState() instead of event.state
+ $('#' + id).yiiGridView('update', {url: State.url});
+ });
+ }
+
+ if (settings.selectableRows > 0) {
+ selectCheckedRows(this.id);
+ $(document).on('click.yiiGridView', '#' + id + ' .' + settings.tableClass + ' > tbody > tr', function (e) {
+ var $currentGrid, $row, isRowSelected, $checks,
+ $target = $(e.target);
+
+ if ($target.closest('td').is('.empty,.button-column') || (e.target.type === 'checkbox' && !$target.hasClass('select-on-check'))) {
+ return;
+ }
+
+ $row = $(this);
+ $currentGrid = $('#' + id);
+ $checks = $('input.select-on-check', $currentGrid);
+ isRowSelected = $row.toggleClass('selected').hasClass('selected');
+
+ if (settings.selectableRows === 1) {
+ $row.siblings().removeClass('selected');
+ $checks.prop('checked', false);
+ }
+ $('input.select-on-check', $row).prop('checked', isRowSelected);
+ $("input.select-on-check-all", $currentGrid).prop('checked', $checks.length === $checks.filter(':checked').length);
+
+ if (settings.selectionChanged !== undefined) {
+ settings.selectionChanged(id);
+ }
+ });
+ if (settings.selectableRows > 1) {
+ $(document).on('click.yiiGridView', '#' + id + ' .select-on-check-all', function () {
+ var $currentGrid = $('#' + id),
+ $checks = $('input.select-on-check', $currentGrid),
+ $checksAll = $('input.select-on-check-all', $currentGrid),
+ $rows = $currentGrid.children('.' + settings.tableClass).children('tbody').children();
+ if (this.checked) {
+ $rows.addClass('selected');
+ $checks.prop('checked', true);
+ $checksAll.prop('checked', true);
+ } else {
+ $rows.removeClass('selected');
+ $checks.prop('checked', false);
+ $checksAll.prop('checked', false);
+ }
+ if (settings.selectionChanged !== undefined) {
+ settings.selectionChanged(id);
+ }
+ });
+ }
+ } else {
+ $(document).on('click.yiiGridView', '#' + id + ' .select-on-check', false);
+ }
+ });
+ },
+
+ /**
+ * Returns the key value for the specified row
+ * @param row integer the row number (zero-based index)
+ * @return string the key value
+ */
+ getKey: function (row) {
+ return this.children('.keys').children('span').eq(row).text();
+ },
+
+ /**
+ * Returns the URL that generates the grid view content.
+ * @return string the URL that generates the grid view content.
+ */
+ getUrl: function () {
+ var sUrl = gridSettings[this.attr('id')].url;
+ return sUrl || this.children('.keys').attr('title');
+ },
+
+ /**
+ * Returns the jQuery collection of the cells in the specified row.
+ * @param row integer the row number (zero-based index)
+ * @return jQuery the jQuery collection of the cells in the specified row.
+ */
+ getRow: function (row) {
+ var sClass = gridSettings[this.attr('id')].tableClass;
+ return this.children('.' + sClass).children('tbody').children('tr').eq(row).children();
+ },
+
+ /**
+ * Returns the jQuery collection of the cells in the specified column.
+ * @param column integer the column number (zero-based index)
+ * @return jQuery the jQuery collection of the cells in the specified column.
+ */
+ getColumn: function (column) {
+ var sClass = gridSettings[this.attr('id')].tableClass;
+ return this.children('.' + sClass).children('tbody').children('tr').children('td:nth-child(' + (column + 1) + ')');
+ },
+
+ /**
+ * Performs an AJAX-based update of the grid view contents.
+ * @param options map the AJAX request options (see jQuery.ajax API manual). By default,
+ * the URL to be requested is the one that generates the current content of the grid view.
+ * @return object the jQuery object
+ */
+ update: function (options) {
+ var customError;
+ if (options && options.error !== undefined) {
+ customError = options.error;
+ delete options.error;
+ }
+
+ return this.each(function () {
+ var $form,
+ $grid = $(this),
+ id = $grid.attr('id'),
+ settings = gridSettings[id];
+ $grid.addClass(settings.loadingClass);
+
+ options = $.extend({
+ type: 'GET',
+ url: $grid.yiiGridView('getUrl'),
+ success: function (data) {
+ var $data = $('<div>' + data + '</div>');
+ $grid.removeClass(settings.loadingClass);
+ $.each(settings.ajaxUpdate, function (i, el) {
+ var updateId = '#' + el;
+ $(updateId).replaceWith($(updateId, $data));
+ });
+ if (settings.afterAjaxUpdate !== undefined) {
+ settings.afterAjaxUpdate(id, data);
+ }
+ if (settings.selectableRows > 0) {
+ selectCheckedRows(id);
+ }
+ },
+ error: function (XHR, textStatus, errorThrown) {
+ var ret, err;
+ $grid.removeClass(settings.loadingClass);
+ if (XHR.readyState === 0 || XHR.status === 0) {
+ return;
+ }
+ if (customError !== undefined) {
+ ret = customError(XHR);
+ if (ret !== undefined && !ret) {
+ return;
+ }
+ }
+ switch (textStatus) {
+ case 'timeout':
+ err = 'The request timed out!';
+ break;
+ case 'parsererror':
+ err = 'Parser error!';
+ break;
+ case 'error':
+ if (XHR.status && !/^\s*$/.test(XHR.status)) {
+ err = 'Error ' + XHR.status;
+ } else {
+ err = 'Error';
+ }
+ if (XHR.responseText && !/^\s*$/.test(XHR.responseText)) {
+ err = err + ': ' + XHR.responseText;
+ }
+ break;
+ }
+
+ if (settings.ajaxUpdateError !== undefined) {
+ settings.ajaxUpdateError(XHR, textStatus, errorThrown, err);
+ } else if (err) {
+ alert(err);
+ }
+ }
+ }, options || {});
+ if (options.data !== undefined && options.type === 'GET') {
+ options.url = $.param.querystring(options.url, options.data);
+ options.data = {};
+ }
+
+ if (settings.ajaxUpdate !== false) {
+ options.url = $.param.querystring(options.url, settings.ajaxVar + '=' + id);
+ if (settings.beforeAjaxUpdate !== undefined) {
+ settings.beforeAjaxUpdate(id, options);
+ }
+ $.ajax(options);
+ } else { // non-ajax mode
+ if (options.type === 'GET') {
+ window.location.href = options.url;
+ } else { // POST mode
+ $form = $('<form action="' + options.url + '" method="post"></form>').appendTo('body');
+ if (options.data === undefined) {
+ options.data = {};
+ }
+
+ if (options.data.returnUrl === undefined) {
+ options.data.returnUrl = window.location.href;
+ }
+
+ $.each(options.data, function (name, value) {
+ $form.append($('<input type="hidden" name="t" value="" />').attr('name', name).val(value));
+ });
+ $form.submit();
+ }
+ }
+ });
+ },
+
+ /**
+ * Returns the key values of the currently selected rows.
+ * @return array the key values of the currently selected rows.
+ */
+ getSelection: function () {
+ var settings = gridSettings[this.attr('id')],
+ keys = this.find('.keys span'),
+ selection = [];
+ this.find('.' + settings.tableClass).children('tbody').children().each(function (i) {
+ if ($(this).hasClass('selected')) {
+ selection.push(keys.eq(i).text());
+ }
+ });
+ return selection;
+ },
+
+ /**
+ * Returns the key values of the currently checked rows.
+ * @param column_id string the ID of the column
+ * @return array the key values of the currently checked rows.
+ */
+ getChecked: function (column_id) {
+ var settings = gridSettings[this.attr('id')],
+ keys = this.find('.keys span'),
+ checked = [];
+ if (column_id.substring(column_id.length - 2) !== '[]') {
+ column_id = column_id + '[]';
+ }
+ this.find('.' + settings.tableClass).children('tbody').children('tr').children('td').children('input[name="' + column_id + '"]').each(function (i) {
+ if (this.checked) {
+ checked.push(keys.eq(i).text());
+ }
+ });
+ return checked;
+ }
+
+ };
+
+ $.fn.yiiGridView = function (method) {
+ if (methods[method]) {
+ return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+ } else if (typeof method === 'object' || !method) {
+ return methods.init.apply(this, arguments);
+ } else {
+ $.error('Method ' + method + ' does not exist on jQuery.yiiGridView');
+ return false;
+ }
+ };
+
+/******************************************************************************
+ *** DEPRECATED METHODS
+ *** used before Yii 1.1.9
+ ******************************************************************************/
+ $.fn.yiiGridView.settings = gridSettings;
+ /**
+ * Returns the key value for the specified row
+ * @param id string the ID of the grid view container
+ * @param row integer the row number (zero-based index)
+ * @return string the key value
+ */
+ $.fn.yiiGridView.getKey = function (id, row) {
+ return $('#' + id).yiiGridView('getKey', row);
+ };
+
+ /**
+ * Returns the URL that generates the grid view content.
+ * @param id string the ID of the grid view container
+ * @return string the URL that generates the grid view content.
+ */
+ $.fn.yiiGridView.getUrl = function (id) {
+ return $('#' + id).yiiGridView('getUrl');
+ };
+
+ /**
+ * Returns the jQuery collection of the cells in the specified row.
+ * @param id string the ID of the grid view container
+ * @param row integer the row number (zero-based index)
+ * @return jQuery the jQuery collection of the cells in the specified row.
+ */
+ $.fn.yiiGridView.getRow = function (id, row) {
+ return $('#' + id).yiiGridView('getRow', row);
+ };
+
+ /**
+ * Returns the jQuery collection of the cells in the specified column.
+ * @param id string the ID of the grid view container
+ * @param column integer the column number (zero-based index)
+ * @return jQuery the jQuery collection of the cells in the specified column.
+ */
+ $.fn.yiiGridView.getColumn = function (id, column) {
+ return $('#' + id).yiiGridView('getColumn', column);
+ };
+
+ /**
+ * Performs an AJAX-based update of the grid view contents.
+ * @param id string the ID of the grid view container
+ * @param options map the AJAX request options (see jQuery.ajax API manual). By default,
+ * the URL to be requested is the one that generates the current content of the grid view.
+ */
+ $.fn.yiiGridView.update = function (id, options) {
+ $('#' + id).yiiGridView('update', options);
+ };
+
+ /**
+ * Returns the key values of the currently selected rows.
+ * @param id string the ID of the grid view container
+ * @return array the key values of the currently selected rows.
+ */
+ $.fn.yiiGridView.getSelection = function (id) {
+ return $('#' + id).yiiGridView('getSelection');
+ };
+
+ /**
+ * Returns the key values of the currently checked rows.
+ * @param id string the ID of the grid view container
+ * @param column_id string the ID of the column
+ * @return array the key values of the currently checked rows.
+ */
+ $.fn.yiiGridView.getChecked = function (id, column_id) {
+ return $('#' + id).yiiGridView('getChecked', column_id);
+ };
+})(jQuery);
View
BIN webapp3/assets/7c286c99/gridview/loading.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
125 webapp3/assets/7c286c99/gridview/styles.css
@@ -0,0 +1,125 @@
+.grid-view-loading
+{
+ background:url(loading.gif) no-repeat;
+}
+
+.grid-view
+{
+ padding: 15px 0;
+}
+
+.grid-view table.items
+{
+ background: white;
+ border-collapse: collapse;
+ width: 100%;
+ border: 1px #D0E3EF solid;
+}
+
+.grid-view table.items th, .grid-view table.items td
+{
+ font-size: 0.9em;
+ border: 1px white solid;
+ padding: 0.3em;
+}
+
+.grid-view table.items th
+{
+ color: white;
+ background: url("bg.gif") repeat-x scroll left top white;
+ text-align: center;
+}
+
+.grid-view table.items th a
+{
+ color: #EEE;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+.grid-view table.items th a:hover
+{
+ color: #FFF;
+}
+
+.grid-view table.items th a.asc
+{
+ background:url(up.gif) right center no-repeat;
+ padding-right: 10px;
+}
+
+.grid-view table.items th a.desc
+{
+ background:url(down.gif) right center no-repeat;
+ padding-right: 10px;
+}
+
+.grid-view table.items tr.even
+{
+ background: #F8F8F8;
+}
+
+.grid-view table.items tr.odd
+{
+ background: #E5F1F4;
+}
+
+.grid-view table.items tr.selected
+{
+ background: #BCE774;
+}
+
+.grid-view table.items tr:hover.selected
+{
+ background: #CCFF66;
+}
+
+.grid-view table.items tbody tr:hover
+{
+ background: #ECFBD4;
+}
+
+.grid-view .link-column img
+{
+ border: 0;
+}
+
+.grid-view .button-column
+{
+ text-align: center;
+ width: 60px;
+}
+
+.grid-view .button-column img
+{
+ border: 0;
+}
+
+.grid-view .checkbox-column
+{
+ width: 15px;
+}
+
+.grid-view .summary
+{
+ margin: 0 0 5px 0;
+ text-align: right;
+}
+
+.grid-view .pager
+{
+ margin: 5px 0 0 0;
+ text-align: right;
+}
+
+.grid-view .empty
+{
+ font-style: italic;
+}
+
+.grid-view .filters input,
+.grid-view .filters select
+{
+ width: 100%;
+ border: 1px solid #ccc;
+}
View
BIN webapp3/assets/7c286c99/gridview/up.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN webapp3/assets/7c286c99/gridview/update.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN webapp3/assets/7c286c99/gridview/view.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN webapp3/assets/7c286c99/listview/down.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
169 webapp3/assets/7c286c99/listview/jquery.yiilistview.js
@@ -0,0 +1,169 @@
+/**
+ * jQuery Yii ListView plugin file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2010 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+;(function($) {
+ /**
+ * yiiListView set function.
+ * @param options map settings for the list view. Availablel options are as follows:
+ * - ajaxUpdate: array, IDs of the containers whose content may be updated by ajax response
+ * - ajaxVar: string, the name of the GET variable indicating the ID of the element triggering the AJAX request
+ * - pagerClass: string, the CSS class for the pager container
+ * - sorterClass: string, the CSS class for the sorter container
+ * - updateSelector: string, the selector for choosing which elements can trigger ajax requests
+ * - beforeAjaxUpdate: function, the function to be called before ajax request is sent
+ * - afterAjaxUpdate: function, the function to be called after ajax response is received
+ */
+ $.fn.yiiListView = function(options) {
+ return this.each(function(){
+ var settings = $.extend({}, $.fn.yiiListView.defaults, options || {}),
+ $this = $(this),
+ id = $this.attr('id');
+
+ if(settings.updateSelector == undefined) {
+ settings.updateSelector = '#'+id+' .'+settings.pagerClass.replace(/\s+/g,'.')+' a, #'+id+' .'+settings.sorterClass.replace(/\s+/g,'.')+' a';
+ }
+ $.fn.yiiListView.settings[id] = settings;
+
+ if(settings.ajaxUpdate.length > 0) {
+ $(document).on('click.yiiListView', settings.updateSelector,function(){
+ if(settings.enableHistory && window.History.enabled) {
+ var url = $(this).attr('href').split('?'),
+ params = $.deparam.querystring('?'+url[1]);
+
+ delete params[settings.ajaxVar];
+ window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url[0], params)));
+ } else {
+ $.fn.yiiListView.update(id, {url: $(this).attr('href')});
+ }
+ return false;
+ });
+
+ if(settings.enableHistory && window.History.enabled) {
+ $(window).bind('statechange', function() { // Note: We are using statechange instead of popstate
+ var State = window.History.getState(); // Note: We are using History.getState() instead of event.state
+ $.fn.yiiListView.update(id, {url: State.url});
+ });
+ }
+ }
+ });
+ };
+
+ $.fn.yiiListView.defaults = {
+ ajaxUpdate: [],
+ ajaxVar: 'ajax',
+ pagerClass: 'pager',
+ loadingClass: 'loading',
+ sorterClass: 'sorter'
+ // updateSelector: '#id .pager a, '#id .sort a',
+ // beforeAjaxUpdate: function(id) {},
+ // afterAjaxUpdate: function(id, data) {},
+ // url: 'ajax request URL'
+ };
+
+ $.fn.yiiListView.settings = {};
+
+ /**
+ * Returns the key value for the specified row
+ * @param id string the ID of the list view container
+ * @param index integer the zero-based index of the data item
+ * @return string the key value
+ */
+ $.fn.yiiListView.getKey = function(id, index) {
+ return $('#'+id+' > div.keys > span:eq('+index+')').text();
+ };
+
+ /**
+ * Returns the URL that generates the list view content.
+ * @param id string the ID of the list view container
+ * @return string the URL that generates the list view content.
+ */
+ $.fn.yiiListView.getUrl = function(id) {
+ var settings = $.fn.yiiListView.settings[id];
+ return settings.url || $('#'+id+' > div.keys').attr('title');
+ };
+
+ /**
+ * Performs an AJAX-based update of the list view contents.
+ * @param id string the ID of the list view container
+ * @param options map the AJAX request options (see jQuery.ajax API manual). By default,
+ * the URL to be requested is the one that generates the current content of the list view.
+ */
+ $.fn.yiiListView.update = function(id, options) {
+ var customError,
+ settings = $.fn.yiiListView.settings[id];
+
+ if (options && options.error !== undefined) {
+ customError = options.error;
+ delete options.error;
+ }
+
+ $('#'+id).addClass(settings.loadingClass);
+ options = $.extend({
+ type: 'GET',
+ url: $.fn.yiiListView.getUrl(id),
+ success: function(data,status) {
+ $.each(settings.ajaxUpdate, function(i,v) {
+ var id='#'+v;
+ $(id).replaceWith($(id,'<div>'+data+'</div>'));
+ });
+ if(settings.afterAjaxUpdate != undefined)
+ settings.afterAjaxUpdate(id, data);
+ $('#'+id).removeClass(settings.loadingClass);
+ },
+ error: function(XHR, textStatus, errorThrown) {
+ var ret, err;
+ $('#'+id).removeClass(settings.loadingClass);
+ if (XHR.readyState === 0 || XHR.status === 0) {
+ return;
+ }
+ if (customError !== undefined) {
+ ret = customError(XHR);
+ if (ret !== undefined && !ret) {
+ return;
+ }
+ }
+ switch (textStatus) {
+ case 'timeout':
+ err = 'The request timed out!';
+ break;
+ case 'parsererror':
+ err = 'Parser error!';
+ break;
+ case 'error':
+ if (XHR.status && !/^\s*$/.test(XHR.status)) {
+ err = 'Error ' + XHR.status;
+ } else {
+ err = 'Error';
+ }
+ if (XHR.responseText && !/^\s*$/.test(XHR.responseText)) {
+ err = err + ': ' + XHR.responseText;
+ }
+ break;
+ }
+
+ if (settings.ajaxUpdateError !== undefined) {
+ settings.ajaxUpdateError(XHR, textStatus, errorThrown, err);
+ } else if (err) {
+ alert(err);
+ }
+ }
+ }, options || {});
+
+ if(options.data!=undefined && options.type=='GET') {
+ options.url = $.param.querystring(options.url, options.data);
+ options.data = {};
+ }
+ options.url = $.param.querystring(options.url, settings.ajaxVar+'='+id);
+
+ if(settings.beforeAjaxUpdate != undefined)
+ settings.beforeAjaxUpdate(id);
+ $.ajax(options);
+ };
+
+})(jQuery);
View
BIN webapp3/assets/7c286c99/listview/loading.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
56 webapp3/assets/7c286c99/listview/styles.css
@@ -0,0 +1,56 @@
+.list-view-loading
+{
+ background:url(loading.gif) no-repeat;
+}
+
+.list-view .summary
+{
+ margin: 0 0 5px 0;
+ text-align: right;
+}
+
+.list-view .sorter
+{
+ margin: 0 0 5px 0;
+ text-align: right;
+}
+
+.list-view .pager
+{
+ margin: 5px 0 0 0;
+ text-align: right;
+}
+
+.list-view .sorter
+{
+ font-size: 0.9em;
+}
+
+.list-view .sorter ul
+{
+ display: inline;
+ list-style-image:none;
+ list-style-position:outside;
+ list-style-type:none;
+ margin:0;
+ padding:0;
+}
+
+.list-view .sorter li
+{
+ display: inline;
+ margin: 0 0 0 5px;
+ padding: 0;
+}
+
+.list-view .sorter a.asc
+{
+ background:url(up.gif) right center no-repeat;
+ padding-right: 10px;
+}
+
+.list-view .sorter a.desc
+{
+ background:url(down.gif) right center no-repeat;
+ padding-right: 10px;
+}
View
BIN webapp3/assets/7c286c99/listview/up.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN webapp3/assets/ee277cf4/autocomplete/indicator.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
48 webapp3/assets/ee277cf4/autocomplete/jquery.autocomplete.css
@@ -0,0 +1,48 @@
+.ac_results {
+ padding: 0px;
+ border: 1px solid black;
+ background-color: white;
+ overflow: hidden;
+ z-index: 99999;
+}
+
+.ac_results ul {
+ width: 100%;
+ list-style-position: outside;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.ac_results li {
+ margin: 0px;
+ padding: 2px 5px;
+ cursor: default;
+ display: block;
+ /*
+ if width will be 100% horizontal scrollbar will apear
+ when scroll mode will be used
+ */
+ /*width: 100%;*/
+ font: menu;
+ font-size: 12px;
+ /*
+ it is very important, if line-height not setted or setted
+ in relative units scroll will be broken in firefox
+ */
+ line-height: 16px;
+ overflow: hidden;
+}
+
+.ac_loading {
+ background: white url('indicator.gif') right center no-repeat;
+}
+
+.ac_odd {
+ background-color: #eee;
+}
+
+.ac_over {
+ background-color: #0A246A;
+ color: white;
+}
View
116 webapp3/assets/ee277cf4/jquery.ajaxqueue.js
@@ -0,0 +1,116 @@
+/**
+ * Ajax Queue Plugin
+ *
+ * Homepage: http://jquery.com/plugins/project/ajaxqueue
+ * Documentation: http://docs.jquery.com/AjaxQueue
+ */
+
+/**
+
+<script>
+$(function(){
+ jQuery.ajaxQueue({
+ url: "test.php",
+ success: function(html){ jQuery("ul").append(html); }
+ });
+ jQuery.ajaxQueue({
+ url: "test.php",
+ success: function(html){ jQuery("ul").append(html); }
+ });
+ jQuery.ajaxSync({
+ url: "test.php",
+ success: function(html){ jQuery("ul").append("<b>"+html+"</b>"); }
+ });
+ jQuery.ajaxSync({
+ url: "test.php",
+ success: function(html){ jQuery("ul").append("<b>"+html+"</b>"); }
+ });
+});
+</script>
+<ul style="position: absolute; top: 5px; right: 5px;"></ul>
+
+ */
+/*
+ * Queued Ajax requests.
+ * A new Ajax request won't be started until the previous queued
+ * request has finished.
+ */
+
+/*
+ * Synced Ajax requests.
+ * The Ajax request will happen as soon as you call this method, but
+ * the callbacks (success/error/complete) won't fire until all previous
+ * synced requests have been completed.
+ */
+
+
+(function($) {
+
+ var ajax = $.ajax;
+
+ var pendingRequests = {};
+
+ var synced = [];
+ var syncedData = [];
+
+ $.ajax = function(settings) {
+ // create settings for compatibility with ajaxSetup
+ settings = jQuery.extend(settings, jQuery.extend({}, jQuery.ajaxSettings, settings));
+
+ var port = settings.port;
+
+ switch(settings.mode) {
+ case "abort":
+ if ( pendingRequests[port] ) {
+ pendingRequests[port].abort();
+ }
+ return pendingRequests[port] = ajax.apply(this, arguments);
+ case "queue":
+ var _old = settings.complete;
+ settings.complete = function(){
+ if ( _old )
+ _old.apply( this, arguments );
+ jQuery([ajax]).dequeue("ajax" + port );;
+ };
+
+ jQuery([ ajax ]).queue("ajax" + port, function(){
+ ajax( settings );
+ });
+ return;
+ case "sync":
+ var pos = synced.length;
+
+ synced[ pos ] = {
+ error: settings.error,
+ success: settings.success,
+ complete: settings.complete,
+ done: false
+ };
+
+ syncedData[ pos ] = {
+ error: [],
+ success: [],
+ complete: []
+ };
+
+ settings.error = function(){ syncedData[ pos ].error = arguments; };
+ settings.success = function(){ syncedData[ pos ].success = arguments; };
+ settings.complete = function(){
+ syncedData[ pos ].complete = arguments;
+ synced[ pos ].done = true;
+
+ if ( pos == 0 || !synced[ pos-1 ] )
+ for ( var i = pos; i < synced.length && synced[i].done; i++ ) {
+ if ( synced[i].error ) synced[i].error.apply( jQuery, syncedData[i].error );
+ if ( synced[i].success ) synced[i].success.apply( jQuery, syncedData[i].success );
+ if ( synced[i].complete ) synced[i].complete.apply( jQuery, syncedData[i].complete );
+
+ synced[i] = null;
+ syncedData[i] = null;
+ }
+ };
+ }
+ return ajax.apply(this, arguments);
+ };
+
+})(jQuery);
View
813 webapp3/assets/ee277cf4/jquery.autocomplete.js
@@ -0,0 +1,813 @@
+/*
+ * jQuery Autocomplete plugin 1.1
+ *
+ * Modified for Yii Framework:
+ * - Renamed "autocomplete" to "legacyautocomplete".
+ * - Fixed IE8 problems (mario.ffranco).
+ *
+ * Copyright (c) 2009 Jörn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $
+ */
+
+;(function($) {
+
+$.fn.extend({
+ legacyautocomplete: function(urlOrData, options) {
+ var isUrl = typeof urlOrData == "string";
+ options = $.extend({}, $.Autocompleter.defaults, {
+ url: isUrl ? urlOrData : null,
+ data: isUrl ? null : urlOrData,
+ delay: isUrl ? $.Autocompleter.defaults.delay : 10,
+ max: options && !options.scroll ? 10 : 150
+ }, options);
+
+ // if highlight is set to false, replace it with a do-nothing function
+ options.highlight = options.highlight || function(value) { return value; };
+
+ // if the formatMatch option is not specified, then use formatItem for backwards compatibility
+ options.formatMatch = options.formatMatch || options.formatItem;
+
+ return this.each(function() {
+ new $.Autocompleter(this, options);
+ });
+ },
+ result: function(handler) {
+ return this.bind("result", handler);
+ },
+ search: function(handler) {
+ return this.trigger("search", [handler]);
+ },
+ flushCache: function() {
+ return this.trigger("flushCache");
+ },
+ setOptions: function(options){
+ return this.trigger("setOptions", [options]);
+ },
+ unautocomplete: function() {
+ return this.trigger("unautocomplete");
+ }
+});
+
+$.Autocompleter = function(input, options) {
+
+ var KEY = {
+ UP: 38,
+ DOWN: 40,
+ DEL: 46,
+ TAB: 9,
+ RETURN: 13,
+ ESC: 27,
+ COMMA: 188,
+ PAGEUP: 33,
+ PAGEDOWN: 34,
+ BACKSPACE: 8
+ };
+
+ // Create $ object for input element
+ var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
+
+ var timeout;
+ var previousValue = "";
+ var cache = $.Autocompleter.Cache(options);
+ var hasFocus = 0;
+ var lastKeyPressCode;
+ var config = {
+ mouseDownOnSelect: false
+ };
+ var select = $.Autocompleter.Select(options, input, selectCurrent, config);
+
+ var blockSubmit;
+
+ // prevent form submit in opera when selecting with return key
+ $.browser.opera && $(input.form).bind("submit.autocomplete", function() {
+ if (blockSubmit) {
+ blockSubmit = false;
+ return false;
+ }
+ });
+
+ // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
+ $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
+ // a keypress means the input has focus
+ // avoids issue where input had focus before the autocomplete was applied
+ hasFocus = 1;
+ // track last key pressed
+ lastKeyPressCode = event.keyCode;
+ switch(event.keyCode) {
+
+ case KEY.UP:
+ event.preventDefault();
+ if ( select.visible() ) {
+ select.prev();
+ } else {
+ onChange(0, true);
+ }
+ break;
+
+ case KEY.DOWN:
+ event.preventDefault();
+ if ( select.visible() ) {
+ select.next();
+ } else {
+ onChange(0, true);
+ }
+ break;
+
+ case KEY.PAGEUP:
+ event.preventDefault();
+ if ( select.visible() ) {
+ select.pageUp();
+ } else {
+ onChange(0, true);
+ }
+ break;
+
+ case KEY.PAGEDOWN:
+ event.preventDefault();
+ if ( select.visible() ) {
+ select.pageDown();
+ } else {
+ onChange(0, true);
+ }
+ break;
+
+ // matches also semicolon
+ case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
+ case KEY.TAB:
+ case KEY.RETURN:
+ if( selectCurrent() ) {
+ // stop default to prevent a form submit, Opera needs special handling
+ event.preventDefault();
+ blockSubmit = true;
+ return false;
+ }
+ break;
+
+ case KEY.ESC:
+ select.hide();
+ break;
+
+ default:
+ clearTimeout(timeout);
+ timeout = setTimeout(onChange, options.delay);
+ break;
+ }
+ }).focus(function(){
+ // track whether the field has focus, we shouldn't process any
+ // results if the field no longer has focus
+ hasFocus++;
+ }).blur(function() {
+ hasFocus = 0;
+ if (!config.mouseDownOnSelect) {
+ hideResults();
+ }
+ }).click(function() {
+ // show select when clicking in a focused field
+ if ( hasFocus++ > 1 && !select.visible() ) {
+ onChange(0, true);
+ }
+ }).bind("search", function() {
+ // TODO why not just specifying both arguments?
+ var fn = (arguments.length > 1) ? arguments[1] : null;
+ function findValueCallback(q, data) {
+ var result;
+ if( data && data.length ) {
+ for (var i=0; i < data.length; i++) {
+ if( data[i].result.toLowerCase() == q.toLowerCase() ) {
+ result = data[i];
+ break;
+ }
+ }
+ }
+ if( typeof fn == "function" ) fn(result);
+ else $input.trigger("result", result && [result.data, result.value]);
+ }
+ $.each(trimWords($input.val()), function(i, value) {
+ request(value, findValueCallback, findValueCallback);
+ });
+ }).bind("flushCache", function() {
+ cache.flush();
+ }).bind("setOptions", function() {
+ $.extend(options, arguments[1]);
+ // if we've updated the data, repopulate
+ if ( "data" in arguments[1] )
+ cache.populate();
+ }).bind("unautocomplete", function() {
+ select.unbind();
+ $input.unbind();
+ $(input.form).unbind(".autocomplete");
+ });
+
+
+ function selectCurrent() {
+ var selected = select.selected();
+ if( !selected )
+ return false;
+
+ var v = selected.result;
+ previousValue = v;
+
+ if ( options.multiple ) {
+ var words = trimWords($input.val());
+ if ( words.length > 1 ) {
+ var seperator = options.multipleSeparator.length;
+ var cursorAt = $(input).selection().start;
+ var wordAt, progress = 0;
+ $.each(words, function(i, word) {
+ progress += word.length;
+ if (cursorAt <= progress) {
+ wordAt = i;
+ // Following return caused IE8 to set cursor to the start of the line.
+ // return false;
+ }
+ progress += seperator;
+ });
+ words[wordAt] = v;
+ // TODO this should set the cursor to the right position, but it gets overriden somewhere
+ //$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
+ v = words.join( options.multipleSeparator );
+ }
+ v += options.multipleSeparator;
+ }
+
+ $input.val(v);
+ hideResultsNow();
+ $input.trigger("result", [selected.data, selected.value]);
+ return true;
+ }
+
+ function onChange(crap, skipPrevCheck) {
+ if( lastKeyPressCode == KEY.DEL ) {
+ select.hide();
+ return;
+ }
+
+ var currentValue = $input.val();
+
+ if ( !skipPrevCheck && currentValue == previousValue )
+ return;
+
+ previousValue = currentValue;
+
+ currentValue = lastWord(currentValue);
+ if ( currentValue.length >= options.minChars) {
+ $input.addClass(options.loadingClass);
+ if (!options.matchCase)
+ currentValue = currentValue.toLowerCase();
+ request(currentValue, receiveData, hideResultsNow);
+ } else {
+ stopLoading();
+ select.hide();
+ }
+ };
+
+ function trimWords(value) {
+ if (!value)
+ return [""];
+ if (!options.multiple)
+ return [$.trim(value)];
+ return $.map(value.split(options.multipleSeparator), function(word) {
+ return $.trim(value).length ? $.trim(word) : null;
+ });
+ }
+
+ function lastWord(value) {
+ if ( !options.multiple )
+ return value;
+ var words = trimWords(value);
+ if (words.length == 1)
+ return words[0];
+ var cursorAt = $(input).selection().start;
+ if (cursorAt == value.length) {
+ words = trimWords(value)
+ } else {
+ words = trimWords(value.replace(value.substring(cursorAt), ""));
+ }
+ return words[words.length - 1];
+ }
+
+ // fills in the input box w/the first match (assumed to be the best match)
+ // q: the term entered
+ // sValue: the first matching result
+ function autoFill(q, sValue){
+ // autofill in the complete box w/the first match as long as the user hasn't entered in more data
+ // if the last user key pressed was backspace, don't autofill
+ if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
+ // fill in the value (keep the case the user has typed)
+ $input.val($input.val() + sValue.substring(lastWord(previousValue).length));
+ // select the portion of the value not typed by the user (so the next character will erase)
+ $(input).selection(previousValue.length, previousValue.length + sValue.length);
+ }
+ };
+
+ function hideResults() {
+ clearTimeout(timeout);
+ timeout = setTimeout(hideResultsNow, 200);
+ };
+
+ function hideResultsNow() {
+ var wasVisible = select.visible();
+ select.hide();
+ clearTimeout(timeout);
+ stopLoading();
+ if (options.mustMatch) {
+ // call search and run callback
+ $input.search(
+ function (result){
+ // if no value found, clear the input box
+ if( !result ) {
+ if (options.multiple) {
+ var words = trimWords($input.val()).slice(0, -1);
+ $input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
+ }
+ else {
+ $input.val( "" );
+ $input.trigger("result", null);
+ }
+ }
+ }
+ );
+ }
+ };
+
+ function receiveData(q, data) {
+ if ( data && data.length && hasFocus ) {
+ stopLoading();
+ select.display(data, q);
+ autoFill(q, data[0].value);
+ select.show();
+ } else {
+ hideResultsNow();
+ }
+ };
+
+ function request(term, success, failure) {
+ if (!options.matchCase)
+ term = term.toLowerCase();
+ var data = cache.load(term);
+ // recieve the cached data
+ if (data && data.length) {
+ success(term, data);
+ // if an AJAX url has been supplied, try loading the data now
+ } else if( (typeof options.url == "string") && (options.url.length > 0) ){
+
+ var extraParams = {
+ timestamp: +new Date()
+ };
+ $.each(options.extraParams, function(key, param) {
+ extraParams[key] = typeof param == "function" ? param() : param;
+ });
+
+ $.ajax({
+ // try to leverage ajaxQueue plugin to abort previous requests
+ mode: "abort",
+ // limit abortion to this input
+ port: "autocomplete" + input.name,
+ dataType: options.dataType,
+ url: options.url,
+ data: $.extend({
+ q: lastWord(term),
+ limit: options.max
+ }, extraParams),
+ success: function(data) {
+ var parsed = options.parse && options.parse(data) || parse(data);
+ cache.add(term, parsed);
+ success(term, parsed);
+ }
+ });
+ } else {
+ // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
+ select.emptyList();
+ failure(term);
+ }
+ };
+
+ function parse(data) {
+ var parsed = [];
+ var rows = data.split("\n");
+ for (var i=0; i < rows.length; i++) {
+ var row = $.trim(rows[i]);
+ if (row) {
+ row = row.split("|");
+ parsed[parsed.length] = {
+ data: row,
+ value: row[0],
+ result: options.formatResult && options.formatResult(row, row[0]) || row[0]
+ };
+ }
+ }
+ return parsed;
+ };
+
+ function stopLoading() {
+ $input.removeClass(options.loadingClass);
+ };
+
+};
+
+$.Autocompleter.defaults = {
+ inputClass: "ac_input",
+ resultsClass: "ac_results",
+ loadingClass: "ac_loading",
+ minChars: 1,
+ delay: 400,
+ matchCase: false,
+ matchSubset: true,
+ matchContains: false,
+ cacheLength: 10,
+ max: 100,
+ mustMatch: false,
+ extraParams: {},
+ selectFirst: true,
+ formatItem: function(row) { return row[0]; },
+ formatMatch: null,
+ autoFill: false,
+ width: 0,
+ multiple: false,
+ multipleSeparator: ", ",
+ highlight: function(value, term) {
+ return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
+ },
+ scroll: true,
+ scrollHeight: 180
+};
+
+$.Autocompleter.Cache = function(options) {
+
+ var data = {};
+ var length = 0;
+
+ function matchSubset(s, sub) {
+ if (!options.matchCase)
+ s = s.toLowerCase();
+ var i = s.indexOf(sub);
+ if (options.matchContains == "word"){
+ i = s.toLowerCase().search("\\b" + sub.toLowerCase());
+ }
+ if (i == -1) return false;
+ return i == 0 || options.matchContains;
+ };
+
+ function add(q, value) {
+ if (length > options.cacheLength){
+ flush();
+ }
+ if (!data[q]){
+ length++;
+ }
+ data[q] = value;
+ }
+
+ function populate(){
+ if( !options.data ) return false;
+ // track the matches
+ var stMatchSets = {},
+ nullData = 0;
+
+ // no url was specified, we need to adjust the cache length to make sure it fits the local data store
+ if( !options.url ) options.cacheLength = 1;
+
+ // track all options for minChars = 0
+ stMatchSets[""] = [];
+
+ // loop through the array and create a lookup structure
+ for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
+ var rawValue = options.data[i];
+ // if rawValue is a string, make an array otherwise just reference the array
+ rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
+
+ var value = options.formatMatch(rawValue, i+1, options.data.length);
+ if ( value === false )
+ continue;
+
+ var firstChar = value.charAt(0).toLowerCase();
+ // if no lookup array for this character exists, look it up now
+ if( !stMatchSets[firstChar] )
+ stMatchSets[firstChar] = [];
+
+ // if the match is a string
+ var row = {
+ value: value,
+ data: rawValue,
+ result: options.formatResult && options.formatResult(rawValue) || value
+ };
+
+ // push the current match into the set list
+ stMatchSets[firstChar].push(row);
+
+ // keep track of minChars zero items
+ if ( nullData++ < options.max ) {
+ stMatchSets[""].push(row);
+ }
+ };
+
+ // add the data items to the cache
+ $.each(stMatchSets, function(i, value) {
+ // increase the cache size
+ options.cacheLength++;
+ // add to the cache
+ add(i, value);
+ });
+ }
+
+ // populate any existing data
+ setTimeout(populate, 25);
+
+ function flush(){
+ data = {};
+ length = 0;
+ }
+
+ return {
+ flush: flush,
+ add: add,
+ populate: populate,
+ load: function(q) {
+ if (!options.cacheLength || !length)
+ return null;
+ /*
+ * if dealing w/local data and matchContains than we must make sure
+ * to loop through all the data collections looking for matches
+ */
+ if( !options.url && options.matchContains ){
+ // track all matches
+ var csub = [];
+ // loop through all the data grids for matches
+ for( var k in data ){
+ // don't search through the stMatchSets[""] (minChars: 0) cache
+ // this prevents duplicates
+ if( k.length > 0 ){
+ var c = data[k];
+ $.each(c, function(i, x) {
+ // if we've got a match, add it to the array
+ if (matchSubset(x.value, q)) {
+ csub.push(x);
+ }
+ });
+ }
+ }
+ return csub;
+ } else
+ // if the exact item exists, use it
+ if (data[q]){
+ return data[q];
+ } else
+ if (options.matchSubset) {
+ for (var i = q.length - 1; i >= options.minChars; i--) {
+ var c = data[q.substr(0, i)];
+ if (c) {
+ var csub = [];
+ $.each(c, function(i, x) {
+ if (matchSubset(x.value, q)) {
+ csub[csub.length] = x;
+ }
+ });
+ return csub;
+ }
+ }
+ }
+ return null;
+ }
+ };
+};
+
+$.Autocompleter.Select = function (options, input, select, config) {
+ var CLASSES = {
+ ACTIVE: "ac_over"
+ };
+
+ var listItems,
+ active = -1,
+ data,
+ term = "",
+ needsInit = true,
+ element,
+ list;
+
+ // Create results
+ function init() {
+ if (!needsInit)
+ return;
+ element = $("<div/>")
+ .hide()
+ .addClass(options.resultsClass)
+ .css("position", "absolute")
+ .appendTo(document.body);
+
+ list = $("<ul/>").appendTo(element).mouseover( function(event) {
+ if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
+ active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
+ $(target(event)).addClass(CLASSES.ACTIVE);
+ }
+ }).click(function(event) {
+ $(target(event)).addClass(CLASSES.ACTIVE);
+ select();
+ // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
+ input.focus();
+ return false;
+ }).mousedown(function() {
+ config.mouseDownOnSelect = true;
+ }).mouseup(function() {
+ config.mouseDownOnSelect = false;
+ });
+
+ if( options.width > 0 )
+ element.css("width", options.width);
+
+ needsInit = false;
+ }
+
+ function target(event) {
+ var element = event.target;
+ while(element && element.tagName != "LI")
+ element = element.parentNode;
+ // more fun with IE, sometimes event.target is empty, just ignore it then
+ if(!element)
+ return [];
+ return element;
+ }
+
+ function moveSelect(step) {
+ listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
+ movePosition(step);
+ var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
+ if(options.scroll) {
+ var offset = 0;
+ listItems.slice(0, active).each(function() {
+ offset += this.offsetHeight;
+ });
+ if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
+ list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
+ } else if(offset < list.scrollTop()) {
+ list.scrollTop(offset);
+ }
+ }
+ };
+
+ function movePosition(step) {
+ active += step;
+ if (active < 0) {
+ active = listItems.size() - 1;
+ } else if (active >= listItems.size()) {
+ active = 0;
+ }
+ }
+
+ function limitNumberOfItems(available) {
+ return options.max && options.max < available
+ ? options.max
+ : available;
+ }
+
+ function fillList() {
+ list.empty();
+ var max = limitNumberOfItems(data.length);
+ for (var i=0; i < max; i++) {
+ if (!data[i])
+ continue;
+ var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
+ if ( formatted === false )
+ continue;
+ var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
+ $.data(li, "ac_data", data[i]);
+ }
+ listItems = list.find("li");
+ if ( options.selectFirst ) {
+ listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
+ active = 0;
+ }
+ // apply bgiframe if available
+ if ( $.fn.bgiframe )
+ list.bgiframe();
+ }
+
+ return {
+ display: function(d, q) {
+ init();
+ data = d;
+ term = q;
+ fillList();
+ },
+ next: function() {
+ moveSelect(1);
+ },
+ prev: function() {
+ moveSelect(-1);
+ },
+ pageUp: function() {
+ if (active != 0 && active - 8 < 0) {
+ moveSelect( -active );
+ } else {
+ moveSelect(-8);
+ }
+ },
+ pageDown: function() {
+ if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
+ moveSelect( listItems.size() - 1 - active );
+ } else {
+ moveSelect(8);
+ }
+ },
+ hide: function() {
+ element && element.hide();
+ listItems && listItems.removeClass(CLASSES.ACTIVE);
+ active = -1;
+ },
+ visible : function() {
+ return element && element.is(":visible");
+ },
+ current: function() {
+ return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
+ },
+ show: function() {
+ var offset = $(input).offset();
+ element.css({
+ width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
+ top: offset.top + input.offsetHeight,
+ left: offset.left
+ }).show();
+ if(options.scroll) {
+ list.scrollTop(0);
+ list.css({
+ maxHeight: options.scrollHeight,
+ overflow: 'auto'
+ });
+
+ if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
+ var listHeight = 0;
+ listItems.each(function() {
+ listHeight += this.offsetHeight;
+ });
+ var scrollbarsVisible = listHeight > options.scrollHeight;
+ list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
+ if (!scrollbarsVisible) {
+ // IE doesn't recalculate width when scrollbar disappears
+ listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
+ }
+ }
+
+ }
+ },
+ selected: function() {
+ var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
+ return selected && selected.length && $.data(selected[0], "ac_data");
+ },
+ emptyList: function (){
+ list && list.empty();
+ },
+ unbind: function() {
+ element && element.remove();
+ }
+ };
+};
+
+$.fn.selection = function(start, end) {
+ if (start !== undefined) {
+ return this.each(function() {
+ if( this.createTextRange ){
+ var selRange = this.createTextRange();
+ if (end === undefined || start == end) {
+ selRange.move("character", start);
+ selRange.select();
+ } else {
+ selRange.collapse(true);
+ selRange.moveStart("character", start);
+ selRange.moveEnd("character", end);
+ selRange.select();
+ }
+ } else if( this.setSelectionRange ){
+ this.setSelectionRange(start, end);
+ } else if( this.selectionStart ){
+ this.selectionStart = start;
+ this.selectionEnd = end;
+ }
+ });
+ }
+ var field = this[0];
+ if ( field.createTextRange ) {
+ var range = document.selection.createRange(),
+ orig = field.value,
+ teststring = "<->",
+ textLength = range.text.length;
+ range.text = teststring;
+ var caretAt = field.value.indexOf(teststring);
+ field.value = orig;
+ this.selection(caretAt, caretAt + textLength);
+ return {
+ start: caretAt,
+ end: caretAt + textLength
+ }
+ } else if( field.selectionStart !== undefined ){
+ return {
+ start: field.selectionStart,
+ end: field.selectionEnd
+ }
+ }
+};
+
+})(jQuery);
View
1,137 webapp3/assets/ee277cf4/jquery.ba-bbq.js
@@ -0,0 +1,1137 @@
+/*!
+ * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
+ * http://benalman.com/projects/jquery-bbq-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+
+// Script: jQuery BBQ: Back Button & Query Library
+//
+// *Version: 1.2.1, Last updated: 2/17/2010*
+//
+// Project Home - http://benalman.com/projects/jquery-bbq-plugin/
+// GitHub - http://github.com/cowboy/jquery-bbq/
+// Source - http://github.com/cowboy/jquery-bbq/raw/master/jquery.ba-bbq.js
+// (Minified) - http://github.com/cowboy/jquery-bbq/raw/master/jquery.ba-bbq.min.js (4.0kb)
+//
+// About: License
+//
+// Copyright (c) 2010 "Cowboy" Ben Alman,
+// Dual licensed under the MIT and GPL licenses.
+// http://benalman.com/about/license/
+//
+// About: Examples
+//
+// These working examples, complete with fully commented code, illustrate a few
+// ways in which this plugin can be used.
+//
+// Basic AJAX - http://benalman.com/code/projects/jquery-bbq/examples/fragment-basic/
+// Advanced AJAX - http://benalman.com/code/projects/jquery-bbq/examples/fragment-advanced/
+// jQuery UI Tabs - http://benalman.com/code/projects/jquery-bbq/examples/fragment-jquery-ui-tabs/
+// Deparam - http://benalman.com/code/projects/jquery-bbq/examples/deparam/
+//
+// About: Support and Testing
+//
+// Information about what version or versions of jQuery this plugin has been
+// tested with, what browsers it has been tested in, and where the unit tests
+// reside (so you can test it yourself).
+//
+// jQuery Versions - 1.3.2, 1.4.1, 1.4.2
+// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4,
+// Chrome 4-5, Opera 9.6-10.1.
+// Unit Tests - http://benalman.com/code/projects/jquery-bbq/unit/
+//
+// About: Release History
+//
+// 1.2.1 - (2/17/2010) Actually fixed the stale window.location Safari bug from
+// <jQuery hashchange event> in BBQ, which was the main reason for the
+// previous release!
+// 1.2 - (2/16/2010) Integrated <jQuery hashchange event> v1.2, which fixes a