From 00f2be30cee2f40e084c2a03ed99e1e86a8eec1f Mon Sep 17 00:00:00 2001 From: Wynne Crisman Date: Wed, 28 Dec 2016 11:13:44 -0800 Subject: [PATCH] Updated JQuery; Added resize sensor library; Updated the admin code (prior to changing gears to use Meteor). --- .gitignore | 2 +- app/initialData.js | 116 - csv.js | 15 + downloaded tools/jsgrid-1.5.2.zip | Bin 0 -> 81173 bytes importAll.js | 88 + importItems.csv | 206 + importItems.js | 221 + importSales.js | 416 + migrations/20160602030143-User.js | 3 +- migrations/20160602030145-Measure.js | 3 +- ...6-Venue.js => 20160602030146-VenueType.js} | 7 +- migrations/20160602030147-Venue.js | 49 + ...Category.js => 20160602030148-Category.js} | 3 +- ...egory.js => 20160602030149-Subcategory.js} | 3 +- ...2030149-Item.js => 20160602030150-Item.js} | 10 +- ...2030150-Sale.js => 20160602030151-Sale.js} | 0 models/item.js | 7 +- models/venue.js | 9 +- models/venueType.js | 32 + package.json | 8 +- public/admin/Venues.html | 25 +- public/admin/bootstrap.styl | 3 +- public/admin/categories.html | 18 +- public/admin/css/jsgrid-theme.css | 258 + public/admin/css/jsgrid-theme.min.css | 7 + public/admin/css/jsgrid.css | 126 + public/admin/css/jsgrid.min.css | 7 + public/admin/index.ejs | 13 +- public/admin/{main.styl => index.styl} | 3 +- public/admin/items.html | 65 +- .../js/{EditableSelect.js => de.combo.js} | 70 +- .../admin/js/{Dropdown.js => de.dropdown.js} | 6 +- .../admin/js/{linkedTable.js => de.table.js} | 57 +- public/admin/js/jquery-1.12.4.js | 11008 ++++++++++++++++ public/admin/js/jquery-1.12.4.min.js | 5 + public/admin/js/jquery-migrate-1.3.0.js | 702 + public/admin/js/jquery-migrate-1.3.0.min.js | 2 + public/admin/js/jquery-migrate-3.0.0.js | 540 + public/admin/js/jquery-migrate-3.0.0.min.js | 2 + public/admin/js/jsgrid.js | 2508 ++++ public/admin/js/jsgrid.min.js | 8 + public/admin/measures.html | 18 +- public/admin/menu.html | 4 + public/admin/prices.html | 81 + public/admin/prices.styl | 3 + public/admin/sales.html | 33 +- public/admin/subcategories.html | 20 +- public/admin/users.html | 7 +- public/index.html | 4 +- public/js/jquery-1.12.4.js | 11008 ++++++++++++++++ public/js/jquery-1.12.4.min.js | 5 + public/js/jquery-migrate-1.3.0.js | 702 + public/js/jquery-migrate-1.3.0.min.js | 2 + public/js/jquery-migrate-3.0.0.js | 540 + public/js/jquery-migrate-3.0.0.min.js | 2 + public/js/resize/ElementQueries.js | 515 + public/js/resize/ResizeSensor.js | 227 + server.js | 3 - 58 files changed, 29553 insertions(+), 252 deletions(-) delete mode 100644 app/initialData.js create mode 100644 csv.js create mode 100644 downloaded tools/jsgrid-1.5.2.zip create mode 100644 importAll.js create mode 100644 importItems.csv create mode 100644 importItems.js create mode 100644 importSales.js rename migrations/{20160602030146-Venue.js => 20160602030146-VenueType.js} (83%) create mode 100644 migrations/20160602030147-Venue.js rename migrations/{20160602030147-Category.js => 20160602030148-Category.js} (94%) rename migrations/{20160602030148-Subcategory.js => 20160602030149-Subcategory.js} (95%) rename migrations/{20160602030149-Item.js => 20160602030150-Item.js} (88%) rename migrations/{20160602030150-Sale.js => 20160602030151-Sale.js} (100%) create mode 100644 models/venueType.js create mode 100644 public/admin/css/jsgrid-theme.css create mode 100644 public/admin/css/jsgrid-theme.min.css create mode 100644 public/admin/css/jsgrid.css create mode 100644 public/admin/css/jsgrid.min.css rename public/admin/{main.styl => index.styl} (98%) rename public/admin/js/{EditableSelect.js => de.combo.js} (88%) rename public/admin/js/{Dropdown.js => de.dropdown.js} (96%) rename public/admin/js/{linkedTable.js => de.table.js} (88%) create mode 100644 public/admin/js/jquery-1.12.4.js create mode 100644 public/admin/js/jquery-1.12.4.min.js create mode 100644 public/admin/js/jquery-migrate-1.3.0.js create mode 100644 public/admin/js/jquery-migrate-1.3.0.min.js create mode 100644 public/admin/js/jquery-migrate-3.0.0.js create mode 100644 public/admin/js/jquery-migrate-3.0.0.min.js create mode 100644 public/admin/js/jsgrid.js create mode 100644 public/admin/js/jsgrid.min.js create mode 100644 public/admin/prices.html create mode 100644 public/admin/prices.styl create mode 100644 public/js/jquery-1.12.4.js create mode 100644 public/js/jquery-1.12.4.min.js create mode 100644 public/js/jquery-migrate-1.3.0.js create mode 100644 public/js/jquery-migrate-1.3.0.min.js create mode 100644 public/js/jquery-migrate-3.0.0.js create mode 100644 public/js/jquery-migrate-3.0.0.min.js create mode 100644 public/js/resize/ElementQueries.js create mode 100644 public/js/resize/ResizeSensor.js diff --git a/.gitignore b/.gitignore index f1527a7..441a3d6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ node_modules config.js public/main.css -public/admin/main.css +public/admin/index.css public/admin/*.css public/emailFailures.txt sessions/ diff --git a/app/initialData.js b/app/initialData.js deleted file mode 100644 index 08a58dd..0000000 --- a/app/initialData.js +++ /dev/null @@ -1,116 +0,0 @@ -var Promise = require('bluebird'); - -module.exports = function(sequelize) { - var models = sequelize.models; - - //Pre-populate a new database with some data. - models.Category.count().then(function(count) { - if(count == 0) { - var basicJarIds = []; - - models.User.create({login: 'wcrisman', password: 'landFJ40', admin: true}); - - models.Venue.create({name: 'Boonville'}); - models.Venue.create({name: 'Clement St Farmers Market in SF'}); - models.Venue.create({name: 'Ukiah Farmers Market'}); - models.Venue.create({name: 'Mendocino Farmers Market'}); - models.Venue.create({name: 'Ft Bragg Farmers Market'}); - - Promise.each([ - models.Measure.create({name: 'Jar 4oz', postfix: '4oz'}), - models.Measure.create({name: 'Jar 8oz', postfix: '8oz'}), - models.Measure.create({name: 'Jar 12oz', postfix: '12oz'}), - models.Measure.create({name: 'Jar 16oz', postfix: '16oz'}), - models.Measure.create({name: 'Jar 32oz', postfix: '32oz'}), - models.Measure.create({name: 'Jar 64oz', postfix: '64oz'}), - models.Measure.create({name: 'Pounds', postfix: 'lbs'}), - models.Measure.create({name: 'Each', postfix: ''}), - models.Measure.create({name: 'Bags', postfix: 'bags'}) - ], function(value, index, length) { - //Collect the first 5 jar ids. - if(index < 5) basicJarIds.push(value.id); - }).then(function() { - models.Category.create({name: 'VAP'}).then(function(category) { - models.Subcategory.create({name: 'Soups'}).then(function(subcategory) { - category.addSubcategory(subcategory); - models.Item.create({name: 'Fava Bean Bisque', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Tomato Basil Soup', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Winter Squash Soup', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - }); - models.Subcategory.create({name: 'Drink Mixes & Syrups'}).then(function(subcategory) { - category.addSubcategory(subcategory); - models.Item.create({name: 'Bloody Mary Mix', defaultPrice: 12, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Grape Syrup', defaultPrice: 8, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Prickly Pear Syrup', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Quince Syrup', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Strawberry Syrup', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Wild Plum Syrup', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - }); - models.Subcategory.create({name: 'Fermented'}).then(function(subcategory) { - category.addSubcategory(subcategory); - models.Item.create({name: 'Napa Cabbage Sauerkraut', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Napa Cabbage Sauerkraut w/ Watercress & Espelette Pepper', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Red Sauerkraut', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - }); - models.Subcategory.create({name: 'Dried Goods'}).then(function(subcategory) { - category.addSubcategory(subcategory); - models.Item.create({name: 'Dried Strawberries', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Membrillo', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Sugared Jalape�os', defaultPrice: 10, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - }); - models.Subcategory.create({name: 'Spices'}).then(function(subcategory) { - category.addSubcategory(subcategory); - models.Item.create({name: 'Basque Pepper Powder', defaultPrice: 8, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Korean Pepper Powder', defaultPrice: 8, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Smoked Basque Pepper Powder', defaultPrice: 8, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - models.Item.create({name: 'Smoked Korean Pepper Powder', defaultPrice: 8, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - }); - models.Subcategory.create({name: 'Specialty'}).then(function(subcategory) { - category.addSubcategory(subcategory); - models.Item.create({name: 'Pure Lard', defaultPrice: 4, measures: basicJarIds}).then(function(item) { - subcategory.addItem(item); - }); - }); - }); - }); - } - }); -}; \ No newline at end of file diff --git a/csv.js b/csv.js new file mode 100644 index 0000000..60401cd --- /dev/null +++ b/csv.js @@ -0,0 +1,15 @@ + +var fs = require("fs"); +var csv = require('csv-parse'); + +module.exports = { + read: function(csvFilePath, callback) { + var parser = csv({delimiter: '\t'}, function(error, data) { + if(error) callback(error); + else callback(null, data); + }); + + + fs.createReadStream(csvFilePath).pipe(parser); + } +}; \ No newline at end of file diff --git a/downloaded tools/jsgrid-1.5.2.zip b/downloaded tools/jsgrid-1.5.2.zip new file mode 100644 index 0000000000000000000000000000000000000000..a27086e07d289e1727a8a9beda3c8a53a5897512 GIT binary patch literal 81173 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 m4Er0W7V$UEzvcYb6)PtR`uQpUQ8g$41D`h 0) weightedMeasures.push({name: '32 oz', count: oz32}); + if(oz16 > 0) weightedMeasures.push({name: '16 oz', count: oz16}); + if(oz12 > 0) weightedMeasures.push({name: '12 oz', count: oz12}); + if(oz8 > 0) weightedMeasures.push({name: '8 oz', count: oz8}); + if(oz4 > 0) weightedMeasures.push({name: '4 oz', count: oz4}); + + if(weightedMeasures.length == 0) { + measures.push(eachId); + } + else { + //Place the measure that had the most jars at the front of the list. + weightedMeasures.sort(function(a, b) { + return a.count >= b.count ? 1 : -1; + }); + + //Build the array of measure id's. + for(var i = 0; i < weightedMeasures.length; i++) { + measures.push(measureIdMap[weightedMeasures[i].name]); + } + } + + //Ensure the item doesn't yet exist - display an error if it does, otherwise add it. + models.Item.findOrCreate({ + where: {name: item}, + defaults: {name: item, subcategoryId: subcategoryId, measures: measures} + }).then(function(result) { + if(!result[1]) { + console.log("The item named '" + item + "' already exists in the database."); + } + + //Recursively read rows until there are no more rows to read. + if(rowIndex + 1 < data.length) readRow(rowIndex + 1); + else resolve(); + }); + }) + }); + } + + if(fs.existsSync(fileName)) { + csv.read(fileName, function(error, csvData) { + if(error) console.log(error); + else { + data = csvData; + //Collect the mapping data. + collectMetadata(); + + //Read or create the required models to make this all work: + Promise.each([ + models.Measure.findOrCreate({where: {name: 'Jar 32oz'}, defaults: {name: 'Jar 32oz', postfix: '32oz'}}), + models.Measure.findOrCreate({where: {name: 'Jar 16oz'}, defaults: {name: 'Jar 16oz', postfix: '16oz'}}), + models.Measure.findOrCreate({where: {name: 'Jar 12oz'}, defaults: {name: 'Jar 12oz', postfix: '12oz'}}), + models.Measure.findOrCreate({where: {name: 'Jar 8oz'}, defaults: {name: 'Jar 8oz', postfix: '8oz'}}), + models.Measure.findOrCreate({where: {name: 'Jar 4oz'}, defaults: {name: 'Jar 4oz', postfix: '4oz'}}), + models.Measure.findOrCreate({where: {name: 'Each'}, defaults: {name: 'Each', postfix: ''}}) + ], function(value, index, length) { + switch(index) { + case 0: + measureIdMap['32 oz'] = value[0].id; + break; + case 1: + measureIdMap['16 oz'] = value[0].id; + break; + case 2: + measureIdMap['12 oz'] = value[0].id; + break; + case 3: + measureIdMap['8 oz'] = value[0].id; + break; + case 4: + measureIdMap['4 oz'] = value[0].id; + break; + case 5: + eachId = value[0].id; + break; + } + }).then(function() { + //Read the first row. + readRow(1); + }); + } + }); + } + else { + console.log("Cannot find " + fileName); + } +}); + +p.then(function() {console.log("Import Complete!")}).error(function(error) {console.log("Ran into an error: \n" + error)}); +// }; \ No newline at end of file diff --git a/importSales.js b/importSales.js new file mode 100644 index 0000000..2297bce --- /dev/null +++ b/importSales.js @@ -0,0 +1,416 @@ + +var fs = require("fs"); +var csv = require('./csv.js'); +var Promise = require('bluebird'); + +var fileName = "./importSales.csv"; + +// module.exports = function(models, softErrors, handler) { +// return new Promise(function(resolve, reject) { +var models = require("./models"); +var softErrors = []; +var p = new Promise(function(resolve, reject) { + //The CSV data as an array of rows (each row is an array). + var data; + //The mapping of model attributes to CSV columns. The oz sizes are arrays of columns since there are multiple. + var map = {}; + + //Database maps so we don't have to constantly query for the same data repeatedly. + var vendorIdMap = {}; + var measureIdMap = {}; + var itemIdMap = {}; + + //Collect the metadata from the first row of the CSV data - make a mapping. + function collectMetadata() { + var DATE = 'date'; + var VENDOR = 'vendor'; + var ITEM = 'item'; + var OZ32 = '32 oz'; + var OZ16 = '16 oz'; + var OZ12 = '12 oz'; + var OZ8 = '8 oz'; + var OZ4 = '4 oz'; + var BAGS = 'bags'; + var EACH = 'each'; + + //Data is an array of arrays. data[0] = array of headers. data[1] = first row of data. + //Iterate over the columns to create a mapping. + for(var i = 0; i < data[0].length; i++) { + var next = data[0][i]; + + if(next && next != '') { + switch(next.toLowerCase()) { + case DATE: + map.date = i; + break; + case VENDOR: + map.vendor = i; + break; + case ITEM: + map.item = i; + break; + case OZ32: + map.oz32 = i; + break; + case OZ16: + map.oz16 = i; + break; + case OZ12: + map.oz12 = i; + break; + case OZ8: + map.oz8 = i; + break; + case OZ4: + map.oz4 = i; + break; + case BAGS: + map.bags = i; + break; + case EACH: + map.each = i; + break; + } + } + } + } + + //Reads a single row of CSV data and adds it to the database. + function readRow(rowIndex) { + if(!data) { + console.log("WTF?"); + //process.exit(1); + reject(new Error("Data is null?!?")); + return; + } + else if(!data[rowIndex]) { + console.log("Empty line?"); + readRow(rowIndex + 1); + return; + } + + var date = data[rowIndex][map.date]; + var vendor = data[rowIndex][map.vendor]; + var item = data[rowIndex][map.item]; + var oz32 = data[rowIndex][map.oz32]; + var oz16 = data[rowIndex][map.oz16]; + var oz12 = data[rowIndex][map.oz12]; + var oz8 = data[rowIndex][map.oz8]; + var oz4 = data[rowIndex][map.oz4]; + var bags = data[rowIndex][map.bags]; + var each = data[rowIndex][map.each]; + + var vendorId = vendorIdMap[vendor]; + var itemId = itemIdMap[item]; + var priceMap = {}; + + var saleQueries = []; + + //TODO: Trim and lowercase any names. + priceMap[2016] = { + oz4: 7, + oz8: 11, + oz12: 13, + oz16: 11, + oz32: 15, + "pickled onion, spicy": {oz16: 12}, + "pickled onion, sweet": {oz16: 12}, + "pickled onion, fennel": {oz16: 12}, + "pickled beets": {oz16: 15}, + "prickly pear margarita mix": {oz16: 15}, + "prickly pear syrup": {oz16: 15}, + "tomato sauce": {oz16: 15}, //TODO: Replace all 'tomato sauce, xxxx' with 'tomato sauce' for price lookup only. + "bone broth": {oz16: 20}, //TODO: Replace all 'bone broth, xxxx' with 'bone broth' for price lookup only. + "fava bean soup": {oz32: 20}, + "pickles, bread butter": {oz16: 11}, + "kimchi": {oz16: 11}, + "kraut - red & white": {oz16: 11}, + + "3 pack": {each: 21}, + "espelette, smoked": {each: 1}, + "leather": {each: 6}, + "leather, apple": {each: 6}, + "leather, grape": {each: 6}, + "leather, peach": {each: 6}, + "leather, persimmon": {each: 6}, + "leather, pumpkin": {each: 6}, + "leather, strawberry": {each: 6}, + "leather, quince": {each: 6}, + "membrillo": {each: 7}, + "membrillo candy": {each: 2.5}, + "spices": {each: 4}, + "spices, basil/coriander": {each: 4}, + "spices, fennel": {each: 4}, + "spices, other": {each: 4}, + "spices, pepper": {each: 4}, + "spices, smoked": {each: 4}, + + "baba ganoush": {bag: 8, oz4: 8}, + "dried, pear": {bag: 6}, //Price?? + "dried, tomatillo": {bag: 6}, //Price?? + "dried, strawberry": {bag: 7.5}, + "dried, tomato": {bag: 7}, + "pesto": {bags: 8}, + "pesto, cilantro jalapeno": {bags: 8}, + "pesto, eggplant": {bags: 8}, + "pesto, mint": {bags: 8}, + "pesto, jalapeno": {bags: 8}, + "jalapeno candy": {bags: 5}, + "tomato, dried": {bag: 7}, //Spelling??? Should be Dried, Tomato + + + //Fresh + "persimmons": {lbs: 5}, + "persimmon, frozen": {lbs: 5}, + "dried, persimmon": {lbs: 5}, + + "eggs": {each: 11} + }; + + priceMap[2015] = { + oz4: 6, + oz8: 10, + oz12: 13, + oz16: 10, + oz32: 15, + "blackberry jam": {oz4: 7, oz8: 12}, + "raspberry jam": {oz4: 7, oz8: 12}, + "blackberry vanilla": {oz4: 7, oz8: 12}, + "bloody mary mix": {oz16: 13}, + "pickled beets": {oz16: 15}, + "tomato juice cocktail": {oz16: 8}, + "fava bean soup": {oz32: 20}, + "kimchi": {oz16: 10}, + "kraut - red & white": {oz16: 10}, + "bread & butter pickles": {oz16: 10}, + "pickled eggs": {oz16: 15}, + + "3 pack": {each: 18}, + "leather": {each: 6}, + "leather, apple": {each: 6}, + "leather, grape": {each: 6}, + "leather, peach": {each: 6}, + "leather, persimmon": {each: 6}, + "leather, pumpkin": {each: 6}, + "leather, strawberry": {each: 6}, + "leather, quince": {each: 6}, + "membrillo": {each: 6}, + "membrillo candy": {each: 2.5}, + "popsicles": {each: 5}, + "spices": {each: 4}, + "spices, basil/coriander": {each: 4}, + "spices, fennel": {each: 4}, + "spices, other": {each: 4}, + "spices, pepper": {each: 4}, + "spices, smoked": {each: 4}, + + "baba ganoush": {bag: 8, oz4: 8}, + "dried, pear": {bag: 6}, //Price?? + "dried, tomatillo": {bag: 6}, //Price?? + "dried, strawberry": {bag: 7.5}, + "dried, tomato": {bag: 7}, + "jalapeno candy": {bag: 5}, + + "eggs": {each: 10}, + }; + + //Log errors, but keep on chugging. + if(vendorId == undefined) { + softErrors.push("ERROR: Unexpected vendor: " + vendor); + } + else if(itemId == undefined) { + softErrors.push("ERROR: Unexpected item: " + item); + } + else { + //Split it into multiple sales entries, one for each measure that has a positive value. + if(oz32 > 0) { + var measureId = measureIdMap['32 oz']; + var price = priceMap[year][item]; + + if(price == undefined) { + price = priceMap[year]['oz32']; + } + + saleQueries.push(models.Sale.create({date: date, vendorId: vendorId, itemId: itemId, measureId: measureId, amount: oz32, price: price})); + } + + if(oz16 > 0) { + var measureId = measureIdMap['16 oz']; + var price = priceMap[year][item]; + + if(price == undefined) { + price = priceMap[year]['oz16']; + } + + saleQueries.push(models.Sale.create({date: date, vendorId: vendorId, itemId: itemId, measureId: measureId, amount: oz32, price: price})); + } + + if(oz12 > 0) { + var measureId = measureIdMap['12 oz']; + var price = priceMap[year][item]; + + if(price == undefined) { + price = priceMap[year]['oz12']; + } + + saleQueries.push(models.Sale.create({date: date, vendorId: vendorId, itemId: itemId, measureId: measureId, amount: oz32, price: price})); + } + + if(oz8 > 0) { + var measureId = measureIdMap['8 oz']; + var price = priceMap[year][item]; + + if(price == undefined) { + price = priceMap[year]['oz8']; + } + + saleQueries.push(models.Sale.create({date: date, vendorId: vendorId, itemId: itemId, measureId: measureId, amount: oz32, price: price})); + } + + if(oz4 > 0) { + var measureId = measureIdMap['4 oz']; + var price = priceMap[year][item]; + + if(price == undefined) { + price = priceMap[year]['oz4']; + } + + saleQueries.push(models.Sale.create({date: date, vendorId: vendorId, itemId: itemId, measureId: measureId, amount: oz32, price: price})); + } + + if(bags > 0) { + var measureId = measureIdMap['bags']; + var price = priceMap[year][item]; + + if(price == undefined) { + price = priceMap[year]['bags']; + } + + saleQueries.push(models.Sale.create({date: date, vendorId: vendorId, itemId: itemId, measureId: measureId, amount: oz32, price: price})); + } + + if(each > 0) { + var measureId = measureIdMap['each']; + var price = priceMap[year][item]; + + if(price == undefined) { + price = priceMap[year]['each']; + } + + saleQueries.push(models.Sale.create({date: date, vendorId: vendorId, itemId: itemId, measureId: measureId, amount: oz32, price: price})); + } + + Promise.each(saleQueries, function(value, index, length) { + //Ignored. + }).then(function(result) { + //Recursively read rows until there are no more rows to read. + if(rowIndex + 1 < data.length) readRow(rowIndex + 1); + else resolve(); + }); + } + } + + if(fs.existsSync(fileName)) { + csv.read(fileName, function(error, csvData) { + if(error) console.log(error); + else { + data = csvData; + //Collect the mapping data. + collectMetadata(); + + //Read or create the required models to make this all work: + Promise.each([ + //Measures 1-6 + models.Measure.find({where: {name: 'Jar 32oz'}}), + models.Measure.find({where: {name: 'Jar 16oz'}}), + models.Measure.find({where: {name: 'Jar 12oz'}}), + models.Measure.find({where: {name: 'Jar 8oz'}}), + models.Measure.find({where: {name: 'Jar 4oz'}}), + models.Measure.find({where: {name: 'Each'}}), + models.Measure.find({where: {name: 'Bags'}}), + //Vendors 7-16 + models.Venue.find({where: {name: 'Boonville'}}), + models.Venue.find({where: {name: 'Clement St'}}), + models.Venue.find({where: {name: 'Ukiah'}}), + models.Venue.find({where: {name: 'Mendocino'}}), + models.Venue.find({where: {name: 'Ft Bragg'}}), + models.Venue.find({where: {name: 'On Farm'}}), + models.Venue.find({where: {name: 'Unknown Restaurant'}}), + models.Venue.find({where: {name: 'Yorkville Market'}}), + models.Venue.find({where: {name: 'Yorkville Cellars'}}), + models.Venue.find({where: {name: 'Mail Order'}}), + //Items + models.Item.findAll() + ], function(value, index, length) { + switch(index) { + case 0: + measureIdMap['32 oz'] = value.id; + break; + case 1: + measureIdMap['16 oz'] = value.id; + break; + case 2: + measureIdMap['12 oz'] = value.id; + break; + case 3: + measureIdMap['8 oz'] = value.id; + break; + case 4: + measureIdMap['4 oz'] = value.id; + break; + case 5: + measureIdMap['each'] = value.id; + break; + case 6: + measureIdMap['bags'] = value.id; + break; + case 7: + vendorIdMap['bv'] = value.id; + break; + case 8: + vendorIdMap['sf'] = value.id; + break; + case 9: + vendorIdMap['uk'] = value.id; + break; + case 10: + vendorIdMap['men'] = value.id; + break; + case 11: + vendorIdMap['fb'] = value.id; + break; + case 12: + vendorIdMap['of'] = value.id; + break; + case 13: + vendorIdMap['res'] = value.id; + break; + case 14: + vendorIdMap['ym'] = value.id; + break; + case 15: + vendorIdMap['yc'] = value.id; + break; + case 16: + vendorIdMap['mo'] = value.id; + break; + case 17: + //Iterate over all the items and setup the itemIdMap to reference the item id given the item name. Item names are unique. + for(var i = 0; i < value.length; i++) { + itemIdMap[value[i].name] = value[i].id; + } + } + }).then(function() { + //Read the first row. + readRow(1); + }); + } + }); + } + else { + console.log("Cannot find " + fileName); + } +}); + +p.then(function() {console.log("Import Complete!")}).error(function(error) {console.log("Ran into an error: \n" + error)}); +// }; \ No newline at end of file diff --git a/migrations/20160602030143-User.js b/migrations/20160602030143-User.js index 1018892..3ded8fa 100644 --- a/migrations/20160602030143-User.js +++ b/migrations/20160602030143-User.js @@ -12,7 +12,8 @@ module.exports = { autoIncrement: true }, login: { - type: DataTypes.STRING + type: DataTypes.STRING, + unique: true }, password: { type: DataTypes.STRING diff --git a/migrations/20160602030145-Measure.js b/migrations/20160602030145-Measure.js index 24bc0e6..c27c77a 100644 --- a/migrations/20160602030145-Measure.js +++ b/migrations/20160602030145-Measure.js @@ -13,7 +13,8 @@ module.exports = { }, name: { type: DataTypes.STRING, - allowNull: false + allowNull: false, + unique: true }, image: { type: DataTypes.STRING, diff --git a/migrations/20160602030146-Venue.js b/migrations/20160602030146-VenueType.js similarity index 83% rename from migrations/20160602030146-Venue.js rename to migrations/20160602030146-VenueType.js index efb0af2..8507b83 100644 --- a/migrations/20160602030146-Venue.js +++ b/migrations/20160602030146-VenueType.js @@ -4,7 +4,7 @@ module.exports = { up: function (query, Sequelize) { var DataTypes = Sequelize; //Allow for more cut and paste :) - return query.createTable('Venue', { + return query.createTable('VenueType', { id: { type: DataTypes.INTEGER, primaryKey: true, @@ -13,7 +13,8 @@ module.exports = { }, name: { type: DataTypes.STRING, - allowNull: false + allowNull: false, + unique: true }, createdAt: { type: DataTypes.DATE, @@ -35,6 +36,6 @@ module.exports = { }, down: function (query, Sequelize) { - return query.dropTable('Venue'); + return query.dropTable('VenueType'); } }; diff --git a/migrations/20160602030147-Venue.js b/migrations/20160602030147-Venue.js new file mode 100644 index 0000000..8cca8a2 --- /dev/null +++ b/migrations/20160602030147-Venue.js @@ -0,0 +1,49 @@ +'use strict'; + +module.exports = { + up: function (query, Sequelize) { + var DataTypes = Sequelize; //Allow for more cut and paste :) + + return query.createTable('Venue', { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + allowNull: false, + autoIncrement: true + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + typeId: { + type: Sequelize.INTEGER, + references: { + model: 'VenueType', + key: 'id' + }, + onUpdate: 'cascade', + onDelete: 'cascade' + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + }, + deletedAt: { + type: DataTypes.DATE, + allowNull: true + } + }, { + charset: 'utf8', + timestamps: true, + paranoid: true + }); + }, + + down: function (query, Sequelize) { + return query.dropTable('Venue'); + } +}; diff --git a/migrations/20160602030147-Category.js b/migrations/20160602030148-Category.js similarity index 94% rename from migrations/20160602030147-Category.js rename to migrations/20160602030148-Category.js index f33b1e5..918b83f 100644 --- a/migrations/20160602030147-Category.js +++ b/migrations/20160602030148-Category.js @@ -13,7 +13,8 @@ module.exports = { }, name: { type: DataTypes.STRING, - allowNull: false + allowNull: false, + unique: true }, createdAt: { type: DataTypes.DATE, diff --git a/migrations/20160602030148-Subcategory.js b/migrations/20160602030149-Subcategory.js similarity index 95% rename from migrations/20160602030148-Subcategory.js rename to migrations/20160602030149-Subcategory.js index 65a9ff2..dba0d6a 100644 --- a/migrations/20160602030148-Subcategory.js +++ b/migrations/20160602030149-Subcategory.js @@ -15,7 +15,8 @@ module.exports = { name: { type: DataTypes.STRING, field: 'name', - allowNull: false + allowNull: false, + unique: true }, categoryId: { type: Sequelize.INTEGER, diff --git a/migrations/20160602030149-Item.js b/migrations/20160602030150-Item.js similarity index 88% rename from migrations/20160602030149-Item.js rename to migrations/20160602030150-Item.js index dbcb38b..46bfc65 100644 --- a/migrations/20160602030149-Item.js +++ b/migrations/20160602030150-Item.js @@ -13,7 +13,8 @@ module.exports = { }, name: { type: DataTypes.STRING, - allowNull: false + allowNull: false, + unique: true }, measures: { type: DataTypes.JSON, @@ -23,9 +24,10 @@ module.exports = { type: DataTypes.JSON, allowNull: true }, - defaultPrice: { - type: DataTypes.DECIMAL(9,2), - allowNull: false + prices: { + type: DataTypes.JSON, + //type: DataTypes.DECIMAL(9,2), + allowNull: true }, subcategoryId: { type: Sequelize.INTEGER, diff --git a/migrations/20160602030150-Sale.js b/migrations/20160602030151-Sale.js similarity index 100% rename from migrations/20160602030150-Sale.js rename to migrations/20160602030151-Sale.js diff --git a/models/item.js b/models/item.js index 4019eb1..3230ad3 100644 --- a/models/item.js +++ b/models/item.js @@ -22,9 +22,10 @@ module.exports = function(sequelize, DataTypes) { type: DataTypes.JSON, allowNull: true }, - defaultPrice: { - type: DataTypes.DECIMAL(9,2), - allowNull: false + prices: { + type: DataTypes.JSON, + //type: DataTypes.DECIMAL(9,2), + allowNull: true }, createdAt: { type: DataTypes.DATE, diff --git a/models/venue.js b/models/venue.js index 8e76fd9..15fbd91 100644 --- a/models/venue.js +++ b/models/venue.js @@ -11,7 +11,7 @@ module.exports = function(sequelize, DataTypes) { }, name: { type: DataTypes.STRING, - allowNull: false + allowNull: false }, createdAt: { type: DataTypes.DATE, @@ -27,6 +27,11 @@ module.exports = function(sequelize, DataTypes) { } }, { freezeTableName: true, // Model tableName will be the same as the model name, - paranoid: true + paranoid: true, + classMethods: { + associate: function(models) { + models.Venue.belongsTo(models.VenueType, {as: 'type', foreignKey: {name: 'typeId', field: 'typeId'}}); + } + } }); }; diff --git a/models/venueType.js b/models/venueType.js new file mode 100644 index 0000000..4e12cab --- /dev/null +++ b/models/venueType.js @@ -0,0 +1,32 @@ +"use strict"; + +module.exports = function(sequelize, DataTypes) { + //The id field is auto added and made primary key. + return sequelize.define('VenueType', { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + allowNull: false, + autoIncrement: true + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + }, + deletedAt: { + type: DataTypes.DATE, + allowNull: true + } + }, { + freezeTableName: true, // Model tableName will be the same as the model name, + paranoid: true + }); +}; diff --git a/package.json b/package.json index e05ad6e..fc2b726 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,10 @@ "start": "node server.js", "migrateDB": "sequelize db:migrate", "dropDB": "sudo -u postgres dropdb PetitTeton", - "createDB": "sudo -u postgres createdb PetitTeton" + "createDB": "sudo -u postgres createdb PetitTeton", + "import1": "node importAll.js", + "import2": "node importItems.js", + "import3": "node %NODE_DEBUG_OPTION% importSales.js" }, "dependencies": { "bcrypt-nodejs": "^0.0.3", @@ -38,6 +41,7 @@ "serve-favicon": "~2.2.0", "session-file-store": "~0.0.24", "stylus": "~0.42.3", - "swig": "~1.4.2" + "swig": "~1.4.2", + "csv-parse": "latest" } } diff --git a/public/admin/Venues.html b/public/admin/Venues.html index e673010..9ed5f6c 100644 --- a/public/admin/Venues.html +++ b/public/admin/Venues.html @@ -15,7 +15,7 @@ - +
@@ -99,7 +99,8 @@ $(function() { } }; - var dataTable = new LinkedTable($page.find('#dataTable'), { + var $table = $page.find('#dataTable'); + $table.buildTable({ url: "data/Venue/readAll", attr: "data-key-name", selection: "row", @@ -122,16 +123,19 @@ $(function() { } } }); + var dataTable = $table.getTable(); + $page.find('#dataTable').on('dblclick', 'tr', function(event) { if(dataTable.getSelectedRow()) { location.hash = "#!/venues-edit"; } }); - $page.find('#dataTable').on('keyup', 'table', function(event) { + + $page.find('#page').on('keyup', '.page', function(event) { switch(event.keyCode || event.which) { case 0x0D: //Enter if(dataTable.getSelectedRow()) { - $btnEdit.click(); + location.hash = '#!/venues-edit'; } break; case 0x08: //Backspace @@ -144,9 +148,6 @@ $(function() { } }); - //Call the refresh user table function once initially. - dataTable.build(); - //Refresh the data table if the user toggles the button to show/hide deleted elements. $page.find('#includeDeletedToggle').on('click', function(event) { dataTable.refresh(); @@ -247,6 +248,16 @@ $(function() { }); }); + //Close the view if the user uses the escape key and it isn't handled at the widget level. + $editorView.on('keyup', function(event) { + switch(event.keyCode) { + case 27: + if(!event.isDefaultPrevented()) + history.back(); + break; + } + }); + //++++++++++++++++++++++++++++++++++++++ // ++++++++++ Delete View +++++++++++ diff --git a/public/admin/bootstrap.styl b/public/admin/bootstrap.styl index b42e4a7..6c1aa6b 100644 --- a/public/admin/bootstrap.styl +++ b/public/admin/bootstrap.styl @@ -13,7 +13,8 @@ input[type="url"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="color"]:focus, -.uneditable-input:focus { +.uneditable-input:focus, +.list-group:focus { border-color: rgba(82, 168, 236, 0.8); outline: 0; outline: thin dotted \9; diff --git a/public/admin/categories.html b/public/admin/categories.html index 1c6cdde..12cca15 100644 --- a/public/admin/categories.html +++ b/public/admin/categories.html @@ -99,7 +99,8 @@ $(function() { } }; - var dataTable = new LinkedTable($page.find('#dataTable'), { + var $table = $page.find('#dataTable'); + $table.buildTable({ url: "data/Category/readAll", attr: "data-key-name", selection: "row", @@ -122,15 +123,14 @@ $(function() { } } }); + var dataTable = $table.getTable(); + $page.find('#dataTable').on('dblclick', 'tr', function(event) { if(dataTable.getSelectedRow()) { location.hash = "#!/categories-edit"; } }); - //Call the refresh user table function once initially. - dataTable.build(); - //Refresh the data table if the user toggles the button to show/hide deleted elements. $page.find('#includeDeletedToggle').on('click', function(event) { dataTable.refresh(); @@ -231,6 +231,16 @@ $(function() { }); }); + //Close the view if the user uses the escape key and it isn't handled at the widget level. + $editorView.on('keyup', function(event) { + switch(event.keyCode) { + case 27: + if(!event.isDefaultPrevented()) + history.back(); + break; + } + }); + //++++++++++++++++++++++++++++++++++++++ // ++++++++++ Delete View +++++++++++ diff --git a/public/admin/css/jsgrid-theme.css b/public/admin/css/jsgrid-theme.css new file mode 100644 index 0000000..0c99286 --- /dev/null +++ b/public/admin/css/jsgrid-theme.css @@ -0,0 +1,258 @@ +/* + * jsGrid v1.5.2 (http://js-grid.com) + * (c) 2016 Artem Tabalin + * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE) + */ + +.jsgrid-grid-header, +.jsgrid-grid-body, +.jsgrid-header-row > .jsgrid-header-cell, +.jsgrid-filter-row > .jsgrid-cell, +.jsgrid-insert-row > .jsgrid-cell, +.jsgrid-edit-row > .jsgrid-cell { + border: 1px solid #e9e9e9; +} + +.jsgrid-header-row > .jsgrid-header-cell { + border-top: 0; +} + +.jsgrid-header-row > .jsgrid-header-cell, +.jsgrid-filter-row > .jsgrid-cell, +.jsgrid-insert-row > .jsgrid-cell { + border-bottom: 0; +} + +.jsgrid-header-row > .jsgrid-header-cell:first-child, +.jsgrid-filter-row > .jsgrid-cell:first-child, +.jsgrid-insert-row > .jsgrid-cell:first-child { + border-left: none; +} + +.jsgrid-header-row > .jsgrid-header-cell:last-child, +.jsgrid-filter-row > .jsgrid-cell:last-child, +.jsgrid-insert-row > .jsgrid-cell:last-child { + border-right: none; +} + +.jsgrid-header-row .jsgrid-align-right, +.jsgrid-header-row .jsgrid-align-left { + text-align: center; +} + +.jsgrid-grid-header { + background: #f9f9f9; +} + +.jsgrid-header-scrollbar { + scrollbar-arrow-color: #f1f1f1; + scrollbar-base-color: #f1f1f1; + scrollbar-3dlight-color: #f1f1f1; + scrollbar-highlight-color: #f1f1f1; + scrollbar-track-color: #f1f1f1; + scrollbar-shadow-color: #f1f1f1; + scrollbar-dark-shadow-color: #f1f1f1; +} + +.jsgrid-header-scrollbar::-webkit-scrollbar { + visibility: hidden; +} + +.jsgrid-header-scrollbar::-webkit-scrollbar-track { + background: #f1f1f1; +} + +.jsgrid-header-sortable:hover { + cursor: pointer; + background: #fcfcfc; +} + +.jsgrid-header-row .jsgrid-header-sort { + background: #c4e2ff; +} + +.jsgrid-header-sort:before { + content: " "; + display: block; + float: left; + width: 0; + height: 0; + border-style: solid; +} + +.jsgrid-header-sort-asc:before { + border-width: 0 5px 5px 5px; + border-color: transparent transparent #009a67 transparent; +} + +.jsgrid-header-sort-desc:before { + border-width: 5px 5px 0 5px; + border-color: #009a67 transparent transparent transparent; +} + +.jsgrid-grid-body { + border-top: none; +} + +.jsgrid-cell { + border: #f3f3f3 1px solid; +} + +.jsgrid-grid-body .jsgrid-row:first-child .jsgrid-cell, +.jsgrid-grid-body .jsgrid-alt-row:first-child .jsgrid-cell { + border-top: none; +} + +.jsgrid-grid-body .jsgrid-cell:first-child { + border-left: none; +} + +.jsgrid-grid-body .jsgrid-cell:last-child { + border-right: none; +} + +.jsgrid-row > .jsgrid-cell { + background: #fff; +} + +.jsgrid-alt-row > .jsgrid-cell { + background: #fcfcfc; +} + +.jsgrid-header-row > .jsgrid-header-cell { + background: #f9f9f9; +} + +.jsgrid-filter-row > .jsgrid-cell { + background: #fcfcfc; +} + +.jsgrid-insert-row > .jsgrid-cell { + background: #e3ffe5; +} + +.jsgrid-edit-row > .jsgrid-cell { + background: #fdffe3; +} + +.jsgrid-selected-row > .jsgrid-cell { + background: #c4e2ff; + border-color: #c4e2ff; +} + +.jsgrid-nodata-row > .jsgrid-cell { + background: #fff; +} + +.jsgrid-invalid input, +.jsgrid-invalid select, +.jsgrid-invalid textarea { + background: #ffe3e5; + border: 1px solid #ff808a; +} + +.jsgrid-pager-current-page { + font-weight: bold; +} + +.jsgrid-pager-nav-inactive-button a { + color: #d3d3d3; +} + +.jsgrid-button + .jsgrid-button { + margin-left: 5px; +} + +.jsgrid-button:hover { + opacity: .5; + transition: opacity 200ms linear; +} + +.jsgrid .jsgrid-button { + width: 16px; + height: 16px; + border: none; + cursor: pointer; + background-image: url(data:image/png;base64,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); + background-repeat: no-repeat; + background-color: transparent; +} + +@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) { + .jsgrid .jsgrid-button { + background-image: url(data:image/png;base64,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); + background-size: 24px 352px; + } +} + +.jsgrid .jsgrid-mode-button { + width: 24px; + height: 24px; +} + +.jsgrid-mode-on-button { + opacity: .5; +} + +.jsgrid-cancel-edit-button { background-position: 0 0; width: 16px; height: 16px; } +.jsgrid-clear-filter-button { background-position: 0 -40px; width: 16px; height: 16px; } +.jsgrid-delete-button { background-position: 0 -80px; width: 16px; height: 16px; } +.jsgrid-edit-button { background-position: 0 -120px; width: 16px; height: 16px; } +.jsgrid-insert-mode-button { background-position: 0 -160px; width: 24px; height: 24px; } +.jsgrid-insert-button { background-position: 0 -208px; width: 16px; height: 16px; } +.jsgrid-search-mode-button { background-position: 0 -248px; width: 24px; height: 24px; } +.jsgrid-search-button { background-position: 0 -296px; width: 16px; height: 16px; } +.jsgrid-update-button { background-position: 0 -336px; width: 16px; height: 16px; } + + +.jsgrid-load-shader { + background: #ddd; + opacity: .5; + filter: alpha(opacity=50); +} + +.jsgrid-load-panel { + width: 15em; + height: 5em; + background: #fff; + border: 1px solid #e9e9e9; + padding-top: 3em; + text-align: center; +} + +.jsgrid-load-panel:before { + content: ' '; + position: absolute; + top: .5em; + left: 50%; + margin-left: -1em; + width: 2em; + height: 2em; + border: 2px solid #009a67; + border-right-color: transparent; + border-radius: 50%; + -webkit-animation: indicator 1s linear infinite; + animation: indicator 1s linear infinite; +} + +@-webkit-keyframes indicator +{ + from { -webkit-transform: rotate(0deg); } + 50% { -webkit-transform: rotate(180deg); } + to { -webkit-transform: rotate(360deg); } +} + +@keyframes indicator +{ + from { transform: rotate(0deg); } + 50% { transform: rotate(180deg); } + to { transform: rotate(360deg); } +} + +/* old IE */ +.jsgrid-load-panel { + padding-top: 1.5em\9; +} +.jsgrid-load-panel:before { + display: none\9; +} diff --git a/public/admin/css/jsgrid-theme.min.css b/public/admin/css/jsgrid-theme.min.css new file mode 100644 index 0000000..f09f472 --- /dev/null +++ b/public/admin/css/jsgrid-theme.min.css @@ -0,0 +1,7 @@ +/* + * jsGrid v1.5.2 (http://js-grid.com) + * (c) 2016 Artem Tabalin + * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE) + */ + +.jsgrid-edit-row>.jsgrid-cell,.jsgrid-filter-row>.jsgrid-cell,.jsgrid-grid-body,.jsgrid-grid-header,.jsgrid-header-row>.jsgrid-header-cell,.jsgrid-insert-row>.jsgrid-cell{border:1px solid #e9e9e9}.jsgrid-header-row>.jsgrid-header-cell{border-top:0}.jsgrid-filter-row>.jsgrid-cell,.jsgrid-header-row>.jsgrid-header-cell,.jsgrid-insert-row>.jsgrid-cell{border-bottom:0}.jsgrid-filter-row>.jsgrid-cell:first-child,.jsgrid-header-row>.jsgrid-header-cell:first-child,.jsgrid-insert-row>.jsgrid-cell:first-child{border-left:none}.jsgrid-filter-row>.jsgrid-cell:last-child,.jsgrid-header-row>.jsgrid-header-cell:last-child,.jsgrid-insert-row>.jsgrid-cell:last-child{border-right:none}.jsgrid-header-row .jsgrid-align-left,.jsgrid-header-row .jsgrid-align-right{text-align:center}.jsgrid-grid-header{background:#f9f9f9}.jsgrid-header-scrollbar{scrollbar-arrow-color:#f1f1f1;scrollbar-base-color:#f1f1f1;scrollbar-3dlight-color:#f1f1f1;scrollbar-highlight-color:#f1f1f1;scrollbar-track-color:#f1f1f1;scrollbar-shadow-color:#f1f1f1;scrollbar-dark-shadow-color:#f1f1f1}.jsgrid-header-scrollbar::-webkit-scrollbar{visibility:hidden}.jsgrid-header-scrollbar::-webkit-scrollbar-track{background:#f1f1f1}.jsgrid-header-sortable:hover{cursor:pointer;background:#fcfcfc}.jsgrid-header-row .jsgrid-header-sort{background:#c4e2ff}.jsgrid-header-sort:before{content:" ";display:block;float:left;width:0;height:0;border-style:solid}.jsgrid-header-sort-asc:before{border-width:0 5px 5px;border-color:transparent transparent #009a67}.jsgrid-header-sort-desc:before{border-width:5px 5px 0;border-color:#009a67 transparent transparent}.jsgrid-grid-body{border-top:none}.jsgrid-cell{border:1px solid #f3f3f3}.jsgrid-grid-body .jsgrid-alt-row:first-child .jsgrid-cell,.jsgrid-grid-body .jsgrid-row:first-child .jsgrid-cell{border-top:none}.jsgrid-grid-body .jsgrid-cell:first-child{border-left:none}.jsgrid-grid-body .jsgrid-cell:last-child{border-right:none}.jsgrid-row>.jsgrid-cell{background:#fff}.jsgrid-alt-row>.jsgrid-cell{background:#fcfcfc}.jsgrid-header-row>.jsgrid-header-cell{background:#f9f9f9}.jsgrid-filter-row>.jsgrid-cell{background:#fcfcfc}.jsgrid-insert-row>.jsgrid-cell{background:#e3ffe5}.jsgrid-edit-row>.jsgrid-cell{background:#fdffe3}.jsgrid-selected-row>.jsgrid-cell{background:#c4e2ff;border-color:#c4e2ff}.jsgrid-nodata-row>.jsgrid-cell{background:#fff}.jsgrid-invalid input,.jsgrid-invalid select,.jsgrid-invalid textarea{background:#ffe3e5;border:1px solid #ff808a}.jsgrid-pager-current-page{font-weight:700}.jsgrid-pager-nav-inactive-button a{color:#d3d3d3}.jsgrid-button+.jsgrid-button{margin-left:5px}.jsgrid-button:hover{opacity:.5;transition:opacity 200ms linear}.jsgrid .jsgrid-button{width:16px;height:16px;border:none;cursor:pointer;background-image:url(data:image/png;base64,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);background-repeat:no-repeat;background-color:transparent}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){.jsgrid .jsgrid-button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAALAEAYAAACFny30AAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAA6CUlEQVR42u2dZ2AUZRPH53rLpVdSKSGhgwoIqIgKiBRFBGwooQjoC9KbSEdFqoIiNhDBQhdEQBABIShNCCUhpEF6T+5yuX77fhgejhwc6dkE5/dl2LvN7uz8n/4cOwAEQVSCmJjOnZ97bunSK1eeeWbo0G7d+Pbn2rWBA8eMmTnz8uWuXQcPfughvv2pLMKKnpiY+Oqrs2Z16lRampwcGzt6tNlcWFhQMGwYX45nZCxe/O23kZEazb///vPPuHEWS3FxQcGrr/LlT62RlBQV9d574eGnT/v6tm6dkREdDRAUxHHR0WJxSAjHXb3ar9+wYcuX15U/WVkrV27e7Od35kzjxg8/fP36iRMA3t4cd+qUUNikCcfFxHTs+Pzzc+fyHbdqk5T02muzZnXu/M8/Xl6RkXl5p04BNGnCcefOAXTrxnFnzgC0a8dxJ08KBL6+HBcb26/fsGEffVRb/mRmLlu2aVNk5JkzjRq1b5+WdvIkQKNGHHf+vN2f9u05LjpaIAgO5rhLlzp1euGFOXP4jmN5CBw/SEgYMWLq1CefzM/fseOXX7Zv57jiYgAvL4kEwMsLgOMATCYAgQBAIgGw2QAMBgCTSSjMygLw9OzXr3fvFStatNizZ9OmqVOr62BW1sqVW7YEBNy8+ckny5YdP26x3LiRnd2smUwGEBZW1h+RyH5sNgsEGg2AQhEZ2bTpqlVisYuLu/tPP7VufebMtm2nT/MdeMZdfYBQqFZLpX376nTFxdeve3mJxQCurvgdx9nP4zgAiwVAKASQyQCkUpvN3x+goGDv3gMHpkyJje3b9/XXP/64qo5hiW/VKjV1+fJly86fN5tv3MjJadZMLi8b+Hv5o1IBWK0cp9EAGI0aTVrapElicWCgi8srr/Ad8HIF8PcfPjwqatas0NBRo2bM+PjjkhKACxewpBuNWNLE4rIPbrXig8vlAFIpx6EQ+/cfPjxtWmzsc8+9/vqqVRV1iJX41NS1a1eu3LPHbM7IyM7295fLAUJD0Y87A3/7QW7d32AASEkBkMmCgwMCCgsbNRo1auzYHj1cXTt16tp15ky+A+6IoLwTbt6cNu3DDxcsSE5etmzevLlzFQqA5s2xuqtUKIDZfOtiAntTwAQzmQSCzEwAT88+fXr1WrGiRYvfftu8+e6mCQPPSvzhwyZTRkZOjr+/QlF+4KVSDPzNmwAiUXCwWp2bGxIyefL06U8+GRAwadKIEVev8h1oZ5Q7DA0JWbZs1qx580JDp02bM2fx4tJSgLg4DIheb+8LGM5rxIEDhw9PmRIb27//G2+sWMHOz8xcuvTrr93dU1PXrFm5cu/eypR4mcweeLE4MFCtLiwMDn777cmTn3++vgeeUW4NcOTmzVmzli9fsCAp6cMPZ86cO1epBIiMvH+NEApRFKMRwGoVCktKANTqDh06dPjsM7M5MzM3t1s3vT4jIympfXu5HCA4uGIlPiUFS7yra05OcPC7706b1qNHo0ZTp44aVf8DX2UBGCkpU6cuWLBoUUrK8uWLFs2Zo1IBtGyJAVIo7J3i7Rvd0TSZzSiIRmOvQRIJgLu7/fvyAi+RhIZ6excUBAWNHz95ct++AQFTp0ZF/f033wGtMwEYWCPmzMEasWhReTWizM1vHd85unKEBV6vB0hKApBIGjf28cnODgubO3fBgu7dfX2jogYNunaN70BWlQovRTgjJOTDD6dOXbw4LGzmzPnz583T6wHi48v2EXeOmu6kIoE3GABu3ACQSkND/fwKCsLCZs6cN+/55xt64BnVrgGOpKUtWrR27ciRaWmLF69atXatSGQ0qlRyuUCAAQW4f+AZVitASQmARBIR4eV17lxQ0JQp7777yiu+vm+9NXTo9et8B66mqHYNcEShCAlp1mzrVrHY3d3VtbCQ1YTKIBBgDSotBVCpGjdu3/7IkQct8IwaEyAjY8mSb75p2zY5efbs9967csViyc4uKQkIEIsBPD3xnIqUfHaeWAzg7Q1QWPjXX4cOvftufPzAgW+/PXEi3wGraaotQE7OmjU//RQUlJb25Zdr1uzZYzKlp6enBwdLJBh4Ni+4F4L7NICsDxAIdDqxWCrNzd29e9euVavi44cMGT9+yhS+A1dTVLkPSE+fO/fzz9u1y8zcuHHDhoMHjcabN9PT/fzKm7my4ajVCqDV4rFcXrazttnufb5Oh4tseXkAvr6DBg0ZMmVKePj27WvWrFzJdyCrSqUFSEoaPXru3NDQ3Ny9e3fuPH7cZsvKKi4OCZFKAYKC7l4kuzOQYjHODQoLAQQCmQznBUaj0Yjfubvbz3OsOWy+wIQzmwWCggIAH5/Bg196aebM5s23bl2zZulSvgNaWUQVD/ybb86e3aFDbu7u3Tt2HDtms+Xm6nSNGkmlAI0alR3v38mdw8mkJACpNDw8ICA9PSho8uQJE558Uiz28XF1LS4uLLx8+dChbt3EYgAPD/w7xxphs9mXIJhQWu3Vq2fOPPPMrFlDhowcWVKyZs2VK//8c+oU34GtKOXWgKSkkSPfey80NC9vz56dO0+csFpzc43GoCCZDMDXt2Iz1+RkALE4JMTbOz8/LGzevLlz+/Tx9R05csiQM2fY+deuvfrqmDE//piV9cMP33338ssqFUCrVvalDI67u2m6s0ZYLCJRYSGAt/dLLw0aNHNm8+Y//9wQaoRTARITX3tt1qyHHsrLO3Bg1679+zkuP99k8vWVSDDw5ZX4O2eu3t6ZmWFhc+YsXNi9u6/vyJGDBjkfTl6/PmzYhAkbNmRkfP/9+vXDhyuV9iUOiaTsEsedq69WKw5bLRahsKgIwM2ta9cuXaZPb9XqxIlt25Yt4zvQFRYgIWHEiGnTHnssL2/Hjt27t20DKC4G8Pe/c0esciV+1iws8ePG3VniyyMubsiQUaN+/DE7e+vWzZsrViPEYvsM3GJBzxWKVq0iIpYulUhUKnf3rVtbtTp9euvW8+f5DvztuN0dSFdXieTFF3FHzN9fLAZwc8Pv2APfOZ53LPFicePGXl4ZGWFh8+cvXPjoo5UNPCMycuvWr79+5ZVGjYYNGzPm2291OoDLl9EHi8Ve8pk/rGCIRABqtb1GGI2FhampM2YIhQEBSuWbb/Id8HIF8Pd/883hw2fMCAsbOXLGjM8+0+kALl60t/WspDmWeIkkJMTHJy8vLGz69HnzBgzw9R0x4sUXExKq62B4+Pfff/LJyJF+fkOGDBu2ZUtpKUBsrH2UdKc/bH/gxg0AmSww0N9fqw0IGD581KhevVxdH3740UdnzeI74JUmKWncuPffX7Hi6FEAiYTjzp4F6NiR46Kj8VcJp083btyqVVpaTs633+7c2aRJbfuDfcTXXx87BiCT4a80OnfmuFOnAEJCOO6ff4KDIyIKCjIyPvxw/foOHfiOX42RmDhy5LRpq1cfPgwAwHGnTwcFtWqVn5+dvW7dtm0PP1zX/ly7NnTo2LGbN//xB/rzzz8BAS1aaDTp6QsXrl37+ON8x6vWSEqaMGH27A8+SEv76KPPPuvShW9/rl2Linr77c8/T0mZPHnBgl69+PaHIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIIga4q5XF7drt3r1nj2PPYZHLAVh8+ZohcKytqI5MerscW49z53vWwfAtEIAAJMmXbw4ceKAASdO8O0pw0l+o9270Xp5oWVv8s/ORssCX5m0PLUJCzzLXMCO/fzQPvJI2efy9ubXXztOBGAl5Pnnyz7YBx+gPXQIbVAQ2jtfo80HrEampaHt2RMte2u6QlH2ueoPTgRgqcp37Cj7QC+8gPbIEazKR47w/QAMbDpbtCjrJws8KzD8pWB3htP8AfhArApv24aWvRI4MRFt794oBDuue9DPpk3x6OBBtOz4r7/QDh6MfrImtP7gNItSWYfHjEHL3rvPHnDnTgyAj09dO172vjt3lvWL+TlmTH0NPKPcNFb4ALGxeDR+PFqWAaNtW7Rbt2JAZLLadrjsfbZuLesH82v8+LJ+118qnEcMHyg6Go8mTUKbk4P2ySfRbtmCAWJtb81R9rpbtpS9L/ODDTOZn/WfSidywwfctw+PWGZsgwHtoEFoV6/GgMnl1XWw7HVWry57H3bfqVPL+tVwqHImPXzg77/HI1Yj2HzgrbfQvvdezbjJrsOuy+7DSjzzo+FRY9lUsaTOno1HS5agNRrRLl+O9uxZtGwC5ww272ATKFbTWNv/3nsYeDYvabjUeDpbFIItYTgm3ywpQVteH8Hyr7q4lP189WoMPKtxDR9x9S9xL2bMQMsCOGoUWhb4lBS0jjNoNqMNCyv7+ddfl73ug0ON5xPGEsqakD17yn7LlgL69EHLUqAwyz53XDLYs6fsdR8caqkGMBwT1rLOs6AAA5qfz77BpsvxPGfXeXCo8RpQFsfAsdRrzrLMs89Fovtf58GhlgUgyoME4BkSgGdIAJ4hAXimjgW4V0Lc/za1LIDjcJNNpEpL+X7w+kItC8ACzkp8y5ZonSUBZcnK/zs1pJZnwmz1k22QdOuGdv16nPn++ise79qFNiYGrVbLd2DqilqrAbjUkJmJR++8gxaz/wI0boyWbXH+9BPazZvRtm7t4OYDO1io9QdDIS5exKNXXkH78stoWcn39UX77LNoQ0PLXqX295r5grc1FmyC2HI1C/hrr6FlAl27hvbtt1HI5GS+/CUIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiB4otbfmHX2LMDDDz/1FB69+ipa9lZEsxkteycce2v67t2PPAJw7lzDS8pTWWr5rYkMlo21a1e0LPuRowAst0xCAtoHX4C7agCW2IcewqPISLQsjRQLWHk4ZrpYtAhteHjF/j43F+20aWWvJ65ggWE1ib2p9/JlrFEsw179wckD/fAD2ogIftxiKQo3bqyZ67GX/7ECVX9w8trKms+Exy/193mc1ICxY9G2aYO2qAgta7udpRRhiZJZJ5uXV/Z81iSwgLCSzs7T6dA6vqiVJZZmTQs7n13PWaoU9j5S9kbe+ofTURD2BSwQrBN1bFvZg3MctrGxsfh3rM9g2U0dA1NcjOffuIHnBwTg5yx9ruM7pFNS8HydDs9n/rBOm2X8Zv4wGx+Pf1fRvqvuKadTe/RRtCy/ESuJLNEaCyjHYWD69y8bOJZImWXUY2/AZZ/36oV2xQq07M26LGASCdpXX8Xrs9HR0aNoWU1iNdNxODtgANr9+/kOtDPKEcAxhzzDWZvKmiCWqI3h+Ophx2PHrEks8AyNBi0rAEplxfypv3mEGeW8O/rmTbSFhRW7nKsrWtZGs8A5UtG0VGz4yXLFq9UV+7usrLJ/V39xKkDZtpO9Bb08WAllTQJrqqoKa7pYDkp394r9HZtHsL+vv1Tw7ekVFcDTEy3LkFHdPADsOqwGenhUzt/6n/qwhgVgAaopAdiwlAng5lY5f1lNrL9UUADWppaHqys2XazpqX4NwOuxQQDrY8r3t+zf1V9qXICyx8464YrimOynogKwHPP1nwoKUNHhnGMnWVxcPfdY58twHH5W11/+qWQf4JiA2RE2A2ZUtwY4NmEV7QNSU2smPLVPJQWw5/+9N44ToorOH5zh2AQ5pjh3hA07q3vfuqOCArDhXHlV27EGVHce4FiDymuC2ATQsemqv1RQAFayyhNAKsU1GzbTrW4gHPuQ8gRgE7AHVoDyRkNsjYetCVW3DygsREHZ/EKluv/5rIBU9751R7kC4Hiadb4ZGfc/mwnAliSqLwBaNroqT4CcHPS3/i9BMCqZyK38JghtTQnANoLY6KeifUDDoZICsDbWGWxZmTUZ1Z0JMwHYKqjjMrUjFZ0w1h8qKUBFl3dZk8E60cqOhtgqbEEB2oouQ9f/5WdHKikAq+LlbfGxGsBKcGXzB7M2nNW4igrABGs4VFIANrwrr61lNaCiAjhu0DCBWSdcngCsrylvolj/qKIA5fUFHh44GmGBdwyMY8Adx+0lJfj3rAkrbyOGCd1wZsCMSgrAOtXyBPD3L3vs2Aew0RLDsXN1bOLYqMoZLPANrwmq9I9zcWLEfjnHfsXgCAtEfDzatm3RsmEkK/FXrqBlv1hjw03WB7Df84SEoGU/W3Hk6FGsMT168BnMqlDFH+eWVwPY1iT7WYsjbFGtc+d7f88mdB07Vswf1gQ1PKooAMuQzYRgM+TylqtrCvb7H/bLt1On6ua+BEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQBEEQDZB27Vav3rNn3jy0o0fz7U9lqfWEzrUFBnzDBjwaPrzstyNGXLw4ceKAAez7+kuDEwADz9Lcvvnm/c+u/0LUewEw4Oxti3v3omUp0itK/RWiku8NrXswcOwFsMHBVbvKt9+ikFFRfD+PI/VWAAzY0qVoIyNRCJbG9vDhql21/glR75qge3eu7M24ISEoREkJnsfS4j7zTNXu9vbbeL116/h63npTA+4/qmFvY79+Hc9zccHA9eyJn1e1RnTpwvdz8y7A/QPvCHsndXWFOHAA7aRJfD8/b01Q5QLvDJYxIzy8Yk3TgQN4Xp8+fD23I3UuQM0E3hFnQly9ip9bLPg5e4l4/aHOBKidwDvCkgyxJom9nZ0NZ+vq3dYVp9YFqJvAO/LjjxjwV1+tm/tVnVrrhPkJ/MGDaN96q27uV31qvAbwFXgs8c8+Wzf3qzlqTAAKfNWodhPET+DZcLLhBp5R5RrAb+Drzzi+ulRagMqtx9cUD17gGRUWgAJfOzgVAAPO8nt99RVaCnxNU04nPH8+Wgp8bXG7BmCJZwmTLRa0CgXaEyfQtmpVO2789wLPcKgBLOCXLqH19cXAtG5d9vOa4r8beIaDAGzzOzwc7bVrWDOYEGw1sbpCUOAZDgK0aXPv01JSakYICrwjDgK0bHnv01jTVFUhKPDOcBCgvE62PCHi4sqe//vvFPj7I8BAsgTLf/+NtlOnyl2GddLJyWgXLsTAT53K9wPWd27VgNBQtM76gPJge7BWKwW+ctxKZ9u9O1rWxLCEygkJaK9fR3v5clnLPmdpbcXisn9PlMetgLHN67Fj0f7zD9rERCzRLJU5QRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRDEf496l0mP0anTtm0LF3755enTqamXLr38skCgULi6lp+Eh+MAAAQCgOLi7GyBYNmyPn3Gj58xY9q0du169+YvY54zxHw74AyRSCgUCn19AUQiiUSt5jiRSFwpb4VCiQRAJAIQCt3d+X4eZ9RbATiO4zhOpwPgOCz3HIelu+JXsNmwRnCcwcD38ziD91SG/3VIAJ4hAXiGBOAZEoBnSACeIQF4hgTgGRKAZ0gAniEBeIYE4BkSgGfqrQAWi81mtQIACASCertrUX3qrQBubjKZUslxAFYrS6xYOXA5WqkUi6XS8jdy+KLeChAcrFJ5eOj1AFar2VyVK+AGTm6uwVBSUn9TsAgefXTbtgULvvwSQCgUidzdceOjao9cfTgOS6zFEh+v1ebmPvFEWppWm5/fuDHujFXmWlhzwsJcXb29z55t1kyt9va+eLGkxGw2GlmyorrHYrFYTCaZLCDAxcXTMy5OALBixeDBHAcgFuOWX2V3nmoamw0bDJkMM1tKpRgu1idUFIFAKAQAMJlKS9HivphQKOS13qMfKpWbm79/ZqZYIFAqXV2Li3HP1c2NfwFwSx2AbbBXNvAMtpUpkcjlaFm55/f5xGKZDMDLS6FwdU1Pr5d9QG0FiO+CdS9/6qUA/yVIAJ4hAXhGaP8lGVGXsLiLAYqKsrNdXe3DUJuN784K769S4e/ZZDKVCv2q3GhIKMTn0emKigAAjMaSEvyG3+JmNhsMAKmpAAJBcLBgxYoLFw4eHDcOQCgUCHAiBlD3vyQTCgUCgYDjpFKhUCw2mb79Njb2r79Gjjx3LiMjLu6hhwDkcheXylzRYNBqAZ5/PiLiscd++aVXr6Cgli1//91gsFrNZpmsrp+PgWtccrm7u1Qql6ekiKdMad++Pv5o9Z13jh797rs2bc6dS0w8c6YqApSWajQAgwc3afLQQ9u2vf568+ZdumzZwvdzOVJvO+ErVwoLMzNdXQFksqotHGATlJ2t12u1vr58P49TL/l2wBklJdhW4hoV397UHvVWALGYBZ7/pZHapN4K8F+BBOAZEoBnSACeIQF4hgTgGRKAZ0gAniEBeIYE4BkSgGdIAJ4hAXim3r4rQq+3WEwmT0/7L9rwB00VB//ObLbZrFa1mu/ncUa9FSAkxMXFw+Ps2cxMd3d//+BguVwuV6v1+vL+ji1dl5QIBAKBQuHuLpMplQkJfD8PQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRANl1pPZ9O9+65dH30UEXHpUk5OYuLhwwUFJpPBoFIJBBKJXG4wsJQ6HFdSUlioVLZp4+0dGpqYOGlSly4vvfTMMyNGNG/epUthId+Bqi1q/Y1ZAoFAIBDI5ZgJIygIQCQSiQA4jiVoYDmN8FggABAIwsLw3w9y7oxbT13bN+A4juM4kwn/ZTDYM2I4swAcp9FwnD0d54NMHb01kZXyimbw+u8klqPXVvIMCcAzJADPkAA8QwLwTK0LgOP6yv+dzfZgJ3Bj1LoAZrPNZrEA2Gz21wrfTxAc/wMoFGKxVMp3eGqfWhfAzU0mUyrz8hQKgUAotNnseYEdZbDZbDYAFxexWCo1m195pWnTRx4pKOA7QLWNuHv33bs//LB5cwAAoVChwBmpyYRfV31ChPmBLRa1WiqVy5s0EQgEAuEtue/dtEgkUilAfr7FYjZLpaNHHz363XcdOsTE5ObeuKHTyeUSiVQqFjv764r5w3FGo8ViNstkHh4ymUKh0ezb17//lClJSbwJcOlSVlZS0rFjuEbj61tTAuBajsViMtlsVqtYXFwsEAgEMpk9Q7ZjG69QqNUA8fGlpcXFISHp6VevHjt28qRSKRZLpVhrOE5c5bUrXJPiOJvNbDaZZDKVSiZTqWJj8dtWrXgToKDAbDYYXFwAbDaRSCjEwMjl1b80xwHgG/9RRizhzksw+1woFAoBdDqz2WxWKHQ6kwlfWl/d5QmBAK9gNptMACaTUCiR1MRzVg8xLgtrtbg66eJSm+lj7Ytt9/8eqenwMAEAhEIApVIikck0Gp2udp61ooixZHFc7S+AVVbWmvbHcUGwfiz4iXEjxMfHnrm6pmoAW0wWibDlVird3Mp+X/Y+rJNmf6fT4TaMzYbn2Utw1WB/b7EYjQC5uRaLxeLtXfshvj/itm29vYOD4+Jw+8PTEwNjNjOnK3tBFlSZTCgUiYzGkhKbzWJRqeLi9HqNJjDQHui7/9JqBRAIOA7Aao2I8PBo1Cg9XaUSiSQSk8lsttlsNomkegJwHMdZLCaTVCoWy2QqVUrKv//yK4Bg48b4+OhoDw90UCLBEFZdADbh8vZWKNRqozE3V6fTaiMjZ878889vvjl+PDfXZNLrlUo26rFTUlJQANCmjZdXcHBi4gcfPPXUiBHduxcVGQw6nUZjtXJcdQRgG59mM8dxnFSqVAqFQqFe/+qr4eGPPqrR8CWAePjw5s27dq29Pdfnntu7d+XK7Gxs4gQCAKEQmyTHeTE2STIZbkRqtSaTXp+ZOWxYeHjnzg/uzlitz4SzsvR6jcbV1WJhUzEcZt4NfmsycZzNJhYbjVarxeLuzneAaps6WIqQSpXKso1ZRTr5+jFGqX1qXQCb7b+wtV51aD+AZ0gAniEBeIYE4BkSgGfq4LehbHkBlwLsazJ2y860f85xbObKd4Bqm1oXwGCw2cxmmcxiMZtNJrmcrccD4LKwXQCz2WgEsFoxj7DZXL2lh4ZCrQvg4SGVyuU6nYeHTKZSxcQIBEKhRCKVSiQSiUxmNLJyr9GYzWazUuniIpe7uKSmymQikUTC1qQIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiAIgiCI/yx1/oLgggKtVqsVCvV6k8lkCg52dVUqlUq1mr24DN+0a7PpdEaj0VhQEBDg4eHpmZXFd6Bqi1oTICenuLioyNs7K6uwsLBw4ECdzmg0GHr2LC01Go3Gtm0NBpPJZGraFF9eJhbfKQBmELDZbDaNBrMnXb8uk0mlYvGZM35+bm4eHr/80rSpv39AwIEDfAewutSYAHl5Gk1xsb9/YmJWVlbWlCnFxaWlJSWjR5tMFovV6uYmFAqFAgGASIRvSReJ8C3qjhnz7C/txrfJWa2YQYmdhwmiAcRioVAkunzZ29vV1dX1888ffrhp0/Dwdev4DmhlqbYAV66kpt64MXbszZt5ebm5H31ktVqtVqubm1QqFkskGCjMzVSzjmMNATAazWazGUChkMmk0jNnmjcPCAgM/N//QkJ8fHx9T5/mK7AVpcoCREfHxV29unFjfr5Wq9G8+SYLuEQiFmO6tfvlomFt+qVLaDMy0BqNaF1c0DZtirZ9e7SYFutemM0Wi8UCoNfjazFbtgwKCgmJioqICAwMCtq4ke9AO6PSAhw9euXKpUt792o0Op1O16+fUimXy2T4DlCWj+luNm9G+/33aI8de/rptm3bt2cBd84ff8TEXLjQqBEe9emDdvRotJ07336QW09isWDNuFOI4ODx48PDAwICA9eu5TvgjlRYgDNnEhLi47/7LiOjoKCg4I03XFzkcud5vv7+G+3kyRjoU6dq2nEUZvhwPFq9Gq2bG8vearFg38GEaN8+LKxJk0GDQkN9fHx9d+6suxDfn3IFSErKysrKGj48JubmzeTkDRtcXGQyuZylBnQ8++uvMeCshNY+KETjxnjERkXNmzP/TCZsmrCJ4rju3Vu3btMmMNDVVaFQKjMz68pPZzh9eTcOFz08rl/PysrIWL9eJsM2HpNiOp79zTd1HXgG3jc5GY86dUKbksL6IKmU9UkAAALB1aupqTdvbthQ1346w6kACQlZWRkZ8+cbDCaT0SiVymQSCUtyZefffzEAo0bx/SDoR3ExHvXujRYHrxwHoFLJZDIZQE5OUVFRUe/e2dlFRYWF3brx7fddAuh0BoNe7+aGE6hx43Ai5GxU8/rrfD+AIyhEfDweLVzIPnecX6Sm5ufn5c2axbe/dwmQlpafn58/ZIjBYDabTBKJRMJSEd7J9u34oFev8v0A92fxYrQFBazwKBRYk/PzNRqNpm9frVav1+vZKKvuuUsArVavLy197jmhEGesLMV4WerfcM4RLCCYuxtg06bbDyzEiSEmdgbAecyzz/Ll520BNJrSUp1OLMYS0a6dWCwSYXLPO8nLQ3viBF8OV439+519U1JiMOj19vlEXVOmBggEgYFms9VqtQYH33u0c/582ZLVULh8GS1LHWFfi9LrjUaTqVkzvjy7LQC6o1bj+NlZ6nD+x81Vg+XKzM6+81OBgC1/l00rWpfcFqBiWYTLXzqon7Aae7f/LNc8X57dUQMEAqGwvKSDbJGsoYHZ7AFcXR2/4bj7LxvWNrcFwB2q3Fxcf9fp2JpKWdiUv6EREIDW15d9UnZfITeXL89uC4AbG7m5CoVUKpMlJ7PFrLJ06IBrL2WTk9d/HnnE8RObDVdNlUq5XC7nbz5z1zzAw0OlcnH5+2+z2Wq1WBy/Zeuf/fvz5XDVGDz4rge/tUPn5qZUKpV//cWXZ3cJ4OXl6urqun07wP1y+k6ZwpfDFQVranAwHj3/PPvcYrFarVYArOlFRV5earVaffgwX37eJUBgoKenl9fBg2q1QiGXp6WZTLjlV5b27fEBX3mFL8crBpux46xGIGB9HYCfn7u7h8d338lkEolUajDw5aHT1dDGjX19/f3nzjUYcD393p3yN9+U3bHiH/TnjTfwaMAA9jkr+TKZVCqR4PP5+S1dyre/TgUIC/P19fPbsMHbW61Wq2NjS0uNRoPBcSNGoUB7/Dg+uLc3Xw+C9+/VC4+++459znFYgKxWpVKpBGjdul279u3fflulksvlcv4nluVmU23dOiQkNHToUJsNF+XYDlPZGsE2z//+GwPRpk1dPQDeLyoKjw4eZJ9zHJZ4qTQ4ODgYwGC4fPnyZQCN5ueft21jPwbgnwrvCd+8mZubk/P66+fOJSUlJHz/vUqFW5M4jnZcNWX/mjcP7dq1uIbElgSqDgY8MhKP5s9HO3So/c6sqQkKCgoCsFgKCvLzAWJjhwx55RUAgyEpKSnJYOjR49NPP/100KAOHaKioqJ++63eC8BISsrOzsr63/9iYm7cSE5es4ZtVdp3zO41r8zPR/vzz2jZ6mRMTNnvWXevVKL180PbpQvavn3RDhp0y/3b/uMPGgHk8tDQ0FAAkykrKysLICnpf/8bPx7AYIiLu3YNgOPUarUaoLQ0Nzc3F6B793nz5s176aVHH50wYcKEHTvqvQCMtLT8/Ly8QYNQiO+/N5stFqtVoWBbf2w19f6TfBZw9jshtlrJljyYAPdw/FZfxH6GYrFgAdDrY2IuXQIoKPj00zVrsMQnJwPIZNgUMdFMJq1WqwXQ6bKzs7MBnnxywYIFC158sXPn8ePHj9+1q64EqHJG7aAgLy9v7x07nniiRYvWrVu3Dgjw8PDw2LULN/MBSkqw02YzznvD8gWz8TrrS5wHno1mNJrS0tJSAI4TCoVCgyEyMjAwKGj2bKXyyJE//9yyJT09Ojo6GkAqDQnBq3Mc9mOsb3BxcXEBUKl8fX19AY4cmTNnzpydO8+f//rrr79+6aW6EqDGf5ybmVlYWFDQu3daWl5eXt5bbxUUlJRotX37Yuctk7G+gq3Hs87csaawpoz9BJHNXFUqqVQmy8ry8XFzc3P7+efQUB8fP7/Vq/FX1ikp7O9/+WX06NGj9+27fPmHH3744bnnvLwiIiIi7Dti7PoCAdsh02g0GgCDobi4uBigT59PPvnkkzFjWrceOnTo0C+/bDACOKLR6PWlpWFhhYVarVb7xBMlJQaDwdC5M/5aulkzDIS7O2tS8HcMNhvuRWdlYZN27RoG+ORJT0+1Wq0+ehR/LKDVlnf/AwcmTpw4ccuWs2fXr1+//tVXvb0jIyMjAYRC3PFjQrDj0tKCgoICex/Rv/9XX3311ZgxrVsPGTJkSM0LUef/P4AvDh6cMmXKlE2bTp/+7LPPPhs2zMenRYsWLe4WQiDAY4OhsLCwEECny8nJyQHo12/9+vXrx45t0+bll19+ef36mvKryn1AQ6N37xUrVqx4441Ond555513Nm/OzY2NjY0FsFpxqYU1RayPUCg8PDw87H3E/v0TJkyY8MUXWJOmTq0pv/4zAjBQiGHDunadPHny5G++KShISEhIALBYDAac6bP/t4BCyOUohELh6enpCXDw4KRJkyYtWxYdvXLlypXvv19df/5zAjCefvqDDz74YNSoxx6bOXPmzE8/tQuBozjHGiGT4fzBzS0sLCwM4OjR+fPnz1+4EIWYO7eqfvxn+oDyOHZs0aJFi9asOXHio48++uh///PwaNy4cWMAsVihUCjsEz0mjNms0+l0AFotTvi6dZs+ffr0BQsef3zmzJkz2Qy9fEgAB44f/+CDDz745JO//lq8ePHiCRNYiZdKVSqV6m4hLBa9Xq8HKCq6cePGDYCHHho9evToTz559tmVK1eunDixvPuRAE44ffrzzz///P33Dx2aNm3atIUL3dxCQkJC7BO4u4XAPsQuxKhRo0atWYNCTJjg7D7/2T6gPDp1evvtt99etKhXr+XLly+fO1ejSU9PTwcwmbDpsfcRKIRYjEswHh5YY86eXbdu3brx42NitmzZsmXcOGf3IQHKoWPHcePGjVu0qGfPjz/++ON584qKkpOTk+0zZzZvYPMIkQiFYE3W1avbt2/fPn68s+uTABWkY8exY8eOXbiwX78vvvjii8mT2QTNYMCZM5vQsRm91YpbnyhIaSnf/j9wXL68devWrWPGLF3q6enpyXFLlqhUKpXdss9TUo4ePXqULaPfDXXC1eTmzejo6OjevS9c2LBhw4a33mKfd+gwYsSIEV9+GRzcpUuXLvadOoIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgCIIgiEpQY++Mi41NTb15s2lTtVqhUKmaNJHLpVKJRKGwWKxWi8VkSkzMysrKSklxcVEo5PLk5HbtwsKaNGmo6XFrjioLcP16RkZ6upubTmc0Go29emFChiefxKxKERESiVgsFstkVqvVarWazRqNXq/XJyS4u6tUSuWpU5hIeffujh2bNYuIqH52pYZKhQWIjU1PT00VCjEnzDvvZGTk5+fnT55ss3EcQFgYy76K+S/uTBCNSXMwI4Y9FQl+mp6O53z5ZUiIt7ePz8cfR0QEBgYH85dasK4pV4Bjx65cuXw5MNBqtdkslp07MUlPp05SqVgsFmMuGJGInc3y8rL0sCw9lVqNAW/bFmXx88NUJQBmMyaGwyYrNrZRIw8PL6/hwyMjg4KCg0+f5jtAtY1TAS5cSE5OSvL1xaQ8hw5hyW7bFnO3AOA7YmNj8ZW9LGnmzz9jwjYWeDuYgM3DA4/69sX3y06ciLXh4YexCQMQiUQikSg3t1WrkJDQ0MceCwnx8vLxiY/nO1C1hVMB/vzz8uWYmL//1ukMBr2+c2elUiqVy1nGvC++wLMmTcKAV73JQGGWLMGsSrNnY5Iflm725s2OHcPDw8Pbt3d1VSiUygevr7jr3dGJiVlZGRljxxYV6XQlJZ07KxRSqVTKAv/llxjwceOqG3gGXue99zBd1eLFLBGcVqvXl5aGhCQmZmZmZFQ9Q0V953YNKC7W6UpK1OqzZxMTr19PSMDMeL6+mKIwPr5HjzZt2rWLiKhth44ciYm5cOHwYcw79vTT+KnF0rFjeHjz5k2aeHmp1a6uqal8B66mEGZmFhbm54tE2NY/95zBYDZbLL6+OIxkeb2WL68rh7CTnjdPKsXUhEaj2Ww2i8WFhSUlJSUvvsh3wGoaIY7bGzfW681ms/mpp3Dczr5mbS5LwllXREfjqCk2ViQSi0UigLw8rba4uHt3vgNW0wix7W3cGHM0NmtWNmHzhQvYRms0deUQ3o/NIi5fZikPjUaz2WIJDT17NiEhPt4+8G3oCPEBVSqRSCAQCuXysl8XFPDrXk5O2cTRmIsS4AESwGKx2TjOaLRaOc5mY+lkGSytLF94epY9tlhwjm1vJBs6QoPBZDKZkpI4zmbjuOTksk1Qhw44Tlep6tox9KFNG6sVlzikUpFILMZ5QUTEAyQAhjslRamUy+XykydFIlyrQXx90T77bF05hIK3a4dNTatWFovVarMBeHqq1S4u0dF8B6ymEYaF+fr6+RmNmCZ2504cfhYV4TyAJaWZPbuuHML7zZ9vMplMJpNAgK09x/n7e3h4edV9yvHa5vZMuFEjDw9Pz8JCDw8XF7V61SqDwWw2mVhT8NBDWDLnzastR/7449KlixfHjrXZjEaT6YUXbDaVSqkEaNasbdu2bT//3M1NqVQqr1/nO2A1zV1LEU2a+Pr6+S1d6uHh4qJSXbtWXIyp+jAT9fz5KMTChTXlAF5vzBibzWAwGNatE4sbNfL3BxCJSkv1eptNJDp16u+/ay+jNd84XYzLyCgoyM9v1+7ixRs3kpOPHbNYLBar1c3NxUUuZ4tyAAcO4Goomyn/9ReO4x1HU3Yw4F27YlMzfrzNZjKZTC+/LJUGBQUFAYjFbm6urgCXLvXu3acPx5nNV65cvXrhwkMPzZw5c+aAAV27Tp06dWpaGt+Bq3UBGCkpOTnZ2eHhyck5OVlZu3drtaWlBkPLllKpWCwUAkilYrFEwtruK1dQmGvX8K8zM9F6eWFTFhGB33foYDJhImWOUyqVSgCBQKPRagFSU+fMef99AJMpJubSJQC9HmfCcrlarVbn5HTqNH78+PG9emGqwYsX+Q5grQvAKCjQarVaT8/ExKyszMxZs3C1dMwYvd5kMpnUapFIJBIKcYNGeKthE9xxdbbEwXbOZDKRSCw2mcLCWrVq1WrNmuzszz77/PO4uJMnp0yZOvWrr9RqTDnu4uLn5+cHkJ8fFxcXByCXe3p6et68+fTTS5YsWfL00y1aDBw4cGBCAt+BrHUBHElKysrKzGzWzGCwWMzmZ58tKSkt1esff1yvN5tNpqZN8SyFAq3RiFuSN296e7u5ubqePKlUSiQSyW+/BQV5e/v6XrnCrrtz5+DBQ4YMHJia+u+/58/v3Mk2N11dsYnKz4+Pj48HUCp9fHx8ioqefHL+/Pnz+/Rp2fLFF1988e+/+Q5onQngDFyrEYttNgAANqew2Tp2bNaseXOLpaLXOXBg0qRJkwYPjovbvXv37p9+wuylQiETIjf3ypUrVwDU6sDAwMCcnK5dp0+fPv2ZZ9q1e+211167dInvwFaUep/K8NChGTNmzOjT5+rVHTt27Ni3z2azWCwWgcDDIzQ0NBQgLw9TkWMfodU+/PC4cePGDRzYpcu777777h9/8O1/edT7bKo9ey5dunTp/v1t277++uuvv/CCSCSRSCQmE0uc7OUVHh4eDmAwFBcXF6vV586tX79+/a5dJ0+uXLlyZefOfPtfHvW+Bjhy4sTSpUuX9uhx/vxXX3311f79ZrNer9fLZJ6ezZo1awZQXIzCYBpZna5Jk549e/Z8+eW+fdeuXbv211/59t+Rel8DHHnssRkzZsz488+OHcePHz++f3+ZzNXV1bWkpKAgMTExEcDNDZsmq9VgMBhUqmvXfvnll1927jxzZt26deu6dePbf0canAAMbOMPHerWbfr06dOffhozWGs0ubmxsbGxAJ6ezZs3bw6AA2CJ5OLFTZs2bdq4kW+/HWmwAjA6dIiKioo6ffrxx2fPnj17wAC12t/f37+wMD393Llz5wBKSoqKiooAJBKlUqnU6fj294EnPv633377LSJi8+Z+/fr1279/8+b+/fv337//xo3jx48fDw/n2z+CIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiCIAiC4J11665ePXbskUdiYgoKMjLUar79+c9w8mR2dnJyWBjAokU9e3Kcp+cXX4waFRt74UJ+flqaqyvf/jnS4F5d7IzERK02L08qbdly48bJkxMSjEazWa8PDgYwm41GAIXCxcXTMzl5+/Z+/SZP7t+/b9/Q0LZt7a/N54sG/+JWxoABv/yyfPmhQ0ZjSUl+fnAwgFrt7Q0A4OkZGAig1xuNOl3jxn37bt06f/6FC3Pm/PPPrl0jR/Ltd4MX4Kmnfvll2bIvvrhyJTn5/PknngDw8goOBgDATB126+aGWdF0usJCsXj79qSks2dHjODb/wYrwIQJJ0/+9NO77x45cuXKn3+OGQPg4xMSAsAybtzxiLdy3ufm3rwJ0KhRcHDr1gkJZ84MGjRnTs+efD9HgxPgq6/i4k6c6Nnz00+PHPnmm9Wr7SWbBZpleGLHGk1uLoBIJJe7uBgMR4++9NL773fvrlZLpQpFaSnfz9NgBNiz58aNmJimTUeP3rt3xYoDBwBcXTHwEgnmgGUlXyDAJEJ6vVYLAGAy6fUA+/a99NL77z/1VPPmbm6+vhkZfD8PQ8y3A+WRkqLV5udLJC1afP/91KnHjwOwECuVOKhkbTxLQmqxYBaz4uLsbIBPPx04cNasUaOefTYoqGXLU6f4fh5H6n1e3q1bw8MNhj//LCwsLMzMbN0awMMjIADAHnhHcnNTUgDeeqt79zfeWLFi8eJOnV54YelSvp/DGfW2CerVa8+e5cvXr8/IyMpKSHjiCeeBt3eyKSkA3bu3afP007/99uWX3bu/8cbUqXw/R3k4FWDDhri4kycffbSuHRo37vjxzZsnTvz99/Pn9+176y0AL6/AQADWtd7h+q3A5+enpgKEhDRqFBkZH3/s2MCBs2b17VvXfleVuwTYsiUx8cyZbt2ion788b33Tp2KjNy0acqU33+vbUdWrbp8+ciR3r3XrYuO/umnVasAfHxCQwHsneq9RzcCgVzu4mI0Hj8+ePC8ed278x3QynJbgFOncnKSkxs1eu21nTs//PDQIQAPD39/gLi49PTY2J49g4K+/XbChNOno6Ozs5OSsDGoCfC+TZtOmvTrr6tWHTiAGcEAAKRSZ6MbjQaALTEcPDh48Lx5PXqEhanVXl5ZWXwHtLII4+OLirKyFIqBA/fsWbbs6FF8ZIUCQKXy8AAA8PYODQVIS8vPT03t2LFr182bp0+/cGHLlvj4U6ceeaSqN46PLy7OzpbJevXavn3RomPHAMRiqRQAQKVydwcAsNkwG5/j6KaoKDsbYPXqvn0nTRoxolevwMAWLerf6KbCAnTsuGPH4sWHD2dlpaZevRoebm9zHafy7u5+fgCYWdjX97XX9uxZtuzMmfff/+efnTtfeaWyNx4wYO/eVav++EOrLSrKzAwMtE+oHDtZVgPy8m7cABg37skn33xz2bKJE9u0eeqpDRv4DmB1ES5Z0qnTCy9s3IijDJsNIC8Ps/XaZ5YIK5EuLl5eAAAymVIJsGjRoUNffPHDD6NG/fHH11+/9155N+zZc8+eFSu++iou7saNCxe6dQPw9sYlBOejmxs3AJ54onXrZ57Zt2/duieeGDZs+nS+A1dT3F6OPnUqOzspqU2b55/fvfujj/bsycnJz09NDQtjTdCdayxl22SrFZuG/Py0NIDHHouIeOyxTZtOnBg8eO7cN99k1582LTp669ZJk5YtO3Lkm29WrgTw9sZFM5Y33rGTzctLTQUIDPTza9Lk2rX09BEjPv00MpLvgNWaAIysLL1eq3Vz69Nn587Fi/fu/fffpKTz5x9/HMDHJywMA4SBt3eOLGMq1pCiosxMgO7dIyMff/znn3v0aNQoImL//vnz//pry5aNGwHkcpUKAEAikcnuvI59dJOTAyAWi8UymV4fFxcV9cknTZs2a+bq6uPDEkQ/OJS7ITN06L59q1d/883PP5879+uvI0bY+wiJBLMFcxwGniVwZmmcdbqiIgAAqxWT2LLOVSSSSO78O1aTDAZcuyktLS4GOHx42LAVKzp3fuaZwMCIiNOn+Q5UbVHuTPjnn/v2nThx5Mjp0596asSIOXMAiopycgAA9PriYoC7VyFZiWZrNS4unp53nmcPPBvdGI0AAMXFubkAa9f27z91alTUgx54RqW3JDdsuHr1+PGhQ6Oi9u1bufKnn+wl2M3N3x8AwGareNpmAIDs7KQkHN1ERX388bp1Tzzx2mszZvAdmLqiynvCR49mZFy71rHjgAG7dn344b59Gk1xcU6Oj499Y4T1CY6wmpCdnZgI0KNH69ZPP713759/vvDCjBkDBvAdkLqm2pvyKSklJQUFfn79+u3YsWTJr79evpyaeunSI4/YO23W1LCagqObsDB//2bNYmNTUqKiVq9u2ZLvQPBFjf8qok+f3bs/+mjbtv37Y2IOH37pJQBfXxQCO1ehUCSSSPT6lJSRIz/7LCwsJMTFxcMDexWiBpk06dixTZs++ADg/fcff5zjAJYs6d2b4/74Iz09Lq7+pxp/YJgx48SJH36YM2fBgnPn9u2bNIlvfwiCIIjb/B/7w7TJ1Po+fAAAAABJRU5ErkJggg==);background-size:24px 352px}}.jsgrid .jsgrid-mode-button{width:24px;height:24px}.jsgrid-mode-on-button{opacity:.5}.jsgrid-cancel-edit-button{background-position:0 0;width:16px;height:16px}.jsgrid-clear-filter-button{background-position:0 -40px;width:16px;height:16px}.jsgrid-delete-button{background-position:0 -80px;width:16px;height:16px}.jsgrid-edit-button{background-position:0 -120px;width:16px;height:16px}.jsgrid-insert-mode-button{background-position:0 -160px;width:24px;height:24px}.jsgrid-insert-button{background-position:0 -208px;width:16px;height:16px}.jsgrid-search-mode-button{background-position:0 -248px;width:24px;height:24px}.jsgrid-search-button{background-position:0 -296px;width:16px;height:16px}.jsgrid-update-button{background-position:0 -336px;width:16px;height:16px}.jsgrid-load-shader{background:#ddd;opacity:.5;filter:alpha(opacity=50)}.jsgrid-load-panel{width:15em;height:5em;background:#fff;border:1px solid #e9e9e9;padding-top:3em;text-align:center}.jsgrid-load-panel:before{content:' ';position:absolute;top:.5em;left:50%;margin-left:-1em;width:2em;height:2em;border:2px solid #009a67;border-right-color:transparent;border-radius:50%;-webkit-animation:indicator 1s linear infinite;animation:indicator 1s linear infinite}@-webkit-keyframes indicator{from{-webkit-transform:rotate(0deg)}50%{-webkit-transform:rotate(180deg)}to{-webkit-transform:rotate(360deg)}}@keyframes indicator{from{transform:rotate(0deg)}50%{transform:rotate(180deg)}to{transform:rotate(360deg)}} \ No newline at end of file diff --git a/public/admin/css/jsgrid.css b/public/admin/css/jsgrid.css new file mode 100644 index 0000000..56128dd --- /dev/null +++ b/public/admin/css/jsgrid.css @@ -0,0 +1,126 @@ +/* + * jsGrid v1.5.2 (http://js-grid.com) + * (c) 2016 Artem Tabalin + * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE) + */ + +.jsgrid { + position: relative; + overflow: hidden; + font-size: 1em; +} + +.jsgrid, .jsgrid *, .jsgrid *:before, .jsgrid *:after { + box-sizing: border-box; +} + +.jsgrid input, +.jsgrid textarea, +.jsgrid select { + font-size: 1em; +} + +.jsgrid-grid-header { + overflow-x: hidden; + overflow-y: scroll; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + +.jsgrid-grid-body { + overflow-x: auto; + overflow-y: scroll; + -webkit-overflow-scrolling: touch; +} + +.jsgrid-table { + width: 100%; + table-layout: fixed; + border-collapse: collapse; + border-spacing: 0; +} + +.jsgrid-cell { + padding: 0.5em 0.5em; +} + +.jsgrid-сell, +.jsgrid-header-cell { + box-sizing: border-box; +} + +.jsgrid-align-left { + text-align: left; +} + +.jsgrid-align-center, +.jsgrid-align-center input, +.jsgrid-align-center textarea, +.jsgrid-align-center select { + text-align: center; +} + +.jsgrid-align-right, +.jsgrid-align-right input, +.jsgrid-align-right textarea, +.jsgrid-align-right select { + text-align: right; +} + +.jsgrid-header-cell { + padding: .5em .5em; +} + +.jsgrid-filter-row input, +.jsgrid-filter-row textarea, +.jsgrid-filter-row select, +.jsgrid-edit-row input, +.jsgrid-edit-row textarea, +.jsgrid-edit-row select, +.jsgrid-insert-row input, +.jsgrid-insert-row textarea, +.jsgrid-insert-row select { + width: 100%; + padding: .3em .5em; +} + +.jsgrid-filter-row input[type='checkbox'], +.jsgrid-edit-row input[type='checkbox'], +.jsgrid-insert-row input[type='checkbox'] { + width: auto; +} + + +.jsgrid-selected-row .jsgrid-cell { + cursor: pointer; +} + +.jsgrid-nodata-row .jsgrid-cell { + padding: .5em 0; + text-align: center; +} + +.jsgrid-header-sort { + cursor: pointer; +} + +.jsgrid-pager { + padding: .5em 0; +} + +.jsgrid-pager-nav-button { + padding: .2em .6em; +} + +.jsgrid-pager-nav-inactive-button { + display: none; + pointer-events: none; +} + +.jsgrid-pager-page { + padding: .2em .6em; +} diff --git a/public/admin/css/jsgrid.min.css b/public/admin/css/jsgrid.min.css new file mode 100644 index 0000000..2a218ac --- /dev/null +++ b/public/admin/css/jsgrid.min.css @@ -0,0 +1,7 @@ +/* + * jsGrid v1.5.2 (http://js-grid.com) + * (c) 2016 Artem Tabalin + * Licensed under MIT (https://github.com/tabalinas/jsgrid/blob/master/LICENSE) + */ + +.jsgrid{position:relative;overflow:hidden;font-size:1em}.jsgrid,.jsgrid *,.jsgrid :after,.jsgrid :before{box-sizing:border-box}.jsgrid input,.jsgrid select,.jsgrid textarea{font-size:1em}.jsgrid-grid-header{overflow-x:hidden;overflow-y:scroll;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.jsgrid-grid-body{overflow-x:auto;overflow-y:scroll;-webkit-overflow-scrolling:touch}.jsgrid-table{width:100%;table-layout:fixed;border-collapse:collapse;border-spacing:0}.jsgrid-cell{padding:.5em}.jsgrid-header-cell,.jsgrid-сell{box-sizing:border-box}.jsgrid-align-left{text-align:left}.jsgrid-align-center,.jsgrid-align-center input,.jsgrid-align-center select,.jsgrid-align-center textarea{text-align:center}.jsgrid-align-right,.jsgrid-align-right input,.jsgrid-align-right select,.jsgrid-align-right textarea{text-align:right}.jsgrid-header-cell{padding:.5em}.jsgrid-edit-row input,.jsgrid-edit-row select,.jsgrid-edit-row textarea,.jsgrid-filter-row input,.jsgrid-filter-row select,.jsgrid-filter-row textarea,.jsgrid-insert-row input,.jsgrid-insert-row select,.jsgrid-insert-row textarea{width:100%;padding:.3em .5em}.jsgrid-edit-row input[type=checkbox],.jsgrid-filter-row input[type=checkbox],.jsgrid-insert-row input[type=checkbox]{width:auto}.jsgrid-selected-row .jsgrid-cell{cursor:pointer}.jsgrid-nodata-row .jsgrid-cell{padding:.5em 0;text-align:center}.jsgrid-header-sort{cursor:pointer}.jsgrid-pager{padding:.5em 0}.jsgrid-pager-nav-button{padding:.2em .6em}.jsgrid-pager-nav-inactive-button{display:none;pointer-events:none}.jsgrid-pager-page{padding:.2em .6em} \ No newline at end of file diff --git a/public/admin/index.ejs b/public/admin/index.ejs index aba9b33..2fd3b3b 100644 --- a/public/admin/index.ejs +++ b/public/admin/index.ejs @@ -26,10 +26,12 @@ - + + + - - + + @@ -38,15 +40,16 @@ - - + + + \ No newline at end of file diff --git a/public/admin/prices.styl b/public/admin/prices.styl new file mode 100644 index 0000000..c104a77 --- /dev/null +++ b/public/admin/prices.styl @@ -0,0 +1,3 @@ +#prices { + +} \ No newline at end of file diff --git a/public/admin/sales.html b/public/admin/sales.html index b03fceb..57e61bc 100644 --- a/public/admin/sales.html +++ b/public/admin/sales.html @@ -35,8 +35,8 @@
- - + +
@@ -111,7 +111,8 @@ $(function() { } }; - var dataTable = new LinkedTable($page.find('#dataTable'), { + var $table = $page.find('#dataTable'); + $table.buildTable({ url: "data/Sale/readAll", attr: "data-key-name", selection: "row", @@ -156,15 +157,14 @@ $(function() { } } }); + var dataTable = $table.getTable(); + $page.find('#dataTable').on('dblclick', 'tr', function(event) { if(dataTable.getSelectedRow()) { location.hash = "#!/sales-edit"; } }); - //Call the refresh user table function once initially. - dataTable.build(); - //Refresh the data table if the user toggles the button to show/hide deleted elements. $page.find('#includeDeletedToggle').on('click', function(event) { dataTable.refresh(); @@ -187,9 +187,9 @@ $(function() { //Update the dialog drop downs when the queries finish. $.when.apply($, queries).then(function(query1, query2, query3) { //Initialize the drop down menus. - $editorForm.find("#DFItem").buildEditableSelect(query1[0], {textAttr: 'name', listClass: 'comboList'}); - $editorForm.find("#DFMeasure").buildEditableSelect(query2[0], {textAttr: 'name', listClass: 'comboList'}); - $editorForm.find("#DFVenue").buildEditableSelect(query3[0], {textAttr: 'name', listClass: 'comboList'}); + $editorForm.find("#DFItem").buildCombo(query1[0], {textAttr: 'name', listClass: 'comboList'}); + $editorForm.find("#DFMeasure").buildCombo(query2[0], {textAttr: 'name', listClass: 'comboList'}); + $editorForm.find("#DFVenue").buildCombo(query3[0], {textAttr: 'name', listClass: 'comboList'}); //Initialize the validator $editorForm.validator(); }); @@ -287,6 +287,21 @@ $(function() { }); }); + //Close the view if the user uses the escape key and it isn't handled at the widget level. + $editorView.on('keyup', function(event) { + switch(event.keyCode) { + case 27: + if(!event.isDefaultPrevented()) + history.back(); + break; + } + }); + + $page.find('div.date').datetimepicker({ + viewMode: 'years', + format: 'MM/DD/YY' + }); + //++++++++++++++++++++++++++++++++++++++ // ++++++++++ Delete View +++++++++++ diff --git a/public/admin/subcategories.html b/public/admin/subcategories.html index 6f665b8..bfa6818 100644 --- a/public/admin/subcategories.html +++ b/public/admin/subcategories.html @@ -104,7 +104,8 @@ $(function() { } }; - var dataTable = new LinkedTable($page.find('#dataTable'), { + var $table = $page.find('#dataTable'); + $table.buildTable({ url: "data/Subcategory/readAll", attr: "data-key-name", selection: "row", @@ -148,15 +149,14 @@ $(function() { } } }); + var dataTable = $table.getTable(); + $page.find('#dataTable').on('dblclick', 'tr', function(event) { if(dataTable.getSelectedRow()) { location.hash = "#!/subcategories-edit"; } }); - //Call the refresh user table function once initially. - dataTable.build(); - //Refresh the data table if the user toggles the button to show/hide deleted elements. $page.find('#includeDeletedToggle').on('click', function(event) { dataTable.refresh(); @@ -188,7 +188,7 @@ $(function() { //Update the dialog drop downs when the queries finish. $.when.apply($, queries).then(function(query1) { //Initialize the drop down menu. - $editorForm.find("#DFCategory").buildEditableSelect(query1, {textAttr: 'name', listClass: 'comboList'}); + $editorForm.find("#DFCategory").buildCombo(query1, {textAttr: 'name', listClass: 'comboList'}); //Initialize the validator $editorForm.validator(); }); @@ -266,6 +266,16 @@ $(function() { }); }); + //Close the view if the user uses the escape key and it isn't handled at the widget level. + $editorView.on('keyup', function(event) { + switch(event.keyCode) { + case 27: + if(!event.isDefaultPrevented()) + history.back(); + break; + } + }); + //++++++++++++++++++++++++++++++++++++++ // ++++++++++ Delete View +++++++++++ diff --git a/public/admin/users.html b/public/admin/users.html index 46b44fb..dfd4b5c 100644 --- a/public/admin/users.html +++ b/public/admin/users.html @@ -143,15 +143,14 @@ $(function() { } }; - var dataTable = new LinkedTable($page.find('#dataTable'), { + var $table = $page.find('#dataTable'); + $table.buildTable({ url: "data/User/readAll", attr: "data-key-name", selection: "row", selectionChanged: selectionChanged }); - - //Call the refresh user table function once initially. - dataTable.build(); + var dataTable = $table.getTable(); //---------------------------- //---- Create User Dialog ---- diff --git a/public/index.html b/public/index.html index 7edd90b..fcfc651 100644 --- a/public/index.html +++ b/public/index.html @@ -17,8 +17,8 @@ - - + + diff --git a/public/js/jquery-1.12.4.js b/public/js/jquery-1.12.4.js new file mode 100644 index 0000000..7fc60fc --- /dev/null +++ b/public/js/jquery-1.12.4.js @@ -0,0 +1,11008 @@ +/*! + * jQuery JavaScript Library v1.12.4 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-05-20T17:17Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Support: Firefox 18+ +// Can't be in strict mode, several libs including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +//"use strict"; +var deletedIds = []; + +var document = window.document; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.12.4", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type( obj ) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call( obj, "constructor" ) && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + } catch ( e ) { + + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( !support.ownFirst ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[ j ] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +// JSHint would error on this code due to the Symbol not being defined in ES5. +// Defining this global in .jshintrc would create a danger of using the global +// unguarded in another place, it seems safer to just disable JSHint for these +// three lines. +/* jshint ignore: start */ +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ]; +} +/* jshint ignore: end */ + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.1 + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-10-17 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, nidselect, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; + while ( i-- ) { + groups[i] = nidselect + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( (parent = document.defaultView) && parent.top !== parent ) { + // Support: IE 11 + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + return m ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( (oldCache = uniqueCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + } ); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not; + } ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // init accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt( 0 ) === "<" && + selector.charAt( selector.length - 1 ) === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[ 2 ] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[ 0 ] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof root.ready !== "undefined" ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( pos ? + pos.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[ 0 ], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.uniqueSort( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +} ); +var rnotwhite = ( /\S+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( jQuery.isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = true; + if ( !memory ) { + self.disable(); + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ) ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( function() { + + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || + ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. + // If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .progress( updateFunc( i, progressContexts, progressValues ) ) + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +} ); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +} ); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || + window.event.type === "load" || + document.readyState === "complete" ) { + + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called + // after the browser event has already occurred. + // Support: IE6-10 + // Older IE sometimes signals "interactive" too soon + if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); + + // If IE event model is used + } else { + + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch ( e ) {} + + if ( top && top.doScroll ) { + ( function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll( "left" ); + } catch ( e ) { + return window.setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + } )(); + } + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownFirst = i === "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery( function() { + + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== "undefined" ) { + + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +} ); + + +( function() { + var div = document.createElement( "div" ); + + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch ( e ) { + support.deleteExpando = false; + } + + // Null elements to avoid leaks in IE. + div = null; +} )(); +var acceptData = function( elem ) { + var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute( "classid" ) === noData; +}; + + + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) && + data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } else { + + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[ i ] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, undefined + } else { + cache[ id ] = undefined; + } +} + +jQuery.extend( { + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + jQuery.data( this, key ); + } ); + } + + return arguments.length > 1 ? + + // Sets one value + this.each( function() { + jQuery.data( this, key, value ); + } ) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each( function() { + jQuery.removeData( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = jQuery._data( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, + // or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); + + +( function() { + var shrinkWrapBlocksVal; + + support.shrinkWrapBlocks = function() { + if ( shrinkWrapBlocksVal != null ) { + return shrinkWrapBlocksVal; + } + + // Will be changed later if needed. + shrinkWrapBlocksVal = false; + + // Minified: var b,c,d + var div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + + // Test fired too early or in an unsupported environment, exit. + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + if ( typeof div.style.zoom !== "undefined" ) { + + // Reset CSS: box-sizing; display; margin; border + div.style.cssText = + + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;" + + "padding:1px;width:1px;zoom:1"; + div.appendChild( document.createElement( "div" ) ).style.width = "5px"; + shrinkWrapBlocksVal = div.offsetWidth !== 3; + } + + body.removeChild( container ); + + return shrinkWrapBlocksVal; + }; + +} )(); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || + !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { return tween.cur(); } : + function() { return jQuery.css( elem, prop, "" ); }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( + elems[ i ], + key, + raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[ 0 ], key ) : emptyGet; +}; +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([\w:-]+)/ ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + +var rleadingWhitespace = ( /^\s+/ ); + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" + + "details|dialog|figcaption|figure|footer|header|hgroup|main|" + + "mark|meter|nav|output|picture|progress|section|summary|template|time|video"; + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + + +( function() { + var div = document.createElement( "div" ), + fragment = document.createDocumentFragment(), + input = document.createElement( "input" ); + + // Setup + div.innerHTML = "
Name
a"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input = document.createElement( "input" ); + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+ + support.noCloneEvent = !!div.addEventListener; + + // Support: IE<9 + // Since attributes and properties are the same in IE, + // cleanData must set properties to undefined rather than use removeAttribute + div[ jQuery.expando ] = 1; + support.attributes = !div.getAttribute( jQuery.expando ); +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + + // Support: IE8 + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] +}; + +// Support: IE8-IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; + ( elem = elems[ i ] ) != null; + i++ + ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; ( elem = elems[ i ] ) != null; i++ ) { + jQuery._data( + elem, + "globalEval", + !refElements || jQuery._data( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/, + rtbody = / from table fragments + if ( !support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[ 1 ] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) && + !tbody.childNodes.length ) { + + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; +} + + +( function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events) + for ( i in { submit: true, change: true, focusin: true } ) { + eventName = "on" + i; + + if ( !( support[ i ] = eventName in window ) ) { + + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +} )(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE9 +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && + ( !e || jQuery.event.triggered !== e.type ) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + + // Add elem as a property of the handle fn to prevent a memory leak + // with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && + jQuery._data( cur, "handle" ); + + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( + ( !special._default || + special._default.apply( eventPath.pop(), data ) === false + ) && acceptData( elem ) + ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Support (at least): Chrome, IE9 + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // + // Support: Firefox<=42+ + // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) + if ( delegateCount && cur.nodeType && + ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push( { elem: cur, handlers: matches } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Safari 6-8+ + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split( " " ), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: ( "button buttons clientX clientY fromElement offsetX offsetY " + + "pageX pageY screenX screenY toElement" ).split( " " ), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - + ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - + ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? + original.toElement : + fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + // Piggyback on a donor event to simulate a different one + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + + // Previously, `originalEvent: {}` was set here, so stopPropagation call + // would not be triggered on donor event, since in our own + // jQuery.event.stopPropagation function we had a check for existence of + // originalEvent.stopPropagation method, so, consequently it would be a noop. + // + // Guard for simulated events was moved to jQuery.event.stopPropagation function + // since `originalEvent` should point to the original event for the + // constancy with other events and for more focused logic + } + ); + + jQuery.event.trigger( e, null, elem ); + + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, + // to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( !e || this.isSimulated ) { + return; + } + + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://code.google.com/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +// IE submit delegation +if ( !support.submit ) { + + jQuery.event.special.submit = { + setup: function() { + + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? + + // Support: IE <=8 + // We use jQuery.prop instead of elem.form + // to allow fixing the IE8 delegated submit issue (gh-2332) + // by 3rd party polyfills/workarounds. + jQuery.prop( elem, "form" ) : + undefined; + + if ( form && !jQuery._data( form, "submit" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submitBubble = true; + } ); + jQuery._data( form, "submit", true ); + } + } ); + + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + + // If form was submitted by the user, bubble the event up the tree + if ( event._submitBubble ) { + delete event._submitBubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event ); + } + } + }, + + teardown: function() { + + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.change ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._justChanged = true; + } + } ); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._justChanged && !event.isTrigger ) { + this._justChanged = false; + } + + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event ); + } ); + } + return false; + } + + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event ); + } + } ); + jQuery._data( elem, "change", true ); + } + } ); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || + ( elem.type !== "radio" && elem.type !== "checkbox" ) ) { + + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Support: Firefox +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome, Safari +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + } ); +} + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + }, + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ), + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, + + // Support: IE 10-11, Edge 10240+ + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) ); + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName( "tbody" )[ 0 ] || + elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute( "type" ); + } + return elem; +} + +function cloneCopyEvent( src, dest ) { + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( + ( node.text || node.textContent || node.innerHTML || "" ) + .replace( rcleanScript, "" ) + ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + elems = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = elems[ i ] ) != null; i++ ) { + + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc( elem ) || + !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( ( !support.noCloneEvent || !support.noCloneChecked ) && + ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) { + + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[ i ] ) { + fixCloneNodeIssues( node, destElements[ i ] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) { + cloneCopyEvent( node, destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + cleanData: function( elems, /* internal */ forceAcceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + attributes = support.attributes, + special = jQuery.event.special; + + for ( ; ( elem = elems[ i ] ) != null; i++ ) { + if ( forceAcceptData || acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // Support: IE<9 + // IE does not allow us to delete expando properties from nodes + // IE creates expando attributes along with the property + // IE does not have a removeAttribute function on Document nodes + if ( !attributes && typeof elem.removeAttribute !== "undefined" ) { + elem.removeAttribute( internalKey ); + + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://code.google.com/p/chromium/issues/detail?id=378607 + } else { + elem[ internalKey ] = undefined; + } + + deletedIds.push( id ); + } + } + } + } + } +} ); + +jQuery.fn.extend( { + + // Keep domManip exposed until 3.0 (gh-2225) + domManip: domManip, + + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( + ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) + ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + + // Remove element nodes and prevent memory leaks + elem = this[ i ] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); + + +var iframe, + elemdisplay = { + + // Support: Firefox + // We have to pre-define these values for FF (#10227) + HTML: "block", + BODY: "block" + }; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ + +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + display = jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = ( iframe || jQuery( "