[
  {
    "path": ".gitignore",
    "content": "# Github Node Default\n\nlib-cov\n*.seed\n*.log\n*.csv\n*.dat\n*.out\n*.pid\n*.gz\n\npids\nlogs\nresults\n\nnpm-debug.log\nnode_modules\n\n# From Mean Stack\nbower_components/\n.DS_Store\n.nodemonignore\n.sass-cache/\nnode_modules/\npublic/lib\ntest/coverage/\nmigrations/\n\n# Configuration Files\n/config/env/development.json5\n/config/env/production.json5\n/config/env/test.json5\n\n*.local\n\n# IDE files\n.idea\n/.*.md.html\n.settings\n.project\n.classpath\n*~\n*.swp\n*.swo\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n    // JSHint Default Configuration File (as on JSHint website)\n    // See http://jshint.com/docs/ for more details\n\n    \"maxerr\"        : 50,       // {int} Maximum error before stopping\n\n    // Enforcing\n    \"bitwise\"       : true,     // true: Prohibit bitwise operators (&, |, ^, etc.)\n    \"camelcase\"     : false,    // true: Identifiers must be in camelCase\n    \"curly\"         : true,     // true: Require {} for every new block or scope\n    \"eqeqeq\"        : true,     // true: Require triple equals (===) for comparison\n    \"forin\"         : true,     // true: Require filtering for..in loops with obj.hasOwnProperty()\n    \"freeze\"        : true,     // true: prohibits overwriting prototypes of native objects such as Array, Date etc.\n    \"immed\"         : false,    // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`\n    \"indent\"        : 4,        // {int} Number of spaces to use for indentation\n    \"latedef\"       : false,    // true: Require variables/functions to be defined before being used\n    \"newcap\"        : false,    // true: Require capitalization of all constructor functions e.g. `new F()`\n    \"noarg\"         : true,     // true: Prohibit use of `arguments.caller` and `arguments.callee`\n    \"noempty\"       : true,     // true: Prohibit use of empty blocks\n    \"nonbsp\"        : true,     // true: Prohibit \"non-breaking whitespace\" characters.\n    \"nonew\"         : false,    // true: Prohibit use of constructors for side-effects (without assignment)\n    \"plusplus\"      : false,    // true: Prohibit use of `++` and `--`\n    \"quotmark\"      : false,    // Quotation mark consistency:\n    //   false    : do nothing (default)\n    //   true     : ensure whatever is used is consistent\n    //   \"single\" : require single quotes\n    //   \"double\" : require double quotes\n    \"undef\"         : true,     // true: Require all non-global variables to be declared (prevents global leaks)\n    \"unused\"        : false,     // Unused variables:\n    //   true     : all variables, last function parameter\n    //   \"vars\"   : all variables only\n    //   \"strict\" : all variables, all function parameters\n    \"strict\"        : true,     // true: Requires all functions run in ES5 Strict Mode\n    \"maxparams\"     : false,    // {int} Max number of formal params allowed per function\n    \"maxdepth\"      : false,    // {int} Max depth of nested blocks (within functions)\n    \"maxstatements\" : false,    // {int} Max number statements per function\n    \"maxcomplexity\" : false,    // {int} Max cyclomatic complexity per function\n    \"maxlen\"        : false,    // {int} Max number of characters per line\n    \"varstmt\"       : false,    // true: Disallow any var statements. Only `let` and `const` are allowed.\n\n    // Relaxing\n    \"asi\"           : false,     // true: Tolerate Automatic Semicolon Insertion (no semicolons)\n    \"boss\"          : false,     // true: Tolerate assignments where comparisons would be expected\n    \"debug\"         : false,     // true: Allow debugger statements e.g. browser breakpoints.\n    \"eqnull\"        : true,     // true: Tolerate use of `== null`\n    \"es5\"           : false,      // true: Allow ES5 syntax (ex: getters and setters)\n    \"esnext\"        : true,     // true: Allow ES.next (ES6) syntax (ex: `const`)\n    \"moz\"           : false,     // true: Allow Mozilla specific syntax (extends and overrides esnext features)\n    // (ex: `for each`, multiple try/catch, function expression…)\n    \"evil\"          : false,     // true: Tolerate use of `eval` and `new Function()`\n    \"expr\"          : false,     // true: Tolerate `ExpressionStatement` as Programs\n    \"funcscope\"     : true,     // true: Tolerate defining variables inside control statements\n    \"globalstrict\"  : false,     // true: Allow global \"use strict\" (also enables 'strict')\n    \"iterator\"      : false,     // true: Tolerate using the `__iterator__` property\n    \"lastsemic\"     : false,     // true: Tolerate omitting a semicolon for the last statement of a 1-line block\n    \"laxbreak\"      : false,     // true: Tolerate possibly unsafe line breakings\n    \"laxcomma\"      : false,     // true: Tolerate comma-first style coding\n    \"loopfunc\"      : false,     // true: Tolerate functions being defined in loops\n    \"multistr\"      : false,     // true: Tolerate multi-line strings\n    \"noyield\"       : false,     // true: Tolerate generator functions with no yield statement in them.\n    \"notypeof\"      : false,     // true: Tolerate invalid typeof operator values\n    \"proto\"         : false,     // true: Tolerate using the `__proto__` property\n    \"scripturl\"     : false,     // true: Tolerate script-targeted URLs\n    \"shadow\"        : false,     // true: Allows re-define variables later in code e.g. `var x=1; x=2;`\n    \"sub\"           : false,     // true: Tolerate using `[]` notation when it can still be expressed in dot notation\n    \"supernew\"      : false,     // true: Tolerate `new function () { ... };` and `new Object;`\n    \"validthis\"     : false,     // true: Tolerate using this in a non-constructor function\n\n    // Environments\n    \"browser\"       : true,     // Web Browser (window, document, etc)\n    \"browserify\"    : false,    // Browserify (node.js code in the browser)\n    \"couch\"         : false,    // CouchDB\n    \"devel\"         : true,     // Development/debugging (alert, confirm, etc)\n    \"dojo\"          : false,    // Dojo Toolkit\n    \"jasmine\"       : true,    // Jasmine\n    \"jquery\"        : false,    // jQuery\n    \"mocha\"         : true,     // Mocha\n    \"mootools\"      : false,    // MooTools\n    \"node\"          : true,    // Node.js\n    \"nonstandard\"   : false,    // Widely adopted globals (escape, unescape, etc)\n    \"phantom\"       : false,    // PhantomJS\n    \"prototypejs\"   : false,    // Prototype and Scriptaculous\n    \"qunit\"         : false,    // QUnit\n    \"rhino\"         : false,    // Rhino\n    \"shelljs\"       : false,    // ShellJS\n    \"typed\"         : false,    // Globals for typed array constructions\n    \"worker\"        : false,    // Web Workers\n    \"wsh\"           : false,    // Windows Scripting Host\n    \"yui\"           : false,    // Yahoo User Interface\n\n    // Custom Globals\n    \"globals\"       : {\n        \"angular\": true,\n        \"describe\": true,\n        \"it\": true,\n        \"expect\": true,\n        \"beforeEach\": true,\n        \"afterEach\": true,\n        \"module\": true,\n        \"inject\": true\n    }        // additional predefined global variables\n}"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"0.10\"\nenv:\n  - NODE_ENV=travis\nservices:\n  - mongodb\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013-2015 Jeff Potter, Chaudhry Junaid\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Procfile",
    "content": "web: node pm2-main.js\n"
  },
  {
    "path": "README.md",
    "content": "MEAN Stack Relational ![Mean Stack Build Status](https://travis-ci.org/jpotts18/mean-stack-relational.png)\n=====================\n\n### Please use for reference only! No support or updates planned.\n\nThe main idea for this repository is shamelessly stolen from [http://mean.io](http://mean.io). It says:\n\n> MEAN is a boilerplate that provides a nice starting point for [MySQL], Express, Node.js, and AngularJS based applications. It is designed to give you quick and organized way to start developing of MEAN based web apps with useful modules like sequelize and passport pre-bundled and configured. We mainly try to take care of the connection points between existing popular frameworks and solve common integration problems.\n\n\nThe MongoDB ORM, [Mongoose](http://mongoosejs.com/), has been replaced with [Sequelize](http://sequelizejs.com/). Switching from mongoose to sequelize allows developers easy access to MySQL, MariaDB, SQLite or PostgreSQL databases by mapping database entries to objects and vice versa.\n\n[Addy Osmani's Blog](http://addyosmani.com/blog/full-stack-javascript-with-mean-and-yeoman/) explains SQL databases, being strongly typed in nature are great at enforcing a level of consistency, ensuring many kinds of bad data simply don’t get recorded. By using SQL databases MEAN Stack Relational favors reliability over the performance gains of NoSQL databases.\n\n# Demo\n\nDeploy to your Heroku account for a demo:\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)\n\nNote: Deploy from main repository view to avoid missing app.json error.\n\n# Getting Started\n\nAlright now the fun begins. First clone or download the repo to your computer. \n\n1. Clone the repository ```git clone git@github.com:jpotts18/mean-stack-relational.git```.\n1. Go into the repository ```cd mean-stack-relational/```.\n1. Install dependencies with NPM ```npm install```. This will copy development.json5, and production.json5 from respective sample files in the config/env folder and run the grunt copy task to copy frontend lib files to their destination.\n1. Plug in your private and public keys for working with FB and Twitter into ```/config/env/development.json5``` and/or ```/config/env/production.json5```.\n1. Wire up the database connection found in ```/config/env/development.json5``` and/or ```/config/env/production.json5```.\n1. Run in production mode with: ```pm2 start pm2-ecosystem.json --env production``` (Run ```sudo npm install -g pm2``` if it's not installed.), or\n1. Run in development mode with grunt: ```grunt```\n1. Make something awesome!\n\nThats all! Now go and open up your browser at [http://localhost:3000](http://localhost:3000), and tweet [@jpotts18](http://twitter.com/jpotts18) to say thanks!\n\n\n## Prerequisites\n- Node.js - Download and Install Node.js. You can also follow [this gist](https://gist.github.com/isaacs/579814) for a quick and easy way to install Node.js and npm\n- MySQL - Download and Install MySQL - Make sure it's running on the default port (3306).\n\n### Tool Prerequisites\n- NPM - Node.js package manager, should be installed when you install node.js. NPM (Node Package Manager) will look at the [package.json](https://github.com/jpotts18/mean-stack-relational/blob/master/package.json) file in the root of the project and download all of the necessary dependencies and put them in a folder called ```node_modules```\n\n- Bower - Web package manager, installing Bower is simple when you have npm:\n``` npm install -g bower ```\n\n### NPM Modules Used\n- [Passport](http://passportjs.org/) - Passport is authentication middleware for Node.js. Extremely flexible and modular, Passport can be unobtrusively dropped in to any Express-based web application. A comprehensive set of strategies support authentication using a username and password, Facebook, Twitter, and more. \n- [Express](http://expressjs.com/) - Express is a minimal and flexible node.js web application framework, providing a robust set of features for building single and multi-page, and hybrid web applications.\n- [Sequelize](http://sequelizejs.com/) - The Sequelize library provides easy access to MySQL, MariaDB, SQLite or PostgreSQL databases by mapping database entries to objects and vice versa. To put it in a nutshell, it's an ORM (Object-Relational-Mapper). The library is written entirely in JavaScript and can be used in the Node.JS environment. \n\n### Javascript Tools Used\n- [Grunt](http://gruntjs.com/) - In one word: automation. The less work you have to do when performing repetitive tasks like minification, compilation, unit testing, linting, etc, the easier your job becomes. After you've configured it, a Grunt can do most of that mundane work for you—and your team—with basically zero effort.\n\n  1. It [watches](https://github.com/jpotts18/mean-stack-relational/blob/master/gruntfile.js#L5) your filesystem and when it detects a change it will livereload your changes. \n\n  2. It runs [jshint](https://github.com/jpotts18/mean-stack-relational/blob/master/gruntfile.js#L32) which looks through your javascript files and ensures coding standards.\n\n  3. It runs [nodemon](https://github.com/jpotts18/mean-stack-relational/blob/master/gruntfile.js#L35) which watches changes in specific folders and recompiles the app when necessary. No running ```node app.js``` every 2 minutes. \n\n  4. It can also run tests like mocha and karma for you.\n\n- [Bower](http://bower.io/) - Bower is a package manager for the web. It offers a generic, unopinionated solution to the problem of front-end package management, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat.\n\n### Front-End Tools Used\n- [Angular.js](http://angularjs.org) - AngularJS is an open-source JavaScript framework, maintained by Google, that assists with running single-page applications. Its goal is to augment browser-based applications with model–view–controller (MVC) capability, in an effort to make both development and testing easier.\n- [Twitter Bootstrap](http://getbootstrap.com/) - Sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development.\n- [UI Bootstrap](http://angular-ui.github.io/bootstrap/) - Bootstrap components written in pure AngularJS by the AngularUI Team\n\n# Project Roadmap\n\nFollowing is a list of items detailing future direction for MEAN Stack Relational:\n\n## Purpose\n- Demonstrate several login strategies using passport.js\n- Demonstrate environment configuration best practices\n- Demonstrate how to use Sequelize to query a single table and to accomplish a join.\n\n## Additions\n- Demonstrate testing for Express routes and javascript classes using Mocha, Sinon, Proxyquire and more\n- Demonstrating modularity by using javascript classes for complex backend functionality\n- Yeoman generator to compete with MEAN\n\n\n# Troubleshooting and Contact\n\nDuring install some of you may encounter some issues feel free to contact me (jpotts18) or the co-contributor (chaudhryjunaid), via the repository issue tracker or the links provided below. I am also available on twitter at [@jpotts18](http://twitter.com/jpotts18) and Junaid at [@chjunaidanwar](http://twitter.com/chjunaidanwar).\n"
  },
  {
    "path": "app/controllers/articles.js",
    "content": "'use strict';\n\n/**\n * Module dependencies.\n */\nvar StandardError = require('standard-error');\nvar db = require('../../config/sequelize');\n\n/**\n * Find article by id\n * Note: This is called every time that the parameter :articleId is used in a URL. \n * Its purpose is to preload the article on the req object then call the next function. \n */\nexports.article = function(req, res, next, id) {\n    console.log('id => ' + id);\n    db.Article.find({where: {id: id}, include: [{model:db.User, attributes:['id', 'username', 'name']}]}).then(function(article){\n        if(!article) {\n            return next(new Error('Failed to load article ' + id));\n        } else {\n            req.article = article;\n            return next();            \n        }\n    }).catch(function(err){\n        return next(err);\n    });\n};\n\n/**\n * Create a article\n */\nexports.create = function(req, res) {\n    // augment the article by adding the UserId\n    req.body.UserId = req.user.id;\n    // save and return and instance of article on the res object. \n    db.Article.create(req.body).then(function(article){\n        if(!article){\n            return res.send('users/signup', {errors: new StandardError('Article could not be created')});\n        } else {\n            return res.jsonp(article);\n        }\n    }).catch(function(err){\n        return res.send('users/signup', { \n            errors: err,\n            status: 500\n        });\n    });\n};\n\n/**\n * Update a article\n */\nexports.update = function(req, res) {\n\n    // create a new variable to hold the article that was placed on the req object.\n    var article = req.article;\n\n    article.updateAttributes({\n        title: req.body.title,\n        content: req.body.content\n    }).then(function(a){\n        return res.jsonp(a);\n    }).catch(function(err){\n        return res.render('error', {\n            error: err, \n            status: 500\n        });\n    });\n};\n\n/**\n * Delete an article\n */\nexports.destroy = function(req, res) {\n\n    // create a new variable to hold the article that was placed on the req object.\n    var article = req.article;\n\n    article.destroy().then(function(){\n        return res.jsonp(article);\n    }).catch(function(err){\n        return res.render('error', {\n            error: err,\n            status: 500\n        });\n    });\n};\n\n/**\n * Show an article\n */\nexports.show = function(req, res) {\n    // Sending down the article that was just preloaded by the articles.article function\n    // and saves article on the req object.\n    return res.jsonp(req.article);\n};\n\n/**\n * List of Articles\n */\nexports.all = function(req, res) {\n    db.Article.findAll({include: [{model:db.User, attributes: ['id', 'username', 'name']}]}).then(function(articles){\n        return res.jsonp(articles);\n    }).catch(function(err){\n        return res.render('error', {\n            error: err,\n            status: 500\n        });\n    });\n};\n\n/**\n * Article authorizations routing middleware\n */\nexports.hasAuthorization = function(req, res, next) {\n    if (req.article.User.id !== req.user.id) {\n      return res.send(401, 'User is not authorized');\n    }\n    next();\n};\n"
  },
  {
    "path": "app/controllers/index.js",
    "content": "'use strict';\n\n/**\n * Module dependencies.\n */\nvar _ = require('lodash');\n\n\nexports.render = function(req, res) {\n    res.render('index', {\n        user: req.user ? JSON.stringify(req.user) : \"null\"\n    });\n};\n"
  },
  {
    "path": "app/controllers/users.js",
    "content": "'use strict';\n\n/**\n * Module dependencies.\n */\nvar db = require('../../config/sequelize'),\n    request = require('request'),\n    qs = require('querystring'),\n    config = require('../../config/config'),\n    passport = require('passport');\n\n/**\n * Auth callback\n */\nexports.authCallback = function (req, res, next) {\n    res.redirect('/');\n};\n\n/**\n * Show login form\n */\nexports.signin = function (req, res) {\n    res.render('users/signin', {\n        title: 'Signin',\n        message: req.flash('error')\n    });\n};\n\n/**\n * Show sign up form\n */\nexports.signup = function (req, res) {\n    res.render('users/signup', {\n        title: 'Sign up',\n    });\n};\n\n/**\n * Logout\n */\nexports.signout = function (req, res) {\n    console.log('Logout: { id: ' + req.user.id + ', username: ' + req.user.username + '}');\n    req.logout();\n    return res.send({status: 'success', message: 'User logout successfully.'});\n};\n\n/**\n * Session\n */\nexports.session = function (req, res) {\n    return res.send({status: 'success', message: 'User login successfully.'})\n    // res.redirect('/');\n};\n\n/**\n * Create user\n */\nexports.create = function (req, res, next) {\n    var message = null;\n\n    var user = db.User.build(req.body);\n\n    user.provider = 'local';\n    user.salt = user.makeSalt();\n    user.hashedPassword = user.encryptPassword(req.body.password, user.salt);\n    console.log('New User (local) : { id: ' + user.id + ' username: ' + user.username + ' }');\n\n    user.save().then(function () {\n        req.login(user, function (err) {\n            if (err) {\n                return next(err);\n            }\n            return res.send({status: 'success', message: 'User signup successfully.'})\n            // res.redirect('/');\n        });\n    }).catch(function (err) {\n        res.render('users/signup', {\n            message: message,\n            user: user\n        });\n    });\n};\n\n/**\n * Send User\n */\nexports.me = function (req, res) {\n    res.jsonp(req.user || null);\n};\n\n/**\n * Find user by id\n */\nexports.user = function (req, res, next, id) {\n    db.User.find({where: {id: id}}).then(function (user) {\n        if (!user) {\n            return next(new Error('Failed to load User ' + id));\n        }\n        req.profile = user;\n        next();\n    }).catch(function (err) {\n        next(err);\n    });\n};\n\n/**\n * Generic require login routing middleware\n */\nexports.requiresLogin = function (req, res, next) {\n    if (!req.isAuthenticated()) {\n        return res.status(401).send('User is not authorized');\n    }\n    next();\n};\n\n/**\n * User authorizations routing middleware\n */\nexports.hasAuthorization = function (req, res, next) {\n    if (req.profile.id !== req.user.id) {\n        return res.status(401).send('User is not authorized');\n    }\n    next();\n};\n\n// function to authenticate and create user\nfunction authenticateSocialUser(profile, done) {\n    var searchQuery = {\n        email: profile.email\n    };\n    if (profile.name) {\n        searchQuery = {\n            twitterKey: profile.id\n        }\n    }\n\n    db.User.find({where: searchQuery}).then(function (user) {\n\n        if (!user) {\n            var userObj = {};\n            if (profile.name) {\n                userObj = {\n                    name: profile.name || '',\n                    username: profile.name || '',\n                    provider: 'twitter',\n                    twitterKey: profile.id,\n                    email: profile.id + \"@twitter.com\"\n                }\n            } else {\n                userObj = {\n                    name: profile.given_name || '',\n                    email: profile.email,\n                    username: profile.given_name || profile.name || '',\n                    provider: 'google',\n                    googleUserId: profile.sub\n                };\n            }\n            db.User.create(userObj).then(function (u) {\n                done(null, u);\n            })\n        } else {\n            done(null, user);\n        }\n    }).catch(function (err) {\n        done(err, null, err);\n    });\n}\n\nexports.facebookUser = function (req, res, next) {\n\n    function sendResponse(err, user, info) {\n\n        if (err) {\n            return res.send({status: \"error\", error: err});\n        }\n        if (!user) {\n            return res.send({status: \"error\", error: info});\n        }\n        req.login(user, function (err) {\n            if (err) {\n                return res.send({status: \"error\", error: {message: 'Login failed'}});\n            }\n            return res.send({status: \"success\", data: {user: user}});\n        });\n    }\n\n    passport.authenticate('facebook-token', {scope: ['email', 'user_about_me', 'phone']}, sendResponse)(req, res, next);\n}\n\nexports.twitterSocialUser = function (req, res) {\n    var requestTokenUrl = 'https://api.twitter.com/oauth/request_token';\n    var accessTokenUrl = 'https://api.twitter.com/oauth/access_token';\n    var profileUrl = 'https://api.twitter.com/1.1/account/verify_credentials.json';\n\n    function sendResponse(err, user, info) {\n        if (err) {\n            return res.send({status: \"error\", error: err});\n        }\n        if (!user) {\n            return res.send({status: \"error\", error: info});\n        }\n\n        req.login(user, function (err) {\n            if (err) {\n                return res.send({status: \"error\", error: {message: 'Login failed'}});\n            }\n            return res.send({status: \"success\", data: {user: user}});\n        });\n\n    }\n\n    function getUserProfile(err, response, profile) {\n        if (err) {\n            return res.send({status: \"error\", error: err});\n        }\n        // Step 5a. Link user accounts.\n        authenticateSocialUser(profile, sendResponse);\n\n    }\n\n    function verifyAccesToken(err, response, accessToken) {\n\n        accessToken = qs.parse(accessToken);\n\n        var profileOauth = {\n            consumer_key: config.twitter.clientID,\n            consumer_secret: config.twitter.clientSecret,\n            token: accessToken.oauth_token,\n            token_secret: accessToken.oauth_token_secret,\n        };\n\n        // Step 4. Retrieve user's profile information and email address.\n        request.get({\n            url: profileUrl,\n            qs: {include_email: true},\n            oauth: profileOauth,\n            json: true\n        }, getUserProfile);\n    }\n\n    function obtainRequestToken() {\n        var requestTokenOauth = {\n            consumer_key: config.twitter.clientID,\n            consumer_secret: config.twitter.clientSecret,\n            callback: req.body.redirectUri\n        };\n        // Step 1. Obtain request token for the authorization popup.\n        request.post({url: requestTokenUrl, oauth: requestTokenOauth}, function (err, response, body) {\n            var oauthToken = qs.parse(body);\n            // Step 2. Send OAuth token back to open the authorization screen.\n            res.send(oauthToken);\n        });\n    }\n\n    function exchangeOauthToken() {\n        var accessTokenOauth = {\n            consumer_key: config.twitter.clientID,\n            consumer_secret: config.twitter.clientSecret,\n            token: req.body.oauth_token,\n            verifier: req.body.oauth_verifier\n        };\n        // Step 3. Exchange oauth token and oauth verifier for access token.\n        request.post({url: accessTokenUrl, oauth: accessTokenOauth}, verifyAccesToken);\n    }\n\n    // Part 1 of 2: Initial request from Satellizer.\n    if (!req.body.oauth_token || !req.body.oauth_verifier) {\n        obtainRequestToken();\n    } else {\n        // Part 2 of 2: Second request after Authorize app is clicked.\n        exchangeOauthToken();\n    }\n}\n\nexports.googleSocailUser = function (req, res) {\n    var accessTokenUrl = 'https://accounts.google.com/o/oauth2/token';\n    var peopleApiUrl = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect';\n    var params = {\n        code: req.body.code,\n        client_id: req.body.clientId,\n        client_secret: config.google.clientSecret,\n        redirect_uri: req.body.redirectUri,\n        grant_type: 'authorization_code'\n    };\n\n    function sendResponse(err, user, info) {\n        if (err) {\n            return res.send({status: \"error\", error: err});\n        }\n        if (!user) {\n            return res.send({status: \"error\", error: info});\n        }\n        req.login(user, function (err) {\n            if (err) {\n                return res.send({status: \"error\", error: {message: 'Login failed'}});\n            }\n            return res.send({status: \"success\", data: {user: user}});\n        });\n    }\n\n    function retrivedInfo(err, response, profile) {\n        if (profile.error) {\n            return res.status(500).send({message: profile.error.message});\n        }\n        // Authenticate User\n        authenticateSocialUser(profile, sendResponse);\n    }\n\n    function getAccessToken(err, response, token) {\n        var accessToken = token.access_token;\n        var headers = {Authorization: 'Bearer ' + accessToken};\n\n        // Step 2. Retrieve profile information about the current user.\n        request.get({url: peopleApiUrl, headers: headers, json: true}, retrivedInfo);\n    }\n\n    // Step 1. Exchange authorization code for access token.\n    request.post(accessTokenUrl, {json: true, form: params}, getAccessToken);\n}\n"
  },
  {
    "path": "app/models/article.js",
    "content": "'use strict';\n\nmodule.exports = function(sequelize, DataTypes) {\n\n\tvar Article = sequelize.define('Article', {\n\t\t\ttitle: DataTypes.STRING,\n\t\t\tcontent: DataTypes.TEXT\n\t\t},\n\t\t{\n\t\t\tassociate: function(models){\n\t\t\t\tArticle.belongsTo(models.User);\n\t\t\t}\n\t\t}\n\t);\n\n\treturn Article;\n};\n"
  },
  {
    "path": "app/models/user.js",
    "content": "'use strict';\n\n/**\n\t* User Model\n\t*/\n\nvar crypto = require('crypto');\n\nmodule.exports = function(sequelize, DataTypes) {\n\n\tvar User = sequelize.define('User', \n\t\t{\n\t\t\tname: DataTypes.STRING,\n\t\t\temail: DataTypes.STRING,\n\t\t\tusername: DataTypes.STRING,\n\t\t\thashedPassword: DataTypes.STRING,\n\t\t\tprovider: DataTypes.STRING,\n\t\t\tsalt: DataTypes.STRING, \n\t\t\tfacebookUserId: DataTypes.INTEGER,\n\t\t\ttwitterUserId: DataTypes.INTEGER,\n\t\t\ttwitterKey: DataTypes.STRING,\n\t\t\ttwitterSecret: DataTypes.STRING,\n\t\t\tgithub: DataTypes.STRING,\n\t\t\topenId: DataTypes.STRING\n\t\t},\n\t\t{\n\t\t\tinstanceMethods: {\n\t\t\t\ttoJSON: function () {\n\t\t\t\t\tvar values = this.get();\n\t\t\t\t\tdelete values.hashedPassword;\n\t\t\t\t\tdelete values.salt;\n\t\t\t\t\treturn values;\n\t\t\t\t},\n\t\t\t\tmakeSalt: function() {\n\t\t\t\t\treturn crypto.randomBytes(16).toString('base64'); \n\t\t\t\t},\n\t\t\t\tauthenticate: function(plainText){\n\t\t\t\t\treturn this.encryptPassword(plainText, this.salt) === this.hashedPassword;\n\t\t\t\t},\n\t\t\t\tencryptPassword: function(password, salt) {\n\t\t\t\t\tif (!password || !salt) {\n                        return '';\n                    }\n\t\t\t\t\tsalt = new Buffer(salt, 'base64');\n\t\t\t\t\treturn crypto.pbkdf2Sync(password, salt, 10000, 64).toString('base64');\n\t\t\t\t}\n\t\t\t},\n\t\t\tassociate: function(models) {\n\t\t\t\tUser.hasMany(models.Article);\n\t\t\t}\n\t\t}\n\t);\n\n\treturn User;\n};\n"
  },
  {
    "path": "app/routes/articles.js",
    "content": "'use strict';\n\n/**\n* Module dependencies.\n*/\nvar users = require('../../app/controllers/users'),\narticles = require('../../app/controllers/articles');\n\nmodule.exports = function(app) {\n// Article Routes\napp.route('/articles')\n    .get(articles.all)\n    .post(users.requiresLogin, articles.create);\napp.route('/articles/:articleId')\n    .get(articles.show)\n    .put(users.requiresLogin, articles.hasAuthorization, articles.update)\n    .delete(users.requiresLogin, articles.hasAuthorization, articles.destroy);\n\n// Finish with setting up the articleId param\n// Note: the articles.article function will be called everytime then it will call the next function.\napp.param('articleId', articles.article);\n};\n\n"
  },
  {
    "path": "app/routes/index.js",
    "content": "'use strict';\n\nmodule.exports = function(app) {\n// Home route\nvar index = require('../../app/controllers/index');\napp.get('/', index.render);\n};\n\n"
  },
  {
    "path": "app/routes/users.js",
    "content": "'use strict';\n\n/**\n * Module dependencies.\n */\nvar passport = require('passport');\n\nmodule.exports = function (app) {\n// User Routes\n    var users = require('../../app/controllers/users');\n\n// User Routes\n    app.get('/signout', users.signout);\n    app.get('/users/me', users.me);\n\n// Setting up the users api\n    app.post('/users', users.create);\n\n// Setting the local strategy route\n    app.post('/users/session', passport.authenticate('local', {\n        failureRedirect: '/signin',\n        failureFlash: true\n    }), users.session);\n\n\n    // Setting social authentication routes\n\n// Setting the facebook oauth route\n\n    app.post('/auth/facebook/token', users.facebookUser);\n\n\n    app.post('/auth/google', users.googleSocailUser);\n\n    // Setting the twitter oauth route\n    app.post('/auth/twitter', users.twitterSocialUser);\n\n    // Finish with setting up the userId param\n    app.param('userId', users.user);\n\n\n};\n\n"
  },
  {
    "path": "app/views/404.jade",
    "content": "extends layouts/default\n\nblock main\n  h1 Oops something went wrong\n  br\n  span 404\n\nblock content\n  #error-message-box\n    #error-stack-trace\n      pre\n        code!= error\n\n"
  },
  {
    "path": "app/views/500.jade",
    "content": "extends layouts/default\n\nblock main\n  h1 Oops something went wrong\n  br\n  span 500\n\nblock content\n  #error-message-box\n    #error-stack-trace\n      pre\n        code!= error\n"
  },
  {
    "path": "app/views/includes/foot.jade",
    "content": "//AngularJS\nscript(type='text/javascript', src='/lib/angular/angular.js')\nscript(type='text/javascript', src='/lib/angular-cookies/angular-cookies.js')\nscript(type='text/javascript', src='/lib/angular-resource/angular-resource.js')\nscript(type='text/javascript', src='/lib/angular-ui-router/release/angular-ui-router.min.js')\n\n//Angular UI\nscript(type='text/javascript', src='/lib/angular-bootstrap/ui-bootstrap.js')\nscript(type='text/javascript', src='/lib/angular-bootstrap/ui-bootstrap-tpls.js')\nscript(type='text/javascript', src='/lib/angular-ui-utils/modules/route/route.js')\nscript(type='text/javascript', src='/lib/satellizer/satellizer.min.js')\nscript(type='text/javascript', src='/js/FbSdk.js')\nscript(type='text/javascript', src='/lib/social/angular-fblogin.js')\n\n//Application Init\nscript(type='text/javascript', src='/js/app.js')\nscript(type='text/javascript', src='/js/config.js')\nscript(type='text/javascript', src='/js/directives.js')\nscript(type='text/javascript', src='/js/filters.js')\n\n//Application Services\nscript(type='text/javascript', src='/js/services/global.js')\nscript(type='text/javascript', src='/js/services/articles.js')\nscript(type='text/javascript', src='/js/services/authenticate.js')\n\n//Application Controllers\nscript(type='text/javascript', src='/js/controllers/articles.js')\nscript(type='text/javascript', src='/js/controllers/index.js')\nscript(type='text/javascript', src='/js/controllers/header.js')\nscript(type='text/javascript', src='/js/controllers/users/auth.js')\nscript(type='text/javascript', src='/js/controllers/users/signIn.js')\nscript(type='text/javascript', src='/js/controllers/users/signUp.js')\nscript(type='text/javascript', src='/js/init.js')\n\n\nif (process.env.NODE_ENV == 'development')\n    //Livereload script rendered \n    script(type='text/javascript', src='http://localhost:35729/livereload.js')\n"
  },
  {
    "path": "app/views/includes/head.jade",
    "content": "head\n  meta(charset='utf-8')\n  meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1')\n  meta(name='viewport', content='width=device-width,initial-scale=1')\n\n  title= appName+' - '+title\n  meta(http-equiv='Content-type', content='text/html;charset=UTF-8')\n  meta(name=\"keywords\", content=\"node.js, express, mongoose, mongodb, angularjs\")\n  meta(name=\"description\", content=\"MEAN - A Modern Stack: MongoDB, ExpressJS, AngularJS, NodeJS. (BONUS: Passport User Support).\")\n\n  link(href='/img/icons/favicon.ico', rel='shortcut icon', type='image/x-icon')\n  \n  meta(property='fb:app_id', content='APP_ID')\n  meta(property='og:title', content='#{appName} - #{title}')\n  meta(property='og:description', content='MEAN - A Modern Stack: MongoDB, ExpressJS, AngularJS, NodeJS. (BONUS: Passport User Support).')\n  meta(property='og:type', content='website')\n  meta(property='og:url', content='APP_URL')\n  meta(property='og:image', content='APP_LOGO')\n  meta(property='og:site_name', content='MEAN - A Modern Stack')\n  meta(property='fb:admins', content='APP_ADMIN')\n\n  link(rel='stylesheet', href='/lib/bootstrap/docs/assets/css/bootstrap.css')\n  //- link(rel='stylesheet', href='/lib/bootstrap/dist/css/bootstrap-responsive.css')\n  link(rel='stylesheet', href='/css/common.css')\n\n  link(rel='stylesheet', href='/css/views/articles.css')\n\n  //if lt IE 9\n    script(src='http://html5shim.googlecode.com/svn/trunk/html5.js')\n"
  },
  {
    "path": "app/views/index.jade",
    "content": "extends layouts/default\n\nblock content\n  section(ui-view)\n  script(type=\"text/javascript\").\n    window.user = !{user};\n"
  },
  {
    "path": "app/views/layouts/default.jade",
    "content": "doctype html\nhtml(lang='en', xmlns='http://www.w3.org/1999/xhtml', xmlns:fb='https://www.facebook.com/2008/fbml', itemscope='itemscope', itemtype='http://schema.org/Product')\n  base(href='/')\n  include ../includes/head\n  body\n    .navbar.navbar-inverse.navbar-fixed-top(data-ng-include=\"'views/header.html'\", data-role=\"navigation\")\n    section.content\n      section.container\n        block content\n    include ../includes/foot\n"
  },
  {
    "path": "app.js",
    "content": "'use strict';\n\n/**\n * Module dependencies.\n */\nvar express     = require('express');\nvar fs          = require('fs');\n\n/**\n * Main application entry file.\n * Please note that the order of loading is important.\n */\n\n// Load Configurations\nvar config          = require('./config/config');\nvar winston         = require('./config/winston');\n\nwinston.info('Starting '+config.app.name+'...');\nwinston.info('Config loaded: '+config.NODE_ENV);\nwinston.debug('Accepted Config:',config);\n\nvar db              = require('./config/sequelize');\nvar passport        = require('./config/passport');\n\nvar app = express();\n\n//Initialize Express\nrequire('./config/express')(app, passport);\n\n//Start the app by listening on <port>\napp.listen(config.PORT);\nwinston.info('Express app started on port ' + config.PORT);\n\n//expose app\nmodule.exports = app;\n"
  },
  {
    "path": "app.json",
    "content": "{\n    \"name\": \"mean-stack-relational\",\n    \"description\": \"M*EAN - A Modern Stack: MySQL(Postgres for Heroku), ExpressJS, AngularJS, NodeJS. (BONUS: Passport User Support).\",\n    \"repository\": \"https://github.com/jpotts18/mean-stack-relational.git\",\n    \"logo\": \"https://raw.githubusercontent.com/jpotts18/mean-stack-relational/master/public/img/m_logo.png\",\n    \"keywords\": [\"node\", \"express\", \"static\"],\n    \"env\": {\n        \"WEB_CONCURRENCY\": {\n            \"description\": \"The number of processes to run.\",\n            \"value\": \"1\"\n        }\n    },\n    \"addons\": [\n        \"heroku-postgresql:hobby-dev\"\n    ]\n}\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"mean\",\n  \"version\": \"0.1.0\",\n  \"dependencies\": {\n    \"angular\": \"latest\",\n    \"angular-resource\": \"latest\",\n    \"angular-cookies\": \"latest\",\n    \"angular-mocks\": \"latest\",\n    \"angular-route\": \"latest\",\n    \"bootstrap\": \"2.3.2\",\n    \"angular-bootstrap\": \"0.7.0\",\n    \"angular-ui-utils\": \"0.0.4\",\n    \"angular-ui-router\": \"~0.3.1\",\n    \"satellizer\": \"^0.15.5\",\n    \"bower\": \"*\",\n    \"install\": \"^1.0.4\",\n    \"angular-fblogin\": \"*\"\n  }\n}\n"
  },
  {
    "path": "config/config.js",
    "content": "'use strict';\n\nvar nconf = require('nconf'),\n    json5 = require('json5'),\n    _ = require('lodash'),\n    glob = require('glob'),\n    path = require('path'),\n    fs = require('fs'),\n    StandardError = require('standard-error');\n\n\nvar rootPath = path.normalize(__dirname + '/..');\n\n// Load app configuration\nvar computedConfig = {\n    root: rootPath,\n    modelsDir : rootPath + '/app/models'\n};\n\n//\n// Setup nconf to use (in-order):\n//   1. Locally computed config\n//   2. Command-line arguments\n//   3. Some Environment variables\n//   4. Some defaults\n//   5. Environment specific config file located at './env/<NODE_ENV>.json'\n//   6. Shared config file located at './env/all.json'\n//\nnconf.argv()\n    .env(['PORT','NODE_ENV','FORCE_DB_SYNC','forceSequelizeSync'])// Load select environment variables\n    .defaults({store:{\n            NODE_ENV:'development'\n    }});\nvar envConfigPath = rootPath + '/config/env/'+nconf.get('NODE_ENV')+'.json5';\ntry{\n    if(!fs.statSync(envConfigPath).isFile()){\n        throw new Error(); // throw error to trigger catch\n    }\n}\ncatch(err){\n    throw new StandardError('Environment specific config file not found! Throwing up! (NODE_ENV='\n        +nconf.get('NODE_ENV')+')');\n}\nnconf.file(nconf.get('NODE_ENV'),{ file: envConfigPath, type:'file', format:json5 })\n    .file('shared',{ file: rootPath+ '/config/env/all.json5', type:'file', format:json5 })\n    .add('base-defaults',{type:'literal', store:{\n        PORT:5555\n    }})\n    .overrides({store:computedConfig});\n\nmodule.exports = nconf.get();\n/**\n * Get files by glob patterns\n */\nmodule.exports.getGlobbedFiles = function(globPatterns, removeRoot) {\n\t// For context switching\n\tvar _this = this;\n\n\t// URL paths regex\n\tvar urlRegex = new RegExp('^(?:[a-z]+:)?\\/\\/', 'i');\n\n\t// The output array\n\tvar output = [];\n\n\t// If glob pattern is array so we use each pattern in a recursive way, otherwise we use glob \n\tif (_.isArray(globPatterns)) {\n\t\tglobPatterns.forEach(function(globPattern) {\n\t\t\toutput = _.union(output, _this.getGlobbedFiles(globPattern, removeRoot));\n\t\t});\n\t} else if (_.isString(globPatterns)) {\n\t\tif (urlRegex.test(globPatterns)) {\n\t\t\toutput.push(globPatterns);\n\t\t} else {\n\t\t\tvar files = glob(globPatterns, { sync: true });\n\n\t\t\tif (removeRoot) {\n\t\t\t\tfiles = files.map(function(file) {\n\t\t\t\t\treturn file.replace(removeRoot, '');\n\t\t\t\t});\n\t\t\t}\n\n\t\t\toutput = _.union(output, files);\n\t\t}\n\t}\n\n\treturn output;\n};\n\n/**\n * Get the modules JavaScript files\n */\nmodule.exports.getJavaScriptAssets = function(includeTests) {\n\tvar output = this.getGlobbedFiles(this.assets.lib.js.concat(this.assets.js), 'public/');\n\n\t// To include tests\n\tif (includeTests) {\n\t\toutput = _.union(output, this.getGlobbedFiles(this.assets.tests));\n\t}\n\n\treturn output;\n};\n\n/**\n * Get the modules CSS files\n */\nmodule.exports.getCSSAssets = function() {\n\tvar output = this.getGlobbedFiles(this.assets.lib.css.concat(this.assets.css), 'public/');\n\treturn output;\n};\n"
  },
  {
    "path": "config/env/all.json5",
    "content": "{\n\tPORT: 3000, // capital PORT allows auto override by common env variable if it exists\n\tFORCE_DB_SYNC: \"false\", // must be string to allow environment variable override\n    enableSequelizeLog: \"true\", // type chosen as string for no particular reason\n    expressSessionSecret: '$uper$ecret$e$$ionKey' // replace with your own in production\n}\n"
  },
  {
    "path": "config/env/development.json5.sample",
    "content": "{\n    // This is your MYSQL Database configuration\n    db: {\n        name: \"mean_relational\",\n        password: \"\",\n        username: \"root\",\n        host: \"localhost\",\n        port: 3306\n    },\n    app: {\n        name: \"M*EAN Stack Relational - Development\"\n    },\n    // You will need to get your own client id's before this will work properly\n    facebook: {\n        clientID: \"<CLIENT ID>\",\n        clientSecret: \"<CLIENT SECRET>\",\n        callbackURL: \"http://localhost:3000/auth/facebook/callback\"\n    },\n    twitter: {\n        clientID: \"<CLIENT ID>\",\n        clientSecret: \"<CLIENT SECRET>\",\n        callbackURL: \"http://localhost:3000/auth/twitter/callback\"\n    },\n    google: {\n        realm: \"http://localhost:3000/\",\n        callbackURL: \"http://localhost:3000/auth/google/callback\"\n    }\n}\n"
  },
  {
    "path": "config/env/production.json5.sample",
    "content": "{\n    // This is your MYSQL Database configuration\n    db: {\n        name: \"mean_relational\",\n        password: \"\",\n        username: \"root\",\n        host:\"localhost\",\n        port:3306\n    },\n    app: {\n        name: \"M*EAN Stack Relational - Production\"\n    },\n    // You will need to get your own client id's before this will work properly\n    facebook: {\n        clientID: \"<CLIENT ID>\",\n        clientSecret: \"<CLIENT SECRET>\",\n        callbackURL: \"http://localhost:3000/auth/facebook/callback\"\n    },\n    twitter: {\n        clientID: \"<CLIENT ID>\",\n        clientSecret: \"<CLIENT SECRET>\",\n        callbackURL: \"http://localhost:3000/auth/twitter/callback\"\n    },\n    google: {\n        realm: \"http://localhost:3000/\",\n        callbackURL: \"http://localhost:3000/auth/google/callback\"\n    }\n}"
  },
  {
    "path": "config/env/test.json5.sample",
    "content": "{\n    PORT: 3001,\n    // This is your MYSQL test database configuration\n    db: {\n        name: \"mean_relational_test\",\n        password: \"\",\n        username: \"root\",\n        host: \"localhost\",\n        port: 3306\n    },\n    app: {\n        name: \"M*EAN Stack Relational - Test\"\n    },\n    // You will need to get your own client id's before this will work properly\n    facebook: {\n        clientID: \"<CLIENT ID>\",\n        clientSecret: \"<CLIENT SECRET>\",\n        callbackURL: \"http://localhost:3000/auth/facebook/callback\"\n    },\n    twitter: {\n        clientID: \"<CLIENT ID>\",\n        clientSecret: \"<CLIENT SECRET>\",\n        callbackURL: \"http://localhost:3000/auth/twitter/callback\"\n    },\n    google: {\n        realm: \"http://localhost:3000/\",\n        callbackURL: \"http://localhost:3000/auth/google/callback\"\n    }\n}"
  },
  {
    "path": "config/env/travis.json",
    "content": "{\n    \"db\": \"mongodb://localhost/mean-travis\",\n    \"port\": 3001,\n    \"app\": {\n        \"name\": \"MEAN - A Modern Stack - Test on travis\"\n    },\n    \"facebook\": {\n        \"clientID\": \"APP_ID\",\n        \"clientSecret\": \"APP_SECRET\",\n        \"callbackURL\": \"http://localhost:3000/auth/facebook/callback\"\n    },\n    \"twitter\": {\n        \"clientID\": \"CONSUMER_KEY\",\n        \"clientSecret\": \"CONSUMER_SECRET\",\n        \"callbackURL\": \"http://localhost:3000/auth/twitter/callback\"\n    },\n    \"github\": {\n        \"clientID\": \"APP_ID\",\n        \"clientSecret\": \"APP_SECRET\",\n        \"callbackURL\": \"http://localhost:3000/auth/github/callback\"\n    },\n    \"google\": {\n        \"clientID\": \"APP_ID\",\n        \"clientSecret\": \"APP_SECRET\",\n        \"callbackURL\": \"http://localhost:3000/auth/google/callback\"\n    }\n}"
  },
  {
    "path": "config/express.js",
    "content": "'use strict';\n\n/**\n * Module dependencies.\n */\nvar express = require('express');\nvar flash = require('connect-flash');\nvar helpers = require('view-helpers');\nvar compression = require('compression');\nvar favicon = require('serve-favicon');\nvar logger = require('morgan');\nvar cookieParser = require('cookie-parser');\nvar bodyParser = require('body-parser');\nvar methodOverride = require('method-override');\nvar path = require('path');\nvar sessionMiddleware = require('./middlewares/session');\nvar config = require('./config');\nvar winston = require('./winston');\n\nmodule.exports = function(app, passport) {\n\n    winston.info('Initializing Express');\n\n    app.set('showStackError', true);    \n    \n    //Prettify HTML\n    app.locals.pretty = true;\n\n    //Should be placed before express.static\n    app.use(compression({\n        filter: function(req, res) {\n            return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));\n        },\n        level: 9\n    }));\n\n    //Setting the fav icon and static folder\n    app.use(favicon(config.root + '/public/img/icons/favicon.ico'));\n    app.use(express.static(config.root + '/public'));\n\n    //Don't use logger for test env\n    if (config.NODE_ENV !== 'test') {\n        app.use(logger('dev', { \"stream\": winston.stream }));\n    }\n\n    //Set views path, template engine and default layout\n    app.set('views', config.root + '/app/views');\n    app.set('view engine', 'jade');\n\n    //Enable jsonp\n    app.enable(\"jsonp callback\");\n\n    //cookieParser should be above session\n    app.use(cookieParser());\n\n    // request body parsing middleware should be above methodOverride\n    app.use(bodyParser.urlencoded({ extended: true }));\n    app.use(bodyParser.json());\n    app.use(methodOverride());\n\n    //express session configuration\n    app.use(sessionMiddleware);\n\n    //connect flash for flash messages\n    app.use(flash());\n\n    //dynamic helpers\n    app.use(helpers(config.app.name));\n\n    //use passport session\n    app.use(passport.initialize());\n    app.use(passport.session());\n\n    // Globbing routing files\n    config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {\n      require(path.resolve(routePath))(app);\n    });\n\n    app.get('*',  function (req, res, next) {\n            res.render('index');\n    });\n\n    app.use(function(err, req, res, next) {\n\n        //Log it\n        winston.error(err);\n\n        //Error page\n        res.status(500).render('500', {\n            error: err.stack\n        });\n    });\n\n};\n"
  },
  {
    "path": "config/middlewares/session.js",
    "content": "'use strict';\n\nvar config = require('./../config'),\n    session = require('express-session'),\n    db = require('./../sequelize') ;\n\nvar sequelizeStore = require('express-sequelize-session')(session.Store);\n\nvar sessionMiddleware = session({\n    resave: true,\n    saveUninitialized: true,\n    store: new sequelizeStore(db.sequelize),\n    cookie:{maxAge:1000*3600*24*7}, //remember for 7 days\n    secret: config.expressSessionSecret/*||'$uper$ecret$e$$ionKey'*/\n});\n\nmodule.exports = sessionMiddleware;\n"
  },
  {
    "path": "config/passport.js",
    "content": "'use strict';\n\nvar passport = require('passport'),\n    _ = require('lodash');\n// These are different types of authentication strategies that can be used with Passport. \nvar LocalStrategy = require('passport-local').Strategy,\n   FacebookTokenStrategy = require('passport-facebook-token'),\n   config = require('./config'),\n   db = require('./sequelize'),\n   winston = require('./winston');\n\n//Serialize sessions\npassport.serializeUser(function(user, done) {\n  done(null, user.id);\n});\n\npassport.deserializeUser(function(id, done) {\n    db.User.find({where: {id: id}}).then(function(user){\n        if(!user){\n            winston.warn('Logged in user not in database, user possibly deleted post-login');\n            return done(null, false);\n        }\n        winston.info('Session: { id: ' + user.id + ', username: ' + user.username + ' }');\n        done(null, user);\n    }).catch(function(err){\n        done(err, null);\n    });\n});\n\n//Use local strategy\npassport.use(new LocalStrategy({\n    usernameField: 'email',\n    passwordField: 'password'\n  },\n  function(email, password, done) {\n    db.User.find({ where: { email: email }}).then(function(user) {\n      if (!user) {\n        done(null, false, { message: 'Unknown user' });\n      } else if (!user.authenticate(password)) {\n        done(null, false, { message: 'Invalid password'});\n      } else {\n        winston.info('Login (local) : { id: ' + user.id + ', username: ' + user.username + ' }');\n        done(null, user);\n      }\n    }).catch(function(err){\n      done(err);\n    });\n  }\n));\n\npassport.use(new FacebookTokenStrategy({\n        clientID: config.facebook.clientID,\n        clientSecret: config.facebook.clientSecret,\n        profileFields: ['id', 'first_name', 'last_name', 'email', 'photos']\n    }, function (accessToken, refreshToken, profile, done) {\n\n        db.User.find({where : {email: profile.emails[0].value}}).then(function(user){\n            if(!user){\n                db.User.create({\n                    name: profile.name.givenName || '',\n                    email: profile.emails[0].value,\n                    username: profile.name.givenName || '',\n                    provider: 'facebook',\n                    facebookUserId: profile.id\n                }).then(function(u){\n                    winston.info('New User (facebook) : { id: ' + u.id + ', username: ' + u.username + ' }');\n                    done(null, u);\n                })\n            } else {\n                winston.info('Login (facebook) : { id: ' + user.id + ', username: ' + user.username + ' }');\n                done(null, user);\n            }\n        }).catch(function(err){\n            done(err, null);\n        });\n\n    }\n\n));\n\nmodule.exports = passport;\n\n"
  },
  {
    "path": "config/sequelize.js",
    "content": "'use strict';\n\nvar fs = require('fs');\nvar path = require('path');\nvar Sequelize = require('sequelize');\nvar _ = require('lodash');\nvar config = require('./config');\nvar winston = require('./winston');\nvar db = {};\n\n\nwinston.info('Initializing Sequelize...');\n\n// create your instance of sequelize\nvar onHeroku = !!process.env.DYNO;\nwinston.info('Checking if running on Heroku: ',onHeroku);\n\nvar sequelize =  onHeroku ?\n    new Sequelize(process.env.DATABASE_URL, {\n        dialect: 'postgres',\n        protocol: 'postgres',\n        dialectOptions: {\n            ssl: true\n        }\n    })\n    :\n    new Sequelize(config.db.name, config.db.username, config.db.password, {\n        host: config.db.host,\n        port: config.db.port,\n        dialect: 'mysql',\n        storage: config.db.storage,\n        logging: config.enableSequelizeLog === 'true' ? winston.verbose : false\n    });\n\n// loop through all files in models directory ignoring hidden files and this file\nfs.readdirSync(config.modelsDir)\n    .filter(function (file) {\n        return (file.indexOf('.') !== 0) && (file !== 'index.js')\n    })\n    // import model files and save model names\n    .forEach(function (file) {\n        winston.info('Loading model file ' + file);\n        var model = sequelize.import(path.join(config.modelsDir, file));\n        db[model.name] = model;\n    });\n\n// invoke associations on each of the models\nObject.keys(db).forEach(function (modelName) {\n    if (db[modelName].options.hasOwnProperty('associate')) {\n        db[modelName].options.associate(db)\n    }\n});\n\n// Synchronizing any model changes with database. \n// set FORCE_DB_SYNC=true in the environment, or the program parameters to drop the database,\n//   and force model changes into it, if required;\n// Caution: Do not set FORCE_DB_SYNC to true for every run to avoid losing data with restarts\nsequelize\n    .sync({\n        force: config.FORCE_DB_SYNC === 'true',\n        logging: config.enableSequelizeLog === 'true' ? winston.verbose : false\n    })\n    .then(function () {\n        winston.info(\"Database \" + (config.FORCE_DB_SYNC === 'true' ? \"*DROPPED* and \" : \"\") + \"synchronized\");\n    }).catch(function (err) {\n        winston.error(\"An error occurred: \", err);\n    });\n\n// assign the sequelize variables to the db object and returning the db. \nmodule.exports = _.extend({\n    sequelize: sequelize,\n    Sequelize: Sequelize\n}, db);"
  },
  {
    "path": "config/winston.js",
    "content": "'use strict';\n\n/**\n * Created by Junaid Anwar on 5/28/15.\n */\nvar winston = require('winston');\nvar logger = new (winston.Logger)();\n\nlogger.add(winston.transports.Console, {\n    level: 'verbose',\n    prettyPrint: true,\n    colorize: true,\n    silent: false,\n    timestamp: false\n});\n\nlogger.stream = {\n    write: function(message, encoding){\n        logger.info(message);\n    }\n};\n\nmodule.exports = logger;\n"
  },
  {
    "path": "gruntfile.js",
    "content": "'use strict';\n\nmodule.exports = function(grunt) {\n    // Project Configuration\n    grunt.initConfig({\n        pkg: grunt.file.readJSON('package.json'),\n        watch: {\n            jade: {\n                files: ['app/views/**'],\n                options: {\n                    livereload: true,\n                },\n            },\n            js: {\n                files: ['public/js/**', 'app/**/*.js', 'config/**/*.js'],\n                tasks: ['jshint'],\n                options: {\n                    livereload: true,\n                },\n            },\n            html: {\n                files: ['public/views/**'],\n                options: {\n                    livereload: true,\n                },\n            },\n            css: {\n                files: ['public/css/**'],\n                options: {\n                    livereload: true\n                }\n            }\n        },\n        jshint: {\n            all:['gruntfile.js', 'public/js/**/*.js', 'test/mocha/**/*.js', 'test/karma/**/*.js', 'app/**/*.js'],\n            options: {\n                jshintrc: '.jshintrc',\n                reporter: require('jshint-stylish')\n            }\n        },\n        copy: {\n            options: {\n                punctuation: ''\n            },\n            js: {\n                files: [\n                    {cwd: 'bower_components/angular-bootstrap', src: ['**/*.js'], dest: 'public/lib/angular-bootstrap', expand: true},\n                    {cwd: 'bower_components/angular-cookies',   src: ['angular-cookies*'], dest: 'public/lib/angular-cookies',   expand: true}, \n                    {cwd: 'bower_components/angular-mocks',     src: ['**/*.js'], dest: 'public/lib/angular-mocks',     expand: true},\n                    {cwd: 'bower_components/angular-resource',  src: ['angular-resource*'], dest: 'public/lib/angular-resource',  expand: true},\n                    {cwd: 'bower_components/angular-route',     src: ['angular-route*'], dest: 'public/lib/angular-route',     expand: true},                    \n                    {cwd: 'bower_components/angular',   src: ['angular*'], dest: 'public/lib/angular',           expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/demo',                      src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/demo',                         expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/test',                      src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/test',                         expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules',                   src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules',                      expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/event',             src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/event',                expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/format',            src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/format',               expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/highlight',         src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/highlight',            expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/ie-shiv',           src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/ie-shiv',              expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/indeterminate',     src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/indeterminate',        expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/inflector',         src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/inflector',            expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/jq',                src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/jq',                   expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/keypress',          src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/keypress',             expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/mask',              src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/mask',                 expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/reset',             src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/reset',                expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/reset/stylesheets', src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/reset/stylesheets',    expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/route',             src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/route',                expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/scrollfix',         src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/scrollfix',            expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/showhide',          src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/showhide',             expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/unique',            src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/unique',               expand: true},\n                    {cwd: 'bower_components/angular-ui-utils/modules/validate',          src: ['**/*.js'], dest: 'public/lib/angular-ui-utils/modules/validate',             expand: true},\n                    {cwd: 'bower_components/bootstrap/js',                               src: ['*.js'],    dest: 'public/lib/bootstrap/js', expand: true},\n                    {cwd: 'bower_components/bootstrap/less',                             src: ['*.less'],  dest: 'public/lib/bootstrap/less', expand: true},\n                    {cwd: 'bower_components/bootstrap/docs/assets/css',                  src: ['*.*'],    dest: 'public/lib/bootstrap/docs/assets/css', expand: true},\n                    {cwd: 'bower_components/bootstrap/docs/assets/ico',                  src: ['*.*'],    dest: 'public/lib/bootstrap/docs/assets/ico', expand: true},\n                    {cwd: 'bower_components/bootstrap/docs/assets/img',                  src: ['*.*'],    dest: 'public/lib/bootstrap/docs/assets/img', expand: true},\n                    {cwd: 'bower_components/bootstrap/docs/assets/js',                   src: ['*.*'],    dest: 'public/lib/bootstrap/docs/assets/js', expand: true},\n                    {cwd: 'bower_components/satellizer/dist',                            src: ['**/*.js'],    dest: 'public/lib/satellizer', expand: true},\n                    {cwd: 'bower_components/angular-fblogin/dist',                       src: ['**/*.js'],    dest: 'public/lib/social', expand: true},\n                    {cwd: 'bower_components/jquery',                                     src: ['jquery*'], dest: 'public/lib/jquery', expand: true},\n                    {cwd: 'bower_components/angular-ui-router',                          src: ['release/*.js'], dest: 'public/lib/angular-ui-router', expand: true}\n\n                ]\n            }\n        },\n        nodemon: {\n            dev: {\n                script: 'app.js',\n                options: {\n                    args: ['--color'],\n                    ignore: ['README.md', 'node_modules/**', '.DS_Store'],\n                    ext: 'js',\n                    watch: ['app', 'config', 'app.js', 'gruntfile.js'],\n                    delay: 1000,\n                    env: {\n                        PORT: 3000\n                    },\n                    cwd: __dirname\n                }\n            }\n        },\n        concurrent: {\n            tasks: ['nodemon', 'watch'],\n            options: {\n                logConcurrentOutput: true\n            }\n        },\n        mochaTest: {\n            options: {\n                reporter: 'spec'\n            },\n            src: ['test/mocha/**/*.js']\n        },\n        env: {\n            test: {\n                NODE_ENV: 'test'\n            }\n        },\n        karma: {\n            unit: {\n                configFile: 'test/karma/karma.conf.js'\n            }\n        }\n    });\n\n    //Load NPM tasks\n    grunt.loadNpmTasks('grunt-contrib-watch');\n    grunt.loadNpmTasks('grunt-contrib-jshint');\n    grunt.loadNpmTasks('grunt-contrib-nodemon');\n    grunt.loadNpmTasks('grunt-concurrent');\n    grunt.loadNpmTasks('grunt-mocha-test');\n    grunt.loadNpmTasks('grunt-karma');\n    grunt.loadNpmTasks('grunt-env');\n    grunt.loadNpmTasks('grunt-copy');\n\n    //Making grunt default to force in order not to break the project.\n    grunt.option('force', true);\n\n    //Default task(s).\n    grunt.registerTask('default', ['copy', 'jshint', 'concurrent']);\n\n    //Test task.\n    grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);\n};"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"mean-stack-relational\",\n  \"description\": \"M*EAN - A Modern Stack: MySQL(Postgres for Heroku), ExpressJS, AngularJS, NodeJS. (BONUS: Passport User Support).\",\n  \"version\": \"0.2.2\",\n  \"private\": false,\n  \"author\": \"Jeff Potter\",\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/jpotts18/mean-stack-relational.git\"\n  },\n  \"engines\": {\n    \"node\": \"4.2.x\",\n    \"npm\": \"2.14.x\"\n  },\n  \"scripts\": {\n    \"start\": \"node node_modules/grunt-cli/bin/grunt\",\n    \"test\": \"node node_modules/grunt-cli/bin/grunt test\",\n    \"postinstall\": \"bower install && cp config/env/development.json5.sample config/env/development.json5 && cp config/env/production.json5.sample config/env/production.json5 && node node_modules/grunt-cli/bin/grunt copy\"\n  },\n  \"dependencies\": {\n    \"async\": \"latest\",\n    \"body-parser\": \"^1.14.1\",\n    \"bower\": \"latest\",\n    \"compression\": \"^1.6.0\",\n    \"connect-flash\": \"^0.1.1\",\n    \"cookie-parser\": \"^1.4.0\",\n    \"express\": \"^4.13.3\",\n    \"express-sequelize-session\": \"^0.4.0\",\n    \"express-session\": \"^1.12.1\",\n    \"glob\": \"^6.0.1\",\n    \"grunt\": \"^0.4.5\",\n    \"grunt-cli\": \"^0.1.13\",\n    \"grunt-copy\": \"latest\",\n    \"grunt-env\": \"latest\",\n    \"jade\": \"^1.11.0\",\n    \"jshint-stylish\": \"^2.1.0\",\n    \"json5\": \"^0.4.0\",\n    \"lodash\": \"latest\",\n    \"method-override\": \"^2.3.5\",\n    \"morgan\": \"^1.6.1\",\n    \"mysql\": \"^2.9.0\",\n    \"nconf\": \"^0.8.2\",\n    \"passport\": \"^0.3.2\",\n    \"passport-facebook\": \"^2.0.0\",\n    \"passport-google\": \"latest\",\n    \"passport-local\": \"^1.0.0\",\n    \"passport-twitter\": \"^1.0.3\",\n    \"pg\": \"^4.4.3\",\n    \"pm2\": \"^1.0.0\",\n    \"proxyquire\": \"^1.7.3\",\n    \"sequelize\": \"^3.13.0\",\n    \"serve-favicon\": \"^2.3.0\",\n    \"standard-error\": \"^1.1.0\",\n    \"view-helpers\": \"latest\",\n    \"winston\": \"latest\",\n    \"request\": \"2.75.0\",\n    \"qs\": \"6.2.1\",\n    \"passport-facebook-token\": \"3.3.0\"\n  },\n  \"devDependencies\": {\n    \"chai\": \"^3.2.0\",\n    \"grunt-concurrent\": \"latest\",\n    \"grunt-contrib-jshint\": \"latest\",\n    \"grunt-contrib-nodemon\": \"^0.5.2\",\n    \"grunt-contrib-watch\": \"latest\",\n    \"grunt-karma\": \"~0.6.2\",\n    \"grunt-mocha-test\": \"latest\",\n    \"karma\": \"~0.10.4\",\n    \"karma-chrome-launcher\": \"~0.1.0\",\n    \"karma-coffee-preprocessor\": \"~0.1.0\",\n    \"karma-coverage\": \"~0.1.0\",\n    \"karma-firefox-launcher\": \"~0.1.0\",\n    \"karma-html2js-preprocessor\": \"~0.1.0\",\n    \"karma-jasmine\": \"~0.1.3\",\n    \"karma-phantomjs-launcher\": \"~0.1.0\",\n    \"karma-requirejs\": \"~0.2.0\",\n    \"karma-script-launcher\": \"~0.1.0\",\n    \"mocha\": \"^2.2.5\",\n    \"supertest\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "pm2-ecosystem.json",
    "content": "{\n  \"apps\" : [{\n    // mean-stack-relational app\n    \"name\"       : \"msr\",\n    \"script\"     : \"app.js\",\n    // by default, the app runs in fork mode, uncomment below to run in cluster mode\n    //\"instances\"  : 4,\n    //\"exec_mode\"  : \"cluster_mode\",  // defaults to fork\n    \"args\"        : [\"--color\"],\n    \"watch\"       : true,\n    \"ignore_watch\" : [\"pids\", \"logs\", \"node_modules\", \"bower_components\"],\n    \"merge_logs\"  : true, // merge logs from all instances in cluster mode\n    \"cwd\"         : \".\",\n    \"error_file\"  : \"./logs/msr.log\",\n    \"out_file\"    : \"./logs/msr.log\",\n    \"pid_file\"    : \"./pids/msr.pid\",\n    \"min_uptime\"  : \"30s\", // defaults to 1000s\n    \"max_restarts\"  : 30, // defaults to 15\n    \"restart_delay\" : 1000,\n    \"max_memory_restart\" : \"8G\",  // restart app if it reaches an 8GB memory footprint\n    \"env\": {\n      \"NODE_ENV\": \"development\"\n    },\n    \"env_production\" : {\n      \"NODE_ENV\": \"production\"\n    }\n  }]\n}\n"
  },
  {
    "path": "pm2-main.js",
    "content": "var pm2 = require('pm2');\n\nvar instances = process.env.WEB_CONCURRENCY || 1; // Set by Heroku or 1 (set -1 to scale to max cpu core - 1)\nvar maxMemory = process.env.WEB_MEMORY || 512;    // 512 is the maximum free Dyno memory on Heroku\n\npm2.connect(function() {\n    pm2.start({\n        script    : 'app.js',\n        name      : 'msr',                // ----> THESE ATTRIBUTES ARE OPTIONAL:\n        exec_mode : 'cluster',               // set to 'cluster' for cluster execution\n        instances : instances,\n        max_memory_restart : maxMemory + 'M',   // Auto restart if process taking more than XXmo\n        env: {                            // If needed declare some environment variables\n            \"NODE_ENV\": \"production\"\n        }\n    }, function(err) {\n        if (err) return console.error('Error while launching applications', err.stack || err);\n        console.log('PM2 and application has been successfully started');\n\n        // Display logs in standard output\n        pm2.launchBus(function(err, bus) {\n            console.log('[PM2] Log streaming started');\n\n            bus.on('log:out', function(packet) {\n                console.log('[App:%s] %s', packet.process.name, packet.data);\n            });\n\n            bus.on('log:err', function(packet) {\n                console.error('[App:%s][Err] %s', packet.process.name, packet.data);\n            });\n        });\n\n    });\n});\n\n"
  },
  {
    "path": "public/css/common.css",
    "content": ".navbar .nav>li>a.brand {\n    padding-left:20px;\n    margin-left:0\n}\n\n.content {\n    margin-top:50px;\n    width:100%\n}\n\nfooter {\n    position:fixed;\n    left:0px;\n    bottom:0px;\n    height:30px;\n    width:100%;\n    background:#ddd;\n    -webkit-box-shadow:0 8px 6px 6px black;\n    -moz-box-shadow:0 8px 6px 6px black;\n    box-shadow:0 8px 6px 6px black\n}\n\nfooter p {\n    padding:5px 0 12px 10px\n}"
  },
  {
    "path": "public/css/views/articles.css",
    "content": "h1 {\n    text-align:center\n}\n\nul.articles li:not(:last-child) {\n    border-bottom:1px solid #ccc\n}"
  },
  {
    "path": "public/humans.txt",
    "content": "# humanstxt.org/\n# The humans responsible & technology colophon\n\n# TEAM\n\n    <name> -- <role> -- <twitter>\n\n# THANKS\n\n    <name>\n\n# TECHNOLOGY COLOPHON\n\n    HTML5, CSS3\n    jQuery, Modernizr\n"
  },
  {
    "path": "public/img/.gitignore",
    "content": ""
  },
  {
    "path": "public/js/FbSdk.js",
    "content": "/*1453279404,,JIT Construction: v2136283,en_US*/\n\n/**\n * Copyright Facebook Inc.\n *\n * Licensed under the Apache License, Version 2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n */\ntry {\n    window.FB || (function (window, fb_fif_window) {\n        var apply = Function.prototype.apply;\n        function bindContext(fn, thisArg) {\n            return function _sdkBound() {\n                return apply.call(fn, thisArg, arguments);\n            };\n        }\n        var global = {__type: 'JS_SDK_SANDBOX', window: window, document: window.document};\n        var sandboxWhitelist = ['setTimeout', 'setInterval', 'clearTimeout', 'clearInterval'];\n        for (var i = 0; i < sandboxWhitelist.length; i++) {\n            global[sandboxWhitelist[i]] = bindContext(window[sandboxWhitelist[i]], window);\n        }\n        (function () {\n            var self = window;\n            var __DEV__ = 0;\n            function emptyFunction() {\n            }\n            var __transform_includes = {};\n            var __annotator, __bodyWrapper;\n            var __w, __t;\n            var undefined;\n            with (this) {\n                (function () {\n                    var a = {}, b = function (i, j) {\n                        if (!i && !j)return null;\n                        var k = {};\n                        if (typeof i !== 'undefined')k.type = i;\n                        if (typeof j !== 'undefined')k.signature = j;\n                        return k;\n                    }, c = function (i, j) {\n                        return b(i && /^[A-Z]/.test(i) ? i : undefined, j && (j.params && j.params.length || j.returns) ? 'function(' + (j.params ? j.params.map(function (k) {\n                            return (/\\?/.test(k) ? '?' + k.replace('?', '') : k);\n                        }).join(',') : '') + ')' + (j.returns ? ':' + j.returns : '') : undefined);\n                    }, d = function (i, j, k) {\n                        return i;\n                    }, e = function (i, j, k) {\n                        if ('sourcemeta' in __transform_includes)i.__SMmeta = j;\n                        if ('typechecks' in __transform_includes) {\n                            var l = c(j ? j.name : undefined, k);\n                            if (l)__w(i, l);\n                        }\n                        return i;\n                    }, f = function (i, j, k) {\n                        return k.apply(i, j);\n                    }, g = function (i, j, k, l) {\n                        if (l && l.params)__t.apply(i, l.params);\n                        var m = k.apply(i, j);\n                        if (l && l.returns)__t([m, l.returns]);\n                        return m;\n                    }, h = function (i, j, k, l, m) {\n                        if (m) {\n                            if (!m.callId)m.callId = m.module + ':' + (m.line || 0) + ':' + (m.column || 0);\n                            var n = m.callId;\n                            a[n] = (a[n] || 0) + 1;\n                        }\n                        return k.apply(i, j);\n                    };\n                    if (typeof __transform_includes === 'undefined') {\n                        __annotator = d;\n                        __bodyWrapper = f;\n                    } else {\n                        __annotator = e;\n                        if ('codeusage' in __transform_includes) {\n                            __annotator = d;\n                            __bodyWrapper = h;\n                            __bodyWrapper.getCodeUsage = function () {\n                                return a;\n                            };\n                            __bodyWrapper.clearCodeUsage = function () {\n                                a = {};\n                            };\n                        } else if ('typechecks' in __transform_includes) {\n                            __bodyWrapper = g;\n                        } else __bodyWrapper = f;\n                    }\n                })();\n                __t=function(a){return a[0];};__w=function(a){return a;};\n    var require,__d;(function(a){var b={},c={},d=['global','require','requireDynamic','requireLazy','module','exports'];require=function(e,f){if(c.hasOwnProperty(e))return c[e];if(!b.hasOwnProperty(e)){if(f)return null;throw new Error('Module '+e+' has not been defined');}var g=b[e],h=g.deps,i=g.factory.length,j,k=[];for(var l=0;l<i;l++){switch(h[l]){case 'module':j=g;break;case 'exports':j=g.exports;break;case 'global':j=a;break;case 'require':j=require;break;case 'requireDynamic':j=require;break;case 'requireLazy':j=null;break;default:j=require.call(null,h[l]);}k.push(j);}g.factory.apply(a,k);c[e]=g.exports;return g.exports;};require.__markCompiled=function(){};__d=function(e,f,g,h){if(typeof g=='function'){b[e]={factory:g,deps:d.concat(f),exports:{}};if(h===3)require.call(null,e);}else c[e]=g;};})(this);\n    __d('ES5Array',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={};h.isArray=function(i){return Object.prototype.toString.call(i)=='[object Array]';};f.exports=h;},null);\n    __d('ES5ArrayPrototype',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={};h.map=function(i,j){if(typeof i!='function')throw new TypeError();var k,l=this.length,m=new Array(l);for(k=0;k<l;++k)if(k in this)m[k]=i.call(j,this[k],k,this);return m;};h.forEach=function(i,j){h.map.call(this,i,j);};h.filter=function(i,j){if(typeof i!='function')throw new TypeError();var k,l,m=this.length,n=[];for(k=0;k<m;++k)if(k in this){l=this[k];if(i.call(j,l,k,this))n.push(l);}return n;};h.every=function(i,j){if(typeof i!='function')throw new TypeError();var k=new Object(this),l=k.length;for(var m=0;m<l;m++)if(m in k)if(!i.call(j,k[m],m,k))return false;return true;};h.some=function(i,j){if(typeof i!='function')throw new TypeError();var k=new Object(this),l=k.length;for(var m=0;m<l;m++)if(m in k)if(i.call(j,k[m],m,k))return true;return false;};h.indexOf=function(i,j){var k=this.length;j|=0;if(j<0)j+=k;for(;j<k;j++)if(j in this&&this[j]===i)return j;return -1;};f.exports=h;},null);\n    __d(\"ES5Date\",[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={};h.now=function(){return new Date().getTime();};f.exports=h;},null);\n    __d('ES5FunctionPrototype',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={};h.bind=function(i){if(typeof this!='function')throw new TypeError('Bind must be called on a function');var j=this,k=Array.prototype.slice.call(arguments,1);function l(){return j.apply(i,k.concat(Array.prototype.slice.call(arguments)));}l.displayName='bound:'+(j.displayName||j.name||'(?)');l.toString=function m(){return 'bound: '+j;};return l;};f.exports=h;},null);\n    __d('ie8DontEnum',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=['toString','toLocaleString','valueOf','hasOwnProperty','isPrototypeOf','prototypeIsEnumerable','constructor'],i=({}).hasOwnProperty,j=function(){};if(({toString:true}).propertyIsEnumerable('toString'))j=function(k,l){for(var m=0;m<h.length;m++){var n=h[m];if(i.call(k,n))l(n);}};f.exports=j;},null);\n    __d('ES5Object',['ie8DontEnum'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i=({}).hasOwnProperty,j={};function k(){}j.create=function(l){var m=typeof l;if(m!='object'&&m!='function')throw new TypeError('Object prototype may only be a Object or null');k.prototype=l;return new k();};j.keys=function(l){var m=typeof l;if(m!='object'&&m!='function'||l===null)throw new TypeError('Object.keys called on non-object');var n=[];for(var o in l)if(i.call(l,o))n.push(o);h(l,function(p){return n.push(p);});return n;};f.exports=j;},null);\n    __d('ES5StringPrototype',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={};h.trim=function(){if(this==null)throw new TypeError('String.prototype.trim called on null or undefined');return String.prototype.replace.call(this,/^\\s+|\\s+$/g,'');};h.startsWith=function(i){var j=String(this);if(this==null)throw new TypeError('String.prototype.startsWith called on null or undefined');var k=arguments.length>1?Number(arguments[1]):0;if(isNaN(k))k=0;var l=Math.min(Math.max(k,0),j.length);return j.indexOf(String(i),k)==l;};h.endsWith=function(i){var j=String(this);if(this==null)throw new TypeError('String.prototype.endsWith called on null or undefined');var k=j.length,l=String(i),m=arguments.length>1?Number(arguments[1]):k;if(isNaN(m))m=0;var n=Math.min(Math.max(m,0),k),o=n-l.length;if(o<0)return false;return j.lastIndexOf(l,o)==o;};h.contains=function(i){if(this==null)throw new TypeError('String.prototype.contains called on null or undefined');var j=String(this),k=arguments.length>1?Number(arguments[1]):0;if(isNaN(k))k=0;return j.indexOf(String(i),k)!=-1;};h.repeat=function(i){if(this==null)throw new TypeError('String.prototype.repeat called on null or undefined');var j=String(this),k=i?Number(i):0;if(isNaN(k))k=0;if(k<0||k===Infinity)throw RangeError();if(k===1)return j;if(k===0)return '';var l='';while(k){if(k&1)l+=j;if(k>>=1)j+=j;}return l;};f.exports=h;},null);\n    __d('ES6Array',[],function a(b,c,d,e,f,g){'use strict';if(c.__markCompiled)c.__markCompiled();var h={from:function(i){if(i==null)throw new TypeError('Object is null or undefined');var j=arguments[1],k=arguments[2],l=this,m=Object(i),n=typeof Symbol==='function'?typeof Symbol==='function'?Symbol.iterator:'@@iterator':'@@iterator',o=typeof j==='function',p=typeof m[n]==='function',q=0,r,s;if(p){r=typeof l==='function'?new l():[];var t=m[n](),u;while(!(u=t.next()).done){s=u.value;if(o)s=j.call(k,s,q);r[q]=s;q+=1;}r.length=q;return r;}var v=m.length;if(isNaN(v)||v<0)v=0;r=typeof l==='function'?new l(v):new Array(v);while(q<v){s=m[q];if(o)s=j.call(k,s,q);r[q]=s;q+=1;}r.length=q;return r;}};f.exports=h;},null);\n    __d('ES6ArrayPrototype',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={find:function(i,j){if(this==null)throw new TypeError('Array.prototype.find called on null or undefined');if(typeof i!=='function')throw new TypeError('predicate must be a function');var k=h.findIndex.call(this,i,j);return k===-1?void 0:this[k];},findIndex:function(i,j){if(this==null)throw new TypeError('Array.prototype.findIndex called on null or undefined');if(typeof i!=='function')throw new TypeError('predicate must be a function');var k=Object(this),l=k.length>>>0;for(var m=0;m<l;m++)if(i.call(j,k[m],m,k))return m;return -1;},fill:function(i){if(this==null)throw new TypeError('Array.prototype.fill called on null or undefined');var j=Object(this),k=j.length>>>0,l=arguments[1],m=l>>0,n=m<0?Math.max(k+m,0):Math.min(m,k),o=arguments[2],p=o===undefined?k:o>>0,q=p<0?Math.max(k+p,0):Math.min(p,k);while(n<q){j[n]=i;n++;}return j;}};f.exports=h;},null);\n    __d('ES6DatePrototype',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(j){return (j<10?'0':'')+j;}var i={toISOString:function(){if(!isFinite(this))throw new Error('Invalid time value');var j=this.getUTCFullYear();j=(j<0?'-':j>9999?'+':'')+('00000'+Math.abs(j)).slice(0<=j&&j<=9999?-4:-6);return j+'-'+h(this.getUTCMonth()+1)+'-'+h(this.getUTCDate())+'T'+h(this.getUTCHours())+':'+h(this.getUTCMinutes())+':'+h(this.getUTCSeconds())+'.'+(this.getUTCMilliseconds()/1000).toFixed(3).slice(2,5)+'Z';}};f.exports=i;},null);\n    __d('ES6Number',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=Math.pow(2,-52),i=Math.pow(2,53)-1,j=-1*i,k={isFinite:function(l){return typeof l=='number'&&isFinite(l);},isNaN:function(l){return typeof l=='number'&&isNaN(l);},isInteger:function(l){return this.isFinite(l)&&Math.floor(l)===l;},isSafeInteger:function(l){return this.isFinite(l)&&l>=this.MIN_SAFE_INTEGER&&l<=this.MAX_SAFE_INTEGER&&Math.floor(l)===l;},EPSILON:h,MAX_SAFE_INTEGER:i,MIN_SAFE_INTEGER:j};f.exports=k;},null);\n    __d('ES6Object',['ie8DontEnum'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i=({}).hasOwnProperty,j={assign:function(k){if(k==null)throw new TypeError('Object.assign target cannot be null or undefined');k=Object(k);for(var l=arguments.length,m=Array(l>1?l-1:0),n=1;n<l;n++)m[n-1]=arguments[n];for(var o=0;o<m.length;o++){var p=m[o];if(p==null)continue;p=Object(p);for(var q in p)if(i.call(p,q))k[q]=p[q];h(p,function(r){return k[r]=p[r];});}return k;},is:function(k,l){if(k===l){return k!==0||1/k===1/l;}else return k!==k&&l!==l;}};f.exports=j;},null);\n    __d('ES7StringPrototype',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={};h.trimLeft=function(){return this.replace(/^\\s+/,'');};h.trimRight=function(){return this.replace(/\\s+$/,'');};f.exports=h;},null);\n    /**\n     * @providesModule JSON3\n     * @preserve-header\n     *\n     *! JSON v3.2.3 | http://bestiejs.github.com/json3 | Copyright 2012, Kit Cambridge | http://kit.mit-license.org\n     */__d(\"JSON3\",[],function a(b,c,d,e,f,g){c.__markCompiled&&c.__markCompiled();(function(){var h={}.toString,i,j,k,l=f.exports={},m='{\"A\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}',n,o,p,q,r,s,t,u,v,w,x,y,z,aa,ba,ca=new Date(-3509827334573292),da,ea,fa;try{ca=ca.getUTCFullYear()==-109252&&ca.getUTCMonth()===0&&ca.getUTCDate()==1&&ca.getUTCHours()==10&&ca.getUTCMinutes()==37&&ca.getUTCSeconds()==6&&ca.getUTCMilliseconds()==708;}catch(ga){}if(!ca){da=Math.floor;ea=[0,31,59,90,120,151,181,212,243,273,304,334];fa=function(ha,ia){return ea[ia]+365*(ha-1970)+da((ha-1969+(ia=+(ia>1)))/4)-da((ha-1901+ia)/100)+da((ha-1601+ia)/400);};}if(typeof JSON==\"object\"&&JSON){l.stringify=JSON.stringify;l.parse=JSON.parse;}if((n=typeof l.stringify==\"function\"&&!fa)){(ca=function(){return 1;}).toJSON=ca;try{n=l.stringify(0)===\"0\"&&l.stringify(Number())===\"0\"&&l.stringify(String())=='\"\"'&&l.stringify(h)===k&&l.stringify(k)===k&&l.stringify()===k&&l.stringify(ca)===\"1\"&&l.stringify([ca])==\"[1]\"&&l.stringify([k])==\"[null]\"&&l.stringify(null)==\"null\"&&l.stringify([k,h,null])==\"[null,null,null]\"&&l.stringify({result:[ca,true,false,null,\"\\0\\b\\n\\f\\r\\t\"]})==m&&l.stringify(null,ca)===\"1\"&&l.stringify([1,2],null,1)==\"[\\n 1,\\n 2\\n]\"&&l.stringify(new Date(-8.64e+15))=='\"-271821-04-20T00:00:00.000Z\"'&&l.stringify(new Date(8.64e+15))=='\"+275760-09-13T00:00:00.000Z\"'&&l.stringify(new Date(-62198755200000))=='\"-000001-01-01T00:00:00.000Z\"'&&l.stringify(new Date(-1))=='\"1969-12-31T23:59:59.999Z\"';}catch(ga){n=false;}}if(typeof l.parse==\"function\")try{if(l.parse(\"0\")===0&&!l.parse(false)){ca=l.parse(m);if((s=ca.A.length==5&&ca.A[0]==1)){try{s=!l.parse('\"\\t\"');}catch(ga){}if(s)try{s=l.parse(\"01\")!=1;}catch(ga){}}}}catch(ga){s=false;}ca=m=null;if(!n||!s){if(!(i={}.hasOwnProperty))i=function(ha){var ia={},ja;if((ia.__proto__=null,ia.__proto__={toString:1},ia).toString!=h){i=function(ka){var la=this.__proto__,ma=ka in (this.__proto__=null,this);this.__proto__=la;return ma;};}else{ja=ia.constructor;i=function(ka){var la=(this.constructor||ja).prototype;return ka in this&&!(ka in la&&this[ka]===la[ka]);};}ia=null;return i.call(this,ha);};j=function(ha,ia){var ja=0,ka,la,ma,na;(ka=function(){this.valueOf=0;}).prototype.valueOf=0;la=new ka();for(ma in la)if(i.call(la,ma))ja++;ka=la=null;if(!ja){la=[\"valueOf\",\"toString\",\"toLocaleString\",\"propertyIsEnumerable\",\"isPrototypeOf\",\"hasOwnProperty\",\"constructor\"];na=function(oa,pa){var qa=h.call(oa)==\"[object Function]\",ra,sa;for(ra in oa)if(!(qa&&ra==\"prototype\")&&i.call(oa,ra))pa(ra);for(sa=la.length;ra=la[--sa];i.call(oa,ra)&&pa(ra));};}else if(ja==2){na=function(oa,pa){var qa={},ra=h.call(oa)==\"[object Function]\",sa;for(sa in oa)if(!(ra&&sa==\"prototype\")&&!i.call(qa,sa)&&(qa[sa]=1)&&i.call(oa,sa))pa(sa);};}else na=function(oa,pa){var qa=h.call(oa)==\"[object Function]\",ra,sa;for(ra in oa)if(!(qa&&ra==\"prototype\")&&i.call(oa,ra)&&!(sa=ra===\"constructor\"))pa(ra);if(sa||i.call(oa,(ra=\"constructor\")))pa(ra);};return na(ha,ia);};if(!n){o={\"\\\\\":\"\\\\\\\\\",'\"':'\\\\\"',\"\\b\":\"\\\\b\",\"\\f\":\"\\\\f\",\"\\n\":\"\\\\n\",\"\\r\":\"\\\\r\",\"\\t\":\"\\\\t\"};p=function(ha,ia){return (\"000000\"+(ia||0)).slice(-ha);};q=function(ha){var ia='\"',ja=0,ka;for(;ka=ha.charAt(ja);ja++)ia+='\\\\\"\\b\\f\\n\\r\\t'.indexOf(ka)>-1?o[ka]:ka<\" \"?\"\\\\u00\"+p(2,ka.charCodeAt(0).toString(16)):ka;return ia+'\"';};r=function(ha,ia,ja,ka,la,ma,na){var oa=ia[ha],pa,qa,ra,sa,ta,ua,va,wa,xa,ya,za,ab,bb,cb,db;if(typeof oa==\"object\"&&oa){pa=h.call(oa);if(pa==\"[object Date]\"&&!i.call(oa,\"toJSON\")){if(oa>-1/0&&oa<1/0){if(fa){sa=da(oa/86400000);for(qa=da(sa/365.2425)+1970-1;fa(qa+1,0)<=sa;qa++);for(ra=da((sa-fa(qa,0))/30.42);fa(qa,ra+1)<=sa;ra++);sa=1+sa-fa(qa,ra);ta=(oa%86400000+86400000)%86400000;ua=da(ta/3600000)%24;va=da(ta/60000)%60;wa=da(ta/1000)%60;xa=ta%1000;}else{qa=oa.getUTCFullYear();ra=oa.getUTCMonth();sa=oa.getUTCDate();ua=oa.getUTCHours();va=oa.getUTCMinutes();wa=oa.getUTCSeconds();xa=oa.getUTCMilliseconds();}oa=(qa<=0||qa>=10000?(qa<0?\"-\":\"+\")+p(6,qa<0?-qa:qa):p(4,qa))+\"-\"+p(2,ra+1)+\"-\"+p(2,sa)+\"T\"+p(2,ua)+\":\"+p(2,va)+\":\"+p(2,wa)+\".\"+p(3,xa)+\"Z\";}else oa=null;}else if(typeof oa.toJSON==\"function\"&&((pa!=\"[object Number]\"&&pa!=\"[object String]\"&&pa!=\"[object Array]\")||i.call(oa,\"toJSON\")))oa=oa.toJSON(ha);}if(ja)oa=ja.call(ia,ha,oa);if(oa===null)return \"null\";pa=h.call(oa);if(pa==\"[object Boolean]\"){return \"\"+oa;}else if(pa==\"[object Number]\"){return oa>-1/0&&oa<1/0?\"\"+oa:\"null\";}else if(pa==\"[object String]\")return q(oa);if(typeof oa==\"object\"){for(bb=na.length;bb--;)if(na[bb]===oa)throw TypeError();na.push(oa);ya=[];cb=ma;ma+=la;if(pa==\"[object Array]\"){for(ab=0,bb=oa.length;ab<bb;db||(db=true),ab++){za=r(ab,oa,ja,ka,la,ma,na);ya.push(za===k?\"null\":za);}return db?(la?\"[\\n\"+ma+ya.join(\",\\n\"+ma)+\"\\n\"+cb+\"]\":(\"[\"+ya.join(\",\")+\"]\")):\"[]\";}else{j(ka||oa,function(eb){var fb=r(eb,oa,ja,ka,la,ma,na);if(fb!==k)ya.push(q(eb)+\":\"+(la?\" \":\"\")+fb);db||(db=true);});return db?(la?\"{\\n\"+ma+ya.join(\",\\n\"+ma)+\"\\n\"+cb+\"}\":(\"{\"+ya.join(\",\")+\"}\")):\"{}\";}na.pop();}};l.stringify=function(ha,ia,ja){var ka,la,ma,na,oa,pa;if(typeof ia==\"function\"||typeof ia==\"object\"&&ia)if(h.call(ia)==\"[object Function]\"){la=ia;}else if(h.call(ia)==\"[object Array]\"){ma={};for(na=0,oa=ia.length;na<oa;pa=ia[na++],((h.call(pa)==\"[object String]\"||h.call(pa)==\"[object Number]\")&&(ma[pa]=1)));}if(ja)if(h.call(ja)==\"[object Number]\"){if((ja-=ja%1)>0)for(ka=\"\",ja>10&&(ja=10);ka.length<ja;ka+=\" \");}else if(h.call(ja)==\"[object String]\")ka=ja.length<=10?ja:ja.slice(0,10);return r(\"\",(pa={},pa[\"\"]=ha,pa),la,ma,ka,\"\",[]);};}if(!s){t=String.fromCharCode;u={\"\\\\\":\"\\\\\",'\"':'\"',\"/\":\"/\",b:\"\\b\",t:\"\\t\",n:\"\\n\",f:\"\\f\",r:\"\\r\"};v=function(){aa=ba=null;throw SyntaxError();};w=function(){var ha=ba,ia=ha.length,ja,ka,la,ma,na;while(aa<ia){ja=ha.charAt(aa);if(\"\\t\\r\\n \".indexOf(ja)>-1){aa++;}else if(\"{}[]:,\".indexOf(ja)>-1){aa++;return ja;}else if(ja=='\"'){for(ka=\"@\",aa++;aa<ia;){ja=ha.charAt(aa);if(ja<\" \"){v();}else if(ja==\"\\\\\"){ja=ha.charAt(++aa);if('\\\\\"/btnfr'.indexOf(ja)>-1){ka+=u[ja];aa++;}else if(ja==\"u\"){la=++aa;for(ma=aa+4;aa<ma;aa++){ja=ha.charAt(aa);if(!(ja>=\"0\"&&ja<=\"9\"||ja>=\"a\"&&ja<=\"f\"||ja>=\"A\"&&ja<=\"F\"))v();}ka+=t(\"0x\"+ha.slice(la,aa));}else v();}else{if(ja=='\"')break;ka+=ja;aa++;}}if(ha.charAt(aa)=='\"'){aa++;return ka;}v();}else{la=aa;if(ja==\"-\"){na=true;ja=ha.charAt(++aa);}if(ja>=\"0\"&&ja<=\"9\"){if(ja==\"0\"&&(ja=ha.charAt(aa+1),ja>=\"0\"&&ja<=\"9\"))v();na=false;for(;aa<ia&&(ja=ha.charAt(aa),ja>=\"0\"&&ja<=\"9\");aa++);if(ha.charAt(aa)==\".\"){ma=++aa;for(;ma<ia&&(ja=ha.charAt(ma),ja>=\"0\"&&ja<=\"9\");ma++);if(ma==aa)v();aa=ma;}ja=ha.charAt(aa);if(ja==\"e\"||ja==\"E\"){ja=ha.charAt(++aa);if(ja==\"+\"||ja==\"-\")aa++;for(ma=aa;ma<ia&&(ja=ha.charAt(ma),ja>=\"0\"&&ja<=\"9\");ma++);if(ma==aa)v();aa=ma;}return +ha.slice(la,aa);}if(na)v();if(ha.slice(aa,aa+4)==\"true\"){aa+=4;return true;}else if(ha.slice(aa,aa+5)==\"false\"){aa+=5;return false;}else if(ha.slice(aa,aa+4)==\"null\"){aa+=4;return null;}v();}}return \"$\";};x=function(ha){var ia,ja,ka;if(ha==\"$\")v();if(typeof ha==\"string\"){if(ha.charAt(0)==\"@\")return ha.slice(1);if(ha==\"[\"){ia=[];for(;;ja||(ja=true)){ha=w();if(ha==\"]\")break;if(ja)if(ha==\",\"){ha=w();if(ha==\"]\")v();}else v();if(ha==\",\")v();ia.push(x(ha));}return ia;}else if(ha==\"{\"){ia={};for(;;ja||(ja=true)){ha=w();if(ha==\"}\")break;if(ja)if(ha==\",\"){ha=w();if(ha==\"}\")v();}else v();if(ha==\",\"||typeof ha!=\"string\"||ha.charAt(0)!=\"@\"||w()!=\":\")v();ia[ha.slice(1)]=x(w());}return ia;}v();}return ha;};z=function(ha,ia,ja){var ka=y(ha,ia,ja);if(ka===k){delete ha[ia];}else ha[ia]=ka;};y=function(ha,ia,ja){var ka=ha[ia],la;if(typeof ka==\"object\"&&ka)if(h.call(ka)==\"[object Array]\"){for(la=ka.length;la--;)z(ka,la,ja);}else j(ka,function(ma){z(ka,ma,ja);});return ja.call(ha,ia,ka);};l.parse=function(ha,ia){aa=0;ba=ha;var ja=x(w());if(w()!=\"$\")v();aa=ba=null;return ia&&h.call(ia)==\"[object Function]\"?y((ca={},ca[\"\"]=ja,ca),\"\",ia):ja;};}}}).call(this);},null);\n    __d('ES',['ES5ArrayPrototype','ES5FunctionPrototype','ES5StringPrototype','ES5Array','ES5Object','ES5Date','JSON3','ES6Array','ES6Object','ES6ArrayPrototype','ES6DatePrototype','ES6Number','ES7StringPrototype'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){if(c.__markCompiled)c.__markCompiled();var u=({}).toString,v={'JSON.stringify':n.stringify,'JSON.parse':n.parse},w={'Array.prototype':h,'Function.prototype':i,'String.prototype':j,Object:l,Array:k,Date:m},x={Object:p,'Array.prototype':q,'Date.prototype':r,Number:s,Array:o},y={'String.prototype':t};function z(ba){for(var ca in ba){if(!ba.hasOwnProperty(ca))continue;var da=ba[ca],ea=ca.split('.'),fa=ea.length==2?window[ea[0]][ea[1]]:window[ca];for(var ga in da){if(!da.hasOwnProperty(ga))continue;if(typeof da[ga]!=='function'){v[ca+'.'+ga]=da[ga];continue;}var ha=fa[ga];v[ca+'.'+ga]=ha&&/\\{\\s+\\[native code\\]\\s\\}/.test(ha)?ha:da[ga];}}}z(w);z(x);z(y);function aa(ba,ca,da){var ea=da?u.call(ba).slice(8,-1)+'.prototype':ba,fa=v[ea+'.'+ca]||ba[ca];if(typeof fa==='function'){for(var ga=arguments.length,ha=Array(ga>3?ga-3:0),ia=3;ia<ga;ia++)ha[ia-3]=arguments[ia];return fa.apply(ba,ha);}else if(fa)return fa;throw new Error('Polyfill '+ea+' does not have implementation of '+ca);}f.exports=aa;},null);\n    __d('sdk.babelHelpers',['ES5FunctionPrototype','ES5Object','ES6Object'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k={},l=Object.prototype.hasOwnProperty;k.inherits=function(m,n){j.assign(m,n);m.prototype=i.create(n&&n.prototype);m.prototype.constructor=m;m.__superConstructor__=n;return n;};k._extends=j.assign;k.objectWithoutProperties=function(m,n){var o={};for(var p in m){if(!l.call(m,p)||n.indexOf(p)>=0)continue;o[p]=m[p];}return o;};k.taggedTemplateLiteralLoose=function(m,n){m.raw=n;return m;};k.bind=h.bind;f.exports=k;},null);      var ES = require('ES');      var babelHelpers = require('sdk.babelHelpers');      __d(\"UrlMapConfig\",[],{\"www\":\"www.facebook.com\",\"m\":\"m.facebook.com\",\"connect\":\"connect.facebook.net\",\"business\":\"business.facebook.com\",\"api_https\":\"api.facebook.com\",\"api_read_https\":\"api-read.facebook.com\",\"graph_https\":\"graph.facebook.com\",\"fbcdn_http\":\"fbstatic-a.akamaihd.net\",\"fbcdn_https\":\"fbstatic-a.akamaihd.net\",\"cdn_http\":\"staticxx.facebook.com\",\"cdn_https\":\"staticxx.facebook.com\"});__d(\"JSSDKRuntimeConfig\",[],{\"locale\":\"en_US\",\"rtl\":false,\"revision\":\"2136283\"});__d(\"JSSDKConfig\",[],{\"bustCache\":true,\"tagCountLogRate\":0.01,\"errorHandling\":{\"rate\":4},\"usePluginPipe\":true,\"features\":{\"dialog_resize_refactor\":true,\"one_comment_controller\":true,\"allow_non_canvas_app_events\":false,\"event_subscriptions_log\":{\"rate\":0.01,\"value\":10000},\"should_force_single_dialog_instance\":true,\"js_sdk_force_status_on_load\":true,\"kill_fragment\":true,\"xfbml_profile_pic_server\":true,\"error_handling\":{\"rate\":4},\"e2e_ping_tracking\":{\"rate\":1.0e-6},\"getloginstatus_tracking\":{\"rate\":0.001},\"xd_timeout\":{\"rate\":4,\"value\":30000},\"use_bundle\":false,\"launch_payment_dialog_via_pac\":{\"rate\":100},\"plugin_tags_blacklist\":[\"recommendations_bar\",\"registration\",\"activity\",\"recommendations\",\"facepile\"],\"should_log_response_error\":true},\"api\":{\"mode\":\"warn\",\"whitelist\":[\"AppEvents\",\"AppEvents.EventNames\",\"AppEvents.ParameterNames\",\"AppEvents.activateApp\",\"AppEvents.logEvent\",\"AppEvents.logPurchase\",\"Canvas\",\"Canvas.Prefetcher\",\"Canvas.Prefetcher.addStaticResource\",\"Canvas.Prefetcher.setCollectionMode\",\"Canvas.getPageInfo\",\"Canvas.hideFlashElement\",\"Canvas.scrollTo\",\"Canvas.setAutoGrow\",\"Canvas.setDoneLoading\",\"Canvas.setSize\",\"Canvas.setUrlHandler\",\"Canvas.showFlashElement\",\"Canvas.startTimer\",\"Canvas.stopTimer\",\"Event\",\"Event.subscribe\",\"Event.unsubscribe\",\"Music.flashCallback\",\"Music.init\",\"Music.send\",\"Payment\",\"Payment.cancelFlow\",\"Payment.continueFlow\",\"Payment.init\",\"Payment.lockForProcessing\",\"Payment.parse\",\"Payment.setSize\",\"Payment.unlockForProcessing\",\"ThirdPartyProvider\",\"ThirdPartyProvider.init\",\"ThirdPartyProvider.sendData\",\"UA\",\"UA.nativeApp\",\"XFBML\",\"XFBML.RecommendationsBar\",\"XFBML.RecommendationsBar.markRead\",\"XFBML.parse\",\"addFriend\",\"api\",\"getAccessToken\",\"getAuthResponse\",\"getLoginStatus\",\"getUserID\",\"init\",\"login\",\"logout\",\"publish\",\"share\",\"ui\"]},\"initSitevars\":{\"enableMobileComments\":1,\"iframePermissions\":{\"read_stream\":false,\"manage_mailbox\":false,\"manage_friendlists\":false,\"read_mailbox\":false,\"publish_checkins\":true,\"status_update\":true,\"photo_upload\":true,\"video_upload\":true,\"sms\":false,\"create_event\":true,\"rsvp_event\":true,\"offline_access\":true,\"email\":true,\"xmpp_login\":false,\"create_note\":true,\"share_item\":true,\"export_stream\":false,\"publish_stream\":true,\"publish_likes\":true,\"ads_management\":false,\"contact_email\":true,\"access_private_data\":false,\"read_insights\":false,\"read_requests\":false,\"read_friendlists\":true,\"manage_pages\":false,\"physical_login\":false,\"manage_groups\":false,\"read_deals\":false}}});__d(\"JSSDKXDConfig\",[],{\"XdUrl\":\"\\/connect\\/xd_arbiter.php?version=42\",\"XdBundleUrl\":\"\\/connect\\/xd_arbiter\\/r\\/MHETSQlw-F9.js?version=42\",\"Flash\":{\"path\":\"https:\\/\\/connect.facebook.net\\/rsrc.php\\/v1\\/yW\\/r\\/yOZN1vHw3Z_.swf\"},\"useCdn\":true});__d(\"JSSDKCssConfig\",[],{\"rules\":\".fb_hidden{position:absolute;top:-10000px;z-index:10001}.fb_reposition{overflow-x:hidden;position:relative}.fb_invisible{display:none}.fb_reset{background:none;border:0;border-spacing:0;color:#000;cursor:auto;direction:ltr;font-family:\\\"lucida grande\\\", tahoma, verdana, arial, sans-serif;font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:1;margin:0;overflow:visible;padding:0;text-align:left;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;visibility:visible;white-space:normal;word-spacing:normal}.fb_reset>div{overflow:hidden}.fb_link img{border:none}\\n.fb_dialog{background:rgba(82, 82, 82, .7);position:absolute;top:-10000px;z-index:10001}.fb_reset .fb_dialog_legacy{overflow:visible}.fb_dialog_advanced{padding:10px;-moz-border-radius:8px;-webkit-border-radius:8px;border-radius:8px}.fb_dialog_content{background:#fff;color:#333}.fb_dialog_close_icon{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/yq\\/r\\/IE9JII6Z1Ys.png) no-repeat scroll 0 0 transparent;_background-image:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/yL\\/r\\/s816eWC-2sl.gif);cursor:pointer;display:block;height:15px;position:absolute;right:18px;top:17px;width:15px}.fb_dialog_mobile .fb_dialog_close_icon{top:5px;left:5px;right:auto}.fb_dialog_padding{background-color:transparent;position:absolute;width:1px;z-index:-1}.fb_dialog_close_icon:hover{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/yq\\/r\\/IE9JII6Z1Ys.png) no-repeat scroll 0 -15px transparent;_background-image:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/yL\\/r\\/s816eWC-2sl.gif)}.fb_dialog_close_icon:active{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/yq\\/r\\/IE9JII6Z1Ys.png) no-repeat scroll 0 -30px transparent;_background-image:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/yL\\/r\\/s816eWC-2sl.gif)}.fb_dialog_loader{background-color:#f6f7f8;border:1px solid #606060;font-size:24px;padding:20px}.fb_dialog_top_left,.fb_dialog_top_right,.fb_dialog_bottom_left,.fb_dialog_bottom_right{height:10px;width:10px;overflow:hidden;position:absolute}.fb_dialog_top_left{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/ye\\/r\\/8YeTNIlTZjm.png) no-repeat 0 0;left:-10px;top:-10px}.fb_dialog_top_right{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/ye\\/r\\/8YeTNIlTZjm.png) no-repeat 0 -10px;right:-10px;top:-10px}.fb_dialog_bottom_left{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/ye\\/r\\/8YeTNIlTZjm.png) no-repeat 0 -20px;bottom:-10px;left:-10px}.fb_dialog_bottom_right{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/ye\\/r\\/8YeTNIlTZjm.png) no-repeat 0 -30px;right:-10px;bottom:-10px}.fb_dialog_vert_left,.fb_dialog_vert_right,.fb_dialog_horiz_top,.fb_dialog_horiz_bottom{position:absolute;background:#525252;filter:alpha(opacity=70);opacity:.7}.fb_dialog_vert_left,.fb_dialog_vert_right{width:10px;height:100\\u0025}.fb_dialog_vert_left{margin-left:-10px}.fb_dialog_vert_right{right:0;margin-right:-10px}.fb_dialog_horiz_top,.fb_dialog_horiz_bottom{width:100\\u0025;height:10px}.fb_dialog_horiz_top{margin-top:-10px}.fb_dialog_horiz_bottom{bottom:0;margin-bottom:-10px}.fb_dialog_iframe{line-height:0}.fb_dialog_content .dialog_title{background:#6d84b4;border:1px solid #3a5795;color:#fff;font-size:14px;font-weight:bold;margin:0}.fb_dialog_content .dialog_title>span{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/yd\\/r\\/Cou7n-nqK52.gif) no-repeat 5px 50\\u0025;float:left;padding:5px 0 7px 26px}body.fb_hidden{-webkit-transform:none;height:100\\u0025;margin:0;overflow:visible;position:absolute;top:-10000px;left:0;width:100\\u0025}.fb_dialog.fb_dialog_mobile.loading{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/ya\\/r\\/3rhSv5V8j3o.gif) white no-repeat 50\\u0025 50\\u0025;min-height:100\\u0025;min-width:100\\u0025;overflow:hidden;position:absolute;top:0;z-index:10001}.fb_dialog.fb_dialog_mobile.loading.centered{width:auto;height:auto;min-height:initial;min-width:initial;background:none}.fb_dialog.fb_dialog_mobile.loading.centered #fb_dialog_loader_spinner{width:100\\u0025}.fb_dialog.fb_dialog_mobile.loading.centered .fb_dialog_content{background:none}.loading.centered #fb_dialog_loader_close{color:#fff;display:block;padding-top:20px;clear:both;font-size:18px}#fb-root #fb_dialog_ipad_overlay{background:rgba(0, 0, 0, .45);position:absolute;left:0;top:0;width:100\\u0025;min-height:100\\u0025;z-index:10000}#fb-root #fb_dialog_ipad_overlay.hidden{display:none}.fb_dialog.fb_dialog_mobile.loading iframe{visibility:hidden}.fb_dialog_content .dialog_header{-webkit-box-shadow:white 0 1px 1px -1px inset;background:-webkit-gradient(linear, 0\\u0025 0\\u0025, 0\\u0025 100\\u0025, from(#738ABA), to(#2C4987));border-bottom:1px solid;border-color:#1d4088;color:#fff;font:14px Helvetica, sans-serif;font-weight:bold;text-overflow:ellipsis;text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0;vertical-align:middle;white-space:nowrap}.fb_dialog_content .dialog_header table{-webkit-font-smoothing:subpixel-antialiased;height:43px;width:100\\u0025}.fb_dialog_content .dialog_header td.header_left{font-size:12px;padding-left:5px;vertical-align:middle;width:60px}.fb_dialog_content .dialog_header td.header_right{font-size:12px;padding-right:5px;vertical-align:middle;width:60px}.fb_dialog_content .touchable_button{background:-webkit-gradient(linear, 0\\u0025 0\\u0025, 0\\u0025 100\\u0025, from(#4966A6), color-stop(.5, #355492), to(#2A4887));border:1px solid #2f477a;-webkit-background-clip:padding-box;-webkit-border-radius:3px;-webkit-box-shadow:rgba(0, 0, 0, .117188) 0 1px 1px inset, rgba(255, 255, 255, .167969) 0 1px 0;display:inline-block;margin-top:3px;max-width:85px;line-height:18px;padding:4px 12px;position:relative}.fb_dialog_content .dialog_header .touchable_button input{border:none;background:none;color:#fff;font:12px Helvetica, sans-serif;font-weight:bold;margin:2px -12px;padding:2px 6px 3px 6px;text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0}.fb_dialog_content .dialog_header .header_center{color:#fff;font-size:16px;font-weight:bold;line-height:18px;text-align:center;vertical-align:middle}.fb_dialog_content .dialog_content{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/y9\\/r\\/jKEcVPZFk-2.gif) no-repeat 50\\u0025 50\\u0025;border:1px solid #555;border-bottom:0;border-top:0;height:150px}.fb_dialog_content .dialog_footer{background:#f6f7f8;border:1px solid #555;border-top-color:#ccc;height:40px}#fb_dialog_loader_close{float:left}.fb_dialog.fb_dialog_mobile .fb_dialog_close_button{text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0}.fb_dialog.fb_dialog_mobile .fb_dialog_close_icon{visibility:hidden}#fb_dialog_loader_spinner{animation:rotateSpinner 1.2s linear infinite;background-color:transparent;background-image:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/yD\\/r\\/t-wz8gw1xG1.png);background-repeat:no-repeat;background-position:50\\u0025 50\\u0025;height:24px;width:24px}\\u0040keyframes rotateSpinner{0\\u0025{transform:rotate(0deg)}100\\u0025{transform:rotate(360deg)}}\\n.fb_iframe_widget{display:inline-block;position:relative}.fb_iframe_widget span{display:inline-block;position:relative;text-align:justify}.fb_iframe_widget iframe{position:absolute}.fb_iframe_widget_fluid_desktop,.fb_iframe_widget_fluid_desktop span,.fb_iframe_widget_fluid_desktop iframe{max-width:100\\u0025}.fb_iframe_widget_fluid_desktop iframe{min-width:220px;position:relative}.fb_iframe_widget_lift{z-index:1}.fb_hide_iframes iframe{position:relative;left:-10000px}.fb_iframe_widget_loader{position:relative;display:inline-block}.fb_iframe_widget_fluid{display:inline}.fb_iframe_widget_fluid span{width:100\\u0025}.fb_iframe_widget_loader iframe{min-height:32px;z-index:2;zoom:1}.fb_iframe_widget_loader .FB_Loader{background:url(https:\\/\\/fbstatic-a.akamaihd.net\\/rsrc.php\\/v2\\/y9\\/r\\/jKEcVPZFk-2.gif) no-repeat;height:32px;width:32px;margin-left:-16px;position:absolute;left:50\\u0025;z-index:4}\",\"components\":[\"css:fb.css.base\",\"css:fb.css.dialog\",\"css:fb.css.iframewidget\"]});__d(\"ApiClientConfig\",[],{\"FlashRequest\":{\"swfUrl\":\"https:\\/\\/connect.facebook.net\\/rsrc.php\\/v1\\/yd\\/r\\/mxzow1Sdmxr.swf\"}});__d(\"JSSDKCanvasPrefetcherConfig\",[],{\"blacklist\":[144959615576466],\"sampleRate\":500});__d(\"JSSDKPluginPipeConfig\",[],{\"threshold\":0,\"enabledApps\":{\"209753825810663\":1,\"187288694643718\":1}});      __d(\"DOMWrapper\",[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h,i,j={setRoot:function(k){h=k;},getRoot:function(){return h||document.body;},setWindow:function(k){i=k;},getWindow:function(){return i||self;}};f.exports=j;},null);\n    __d('dotAccess',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(i,j,k){var l=j.split('.');do{var m=l.shift();i=i[m]||k&&(i[m]={});}while(l.length&&i);return i;}f.exports=h;},null);\n    __d('guid',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(){return 'f'+(Math.random()*(1<<30)).toString(16).replace('.','');}f.exports=h;},null);\n    __d('wrapFunction',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={};function i(j,k,l){k=k||'default';return function(){var m=k in h?h[k](j,l):j;return m.apply(this,arguments);};}i.setWrapper=function(j,k){k=k||'default';h[k]=j;};f.exports=i;},null);\n    __d('GlobalCallback',['DOMWrapper','dotAccess','guid','wrapFunction'],function a(b,c,d,e,f,g,h,i,j,k){if(c.__markCompiled)c.__markCompiled();var l,m,n={setPrefix:function(o){l=i(h.getWindow(),o,true);m=o;},create:function(o,p){if(!l)this.setPrefix('__globalCallbacks');var q=j();l[q]=k(o,'entry',p||'GlobalCallback');return m+'.'+q;},remove:function(o){var p=o.substring(m.length+1);delete l[p];}};f.exports=n;},null);\n    __d(\"sprintf\",[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(i){for(var j=arguments.length,k=Array(j>1?j-1:0),l=1;l<j;l++)k[l-1]=arguments[l];var m=0;return i.replace(/%s/g,function(n){return k[m++];});}f.exports=h;},null);\n    __d('Log',['sprintf'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i={DEBUG:3,INFO:2,WARNING:1,ERROR:0};function j(l,m){var n=Array.prototype.slice.call(arguments,2),o=h.apply(null,n),p=window.console;if(p&&k.level>=m)p[l in p?l:'log'](o);}var k={level:-1,Level:i,debug:ES(j,'bind',true,null,'debug',i.DEBUG),info:ES(j,'bind',true,null,'info',i.INFO),warn:ES(j,'bind',true,null,'warn',i.WARNING),error:ES(j,'bind',true,null,'error',i.ERROR)};f.exports=k;},null);\n    __d(\"ObservableMixin\",[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(){this.__observableEvents={};}h.prototype={inform:function(i){var j=Array.prototype.slice.call(arguments,1),k=Array.prototype.slice.call(this.getSubscribers(i));for(var l=0;l<k.length;l++){if(k[l]===null)continue;try{k[l].apply(this,j);}catch(m){setTimeout(function(){throw m;},0);}}return this;},getSubscribers:function(i){return this.__observableEvents[i]||(this.__observableEvents[i]=[]);},clearSubscribers:function(i){if(i)this.__observableEvents[i]=[];return this;},clearAllSubscribers:function(){this.__observableEvents={};return this;},subscribe:function(i,j){var k=this.getSubscribers(i);k.push(j);return this;},unsubscribe:function(i,j){var k=this.getSubscribers(i);for(var l=0;l<k.length;l++)if(k[l]===j){k.splice(l,1);break;}return this;},monitor:function(i,j){if(!j()){var k=ES(function(l){if(j.apply(j,arguments))this.unsubscribe(i,k);},\"bind\",true,this);this.subscribe(i,k);}return this;}};f.exports=h;},null);\n    __d('UrlMap',['UrlMapConfig'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i={resolve:function(j,k){var l=typeof k=='undefined'?location.protocol.replace(':',''):k?'https':'http';if(j in h)return l+'://'+h[j];if(typeof k=='undefined'&&j+'_'+l in h)return l+'://'+h[j+'_'+l];if(k!==true&&j+'_http' in h)return 'http://'+h[j+'_http'];if(k!==false&&j+'_https' in h)return 'https://'+h[j+'_https'];}};f.exports=i;},null);\n    __d('QueryString',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(l){var m=[];ES(ES('Object','keys',false,l).sort(),'forEach',true,function(n){var o=l[n];if(typeof o==='undefined')return;if(o===null){m.push(n);return;}m.push(encodeURIComponent(n)+'='+encodeURIComponent(o));});return m.join('&');}function i(l,m){var n={};if(l==='')return n;var o=l.split('&');for(var p=0;p<o.length;p++){var q=o[p].split('=',2),r=decodeURIComponent(q[0]);if(m&&n.hasOwnProperty(r))throw new URIError('Duplicate key: '+r);n[r]=q.length===2?decodeURIComponent(q[1]):null;}return n;}function j(l,m){return l+(ES(l,'indexOf',true,'?')!==-1?'&':'?')+(typeof m==='string'?m:k.encode(m));}var k={encode:h,decode:i,appendToUrl:j};f.exports=k;},null);\n    __d(\"ManagedError\",[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(i,j){Error.prototype.constructor.call(this,i);this.message=i;this.innerError=j;}h.prototype=new Error();h.prototype.constructor=h;f.exports=h;},null);\n    __d('AssertionError',['ManagedError'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();function i(j){h.prototype.constructor.apply(this,arguments);}i.prototype=new h();i.prototype.constructor=i;f.exports=i;},null);\n    __d('Assert',['AssertionError','sprintf'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();function j(o,p){if(typeof o!=='boolean'||!o)throw new h(p);return o;}function k(o,p,q){var r;if(p===undefined){r='undefined';}else if(p===null){r='null';}else{var s=Object.prototype.toString.call(p);r=/\\s(\\w*)/.exec(s)[1].toLowerCase();}j(ES(o,'indexOf',true,r)!==-1,q||i('Expression is of type %s, not %s',r,o));return p;}function l(o,p,q){j(p instanceof o,q||'Expression not instance of type');return p;}function m(o,p){n['is'+o]=p;n['maybe'+o]=function(q,r){if(q!=null)p(q,r);};}var n={isInstanceOf:l,isTrue:j,isTruthy:function(o,p){return j(!!o,p);},type:k,define:function(o,p){o=o.substring(0,1).toUpperCase()+o.substring(1).toLowerCase();m(o,function(q,r){j(p(q),r);});}};ES(['Array','Boolean','Date','Function','Null','Number','Object','Regexp','String','Undefined'],'forEach',true,function(o){m(o,ES(k,'bind',true,null,o.toLowerCase()));});f.exports=n;},null);\n    __d('Type',['Assert'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();function i(){var m=this.__mixins;if(m)for(var n=0;n<m.length;n++)m[n].apply(this,arguments);}function j(m,n){if(n instanceof m)return true;if(n instanceof i)for(var o=0;o<n.__mixins.length;o++)if(n.__mixins[o]==m)return true;return false;}function k(m,n){var o=m.prototype;if(!ES('Array','isArray',false,n))n=[n];for(var p=0;p<n.length;p++){var q=n[p];if(typeof q=='function'){o.__mixins.push(q);q=q.prototype;}ES(ES('Object','keys',false,q),'forEach',true,function(r){o[r]=q[r];});}}function l(m,n,o){var p=n&&n.hasOwnProperty('constructor')?n.constructor:function(){this.parent.apply(this,arguments);};h.isFunction(p);if(m&&m.prototype instanceof i===false)throw new Error('parent type does not inherit from Type');m=m||i;function q(){}q.prototype=m.prototype;p.prototype=new q();if(n)ES('Object','assign',false,p.prototype,n);p.prototype.constructor=p;p.parent=m;p.prototype.__mixins=m.prototype.__mixins?Array.prototype.slice.call(m.prototype.__mixins):[];if(o)k(p,o);p.prototype.parent=function(){this.parent=m.prototype.parent;m.apply(this,arguments);};p.prototype.parentCall=function(r){return m.prototype[r].apply(this,Array.prototype.slice.call(arguments,1));};p.extend=function(r,s){return l(this,r,s);};return p;}ES('Object','assign',false,i.prototype,{instanceOf:function(m){return j(m,this);}});ES('Object','assign',false,i,{extend:function(m,n){return typeof m==='function'?l.apply(null,arguments):l(null,m,n);},instanceOf:j});f.exports=i;},null);\n    __d('sdk.Model',['Type','ObservableMixin'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();var j=h.extend({constructor:function(k){this.parent();var l={},m=this;ES(ES('Object','keys',false,k),'forEach',true,function(n){l[n]=k[n];m['set'+n]=function(o){if(o===l[n])return this;l[n]=o;m.inform(n+'.change',o);return m;};m['get'+n]=function(){return l[n];};});}},i);f.exports=j;},null);\n    __d('sdk.Runtime',['sdk.Model','JSSDKRuntimeConfig'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();var j={UNKNOWN:0,PAGETAB:1,CANVAS:2,PLATFORM:4},k=new h({AccessToken:'',ClientID:'',CookieUserID:'',Environment:j.UNKNOWN,Initialized:false,IsVersioned:false,KidDirectedSite:undefined,Locale:i.locale,LoggedIntoFacebook:undefined,LoginStatus:undefined,Revision:i.revision,Rtl:i.rtl,Scope:undefined,Secure:undefined,UseCookie:false,UserID:'',Version:undefined});ES('Object','assign',false,k,{ENVIRONMENTS:j,isEnvironment:function(l){var m=this.getEnvironment();return (l|m)===m;},isCanvasEnvironment:function(){return this.isEnvironment(j.CANVAS)||this.isEnvironment(j.PAGETAB);}});(function(){var l=/app_runner/.test(window.name)?j.PAGETAB:/iframe_canvas/.test(window.name)?j.CANVAS:j.UNKNOWN;if((l|j.PAGETAB)===l)l=l|j.CANVAS;k.setEnvironment(l);})();f.exports=k;},null);\n    __d('sdk.Cookie',['QueryString','sdk.Runtime'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();var j=null;function k(n,o,p){n=n+i.getClientID();var q=j&&j!=='.';if(q){document.cookie=n+'=; expires=Wed, 04 Feb 2004 08:00:00 GMT;';document.cookie=n+'=; expires=Wed, 04 Feb 2004 08:00:00 GMT;'+'domain='+location.hostname+';';}var r=new Date(p).toGMTString();document.cookie=n+'='+o+(o&&p===0?'':'; expires='+r)+'; path=/'+(q?'; domain='+j:'');}function l(n){n=n+i.getClientID();var o=new RegExp('\\\\b'+n+'=([^;]*)\\\\b');return o.test(document.cookie)?RegExp.$1:null;}var m={setDomain:function(n){j=n;var o=h.encode({base_domain:j&&j!=='.'?j:''}),p=new Date();p.setFullYear(p.getFullYear()+1);k('fbm_',o,p.getTime());},getDomain:function(){return j;},loadMeta:function(){var n=l('fbm_');if(n){var o=h.decode(n);if(!j)j=o.base_domain;return o;}},loadSignedRequest:function(){return l('fbsr_');},setSignedRequestCookie:function(n,o){if(!n)throw new Error('Value passed to Cookie.setSignedRequestCookie '+'was empty.');k('fbsr_',n,o);},clearSignedRequestCookie:function(){k('fbsr_','',0);},setRaw:k,getRaw:l};f.exports=m;},null);\n    __d('Miny',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h='Miny1',i='wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'.split(''),j={encode:function(k){if(/^$|[~\\\\]|__proto__/.test(k))return k;var l=k.match(/\\w+|\\W+/g),m,n=ES('Object','create',false,null);for(m=0;m<l.length;m++)n[l[m]]=(n[l[m]]||0)+1;var o=ES('Object','keys',false,n);o.sort(function(r,s){return n[s]-n[r];});for(m=0;m<o.length;m++){var p=(m-m%32)/32;n[o[m]]=p?p.toString(32)+i[m%32]:i[m%32];}var q='';for(m=0;m<l.length;m++)q+=n[l[m]];o.unshift(h,o.length);o.push(q);return o.join('~');}};f.exports=j;},null);\n    __d('sdk.UA',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=navigator.userAgent,i={iphone:/\\b(iPhone|iP[ao]d)/.test(h),ipad:/\\b(iP[ao]d)/.test(h),android:/Android/i.test(h),nativeApp:/FBAN\\/\\w+;/i.test(h)},j=/Mobile/i.test(h),k={ie:'',firefox:'',chrome:'',webkit:'',osx:''},l=/(?:MSIE.(\\d+\\.\\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\\d+\\.\\d+))|(?:AppleWebKit.(\\d+(?:\\.\\d+)?))|(?:Trident\\/\\d+\\.\\d+.*rv:(\\d+\\.\\d+))/.exec(h);if(l){k.ie=l[1]?parseFloat(l[1]):l[4]?parseFloat(l[4]):'';k.firefox=l[2]||'';k.webkit=l[3]||'';if(l[3]){var m=/(?:Chrome\\/(\\d+\\.\\d+))/.exec(h);k.chrome=m?m[1]:'';}}var n=/(?:Mac OS X (\\d+(?:[._]\\d+)?))/.exec(h);if(n)k.osx=n[1];function o(q){return ES(q.split('.'),'map',true,function(r){return parseFloat(r);});}var p={};ES(ES('Object','keys',false,k),'map',true,function(q){p[q]=function(){return parseFloat(k[q]);};p[q].getVersionParts=function(){return o(k[q]);};});ES(ES('Object','keys',false,i),'map',true,function(q){p[q]=function(){return i[q];};});p.mobile=function(){return i.iphone||i.ipad||i.android||j;};f.exports=p;},null);\n    __d('getBlankIframeSrc',['sdk.UA'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();function i(){return h.ie()<10?'javascript:false':'about:blank';}f.exports=i;},null);\n    __d('insertIframe',['GlobalCallback','getBlankIframeSrc','guid'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();function k(l){l.id=l.id||j();l.name=l.name||j();var m=false,n=false,o=function(){if(m&&!n){n=true;l.onload&&l.onload(l.root.firstChild);}},p=h.create(o);if(document.attachEvent){var q='<iframe'+' id=\"'+l.id+'\"'+' name=\"'+l.name+'\"'+(l.title?' title=\"'+l.title+'\"':'')+(l.className?' class=\"'+l.className+'\"':'')+' style=\"border:none;'+(l.width?'width:'+l.width+'px;':'')+(l.height?'height:'+l.height+'px;':'')+'\"'+' src=\"'+i()+'\"'+' frameborder=\"0\"'+' scrolling=\"no\"'+' allowtransparency=\"true\"'+' onload=\"'+p+'()\"'+'></iframe>';l.root.innerHTML='<iframe src=\"'+i()+'\"'+' frameborder=\"0\"'+' scrolling=\"no\"'+' style=\"height:1px\"></iframe>';m=true;setTimeout(function(){l.root.innerHTML=q;l.root.firstChild.src=l.url;l.onInsert&&l.onInsert(l.root.firstChild);},0);}else{var r=document.createElement('iframe');r.id=l.id;r.name=l.name;r.onload=o;r.scrolling='no';r.style.border='none';r.style.overflow='hidden';if(l.title)r.title=l.title;if(l.className)r.className=l.className;if(l.height!==undefined)r.style.height=l.height+'px';if(l.width!==undefined)if(l.width=='100%'){r.style.width=l.width;}else r.style.width=l.width+'px';l.root.appendChild(r);m=true;r.src=l.url;l.onInsert&&l.onInsert(r);}}f.exports=k;},null);\n    __d('sdk.domReady',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h,i=\"readyState\" in document?/loaded|complete/.test(document.readyState):!!document.body;function j(){if(!h)return;var m;while(m=h.shift())m();h=null;}function k(m){if(h){h.push(m);}else m();}if(!i){h=[];if(document.addEventListener){document.addEventListener('DOMContentLoaded',j,false);window.addEventListener('load',j,false);}else if(document.attachEvent){document.attachEvent('onreadystatechange',j);window.attachEvent('onload',j);}if(document.documentElement.doScroll&&window==window.top){var l=function(){try{document.documentElement.doScroll('left');}catch(m){setTimeout(l,0);return;}j();};l();}}f.exports=k;},3);\n    __d('sdk.Content',['Log','sdk.UA','sdk.domReady'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k,l,m={append:function(n,o){if(!o)if(!k){k=o=document.getElementById('fb-root');if(!o){h.warn('The \"fb-root\" div has not been created, auto-creating');k=o=document.createElement('div');o.id='fb-root';if(i.ie()||!document.body){j(function(){document.body.appendChild(o);});}else document.body.appendChild(o);}o.className+=' fb_reset';}else o=k;if(typeof n=='string'){var p=document.createElement('div');o.appendChild(p).innerHTML=n;return p;}else return o.appendChild(n);},appendHidden:function(n){if(!o){var o=document.createElement('div'),p=o.style;p.position='absolute';p.top='-10000px';p.width=p.height=0;o=m.append(o);}return m.append(n,o);},submitToTarget:function(n,o){var p=document.createElement('form');p.action=n.url;p.target=n.target;p.method=o?'GET':'POST';m.appendHidden(p);for(var q in n.params)if(n.params.hasOwnProperty(q)){var r=n.params[q];if(r!==null&&r!==undefined){var s=document.createElement('input');s.name=q;s.value=r;p.appendChild(s);}}p.submit();p.parentNode.removeChild(p);}};f.exports=m;},null);\n    __d('sdk.Impressions',['sdk.Content','Miny','QueryString','sdk.Runtime','UrlMap','getBlankIframeSrc','guid','insertIframe'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o){if(c.__markCompiled)c.__markCompiled();function p(r){var s=k.getClientID();if(!r.api_key&&s)r.api_key=s;r.kid_directed_site=k.getKidDirectedSite();var t=l.resolve('www',true)+'/impression.php/'+n()+'/',u=j.appendToUrl(t,r);if(u.length>2000)if(r.payload&&typeof r.payload==='string'){var v=i.encode(r.payload);if(v&&v.length<r.payload.length){r.payload=v;u=j.appendToUrl(t,r);}}if(u.length<=2000){var w=new Image();w.src=u;}else{var x=n(),y=h.appendHidden('');o({url:m(),root:y,name:x,className:'fb_hidden fb_invisible',onload:function(){y.parentNode.removeChild(y);}});h.submitToTarget({url:t,target:x,params:r});}}var q={log:function(r,s){if(!s.source)s.source='jssdk';p({lid:r,payload:ES('JSON','stringify',false,s)});},impression:p};f.exports=q;},null);\n    __d('Base64',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';function i(m){m=m.charCodeAt(0)<<16|m.charCodeAt(1)<<8|m.charCodeAt(2);return String.fromCharCode(h.charCodeAt(m>>>18),h.charCodeAt(m>>>12&63),h.charCodeAt(m>>>6&63),h.charCodeAt(m&63));}var j='>___?456789:;<=_______'+'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\x0b\\f\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19'+'______\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123';function k(m){m=j.charCodeAt(m.charCodeAt(0)-43)<<18|j.charCodeAt(m.charCodeAt(1)-43)<<12|j.charCodeAt(m.charCodeAt(2)-43)<<6|j.charCodeAt(m.charCodeAt(3)-43);return String.fromCharCode(m>>>16,m>>>8&255,m&255);}var l={encode:function(m){m=unescape(encodeURI(m));var n=(m.length+2)%3;m=(m+'\\0\\0'.slice(n)).replace(/[\\s\\S]{3}/g,i);return m.slice(0,m.length+n-2)+'=='.slice(n);},decode:function(m){m=m.replace(/[^A-Za-z0-9+\\/]/g,'');var n=m.length+3&3;m=(m+'AAA'.slice(n)).replace(/..../g,k);m=m.slice(0,m.length+n-3);try{return decodeURIComponent(escape(m));}catch(o){throw new Error('Not valid UTF-8');}},encodeObject:function(m){return l.encode(ES('JSON','stringify',false,m));},decodeObject:function(m){return ES('JSON','parse',false,l.decode(m));},encodeNums:function(m){return String.fromCharCode.apply(String,ES(m,'map',true,function(n){return h.charCodeAt((n|-(n>63))&-(n>0)&63);}));}};f.exports=l;},null);\n    __d('sdk.SignedRequest',['Base64'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();function i(k){if(!k)return null;var l=k.split('.',2)[1].replace(/\\-/g,'+').replace(/\\_/g,'/');return h.decodeObject(l);}var j={parse:i};f.exports=j;},null);\n    __d('URIRFC3986',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=new RegExp('^'+'([^:/?#]+:)?'+'(//'+'([^\\\\\\\\/?#@]*@)?'+'('+'\\\\[[A-Fa-f0-9:.]+\\\\]|'+'[^\\\\/?#:]*'+')'+'(:[0-9]*)?'+')?'+'([^?#]*)'+'(\\\\?[^#]*)?'+'(#.*)?'),i={parse:function(j){if(ES(j,'trim',true)==='')return null;var k=j.match(h),l={};l.uri=k[0]?k[0]:null;l.scheme=k[1]?k[1].substr(0,k[1].length-1):null;l.authority=k[2]?k[2].substr(2):null;l.userinfo=k[3]?k[3].substr(0,k[3].length-1):null;l.host=k[2]?k[4]:null;l.port=k[5]?k[5].substr(1)?parseInt(k[5].substr(1),10):null:null;l.path=k[6]?k[6]:null;l.query=k[7]?k[7].substr(1):null;l.fragment=k[8]?k[8].substr(1):null;l.isGenericURI=l.authority===null&&!!l.scheme;return l;}};f.exports=i;},null);\n    __d('createObjectFrom',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(i,j){var k={},l=ES('Array','isArray',false,j);if(j===undefined)j=true;for(var m=i.length-1;m>=0;m--)k[i[m]]=l?j[m]:j;return k;}f.exports=h;},null);\n    __d('URISchemes',['createObjectFrom'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i=h(['blob','fb','fb-ama','fb-messenger','fbcf','fbconnect','fbmobilehome','fbrpc','file','ftp','http','https','mailto','ms-app','intent','itms','itms-apps','itms-services','market','svn+ssh','fbstaging','tel','sms','pebblejs','sftp']),j={isAllowed:function(k){if(!k)return true;return i.hasOwnProperty(k.toLowerCase());}};f.exports=j;},null);\n    __d('eprintf',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=function(i){var j=ES(Array.prototype.slice.call(arguments),'map',true,function(m){return String(m);}),k=i.split('%s').length-1;if(k!==j.length-1)return h('eprintf args number mismatch: %s',ES('JSON','stringify',false,j));var l=1;return i.replace(/%s/g,function(m){return String(j[l++]);});};f.exports=h;},null);\n    __d('ex',['eprintf'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i=function(){for(var j=arguments.length,k=Array(j),l=0;l<j;l++)k[l]=arguments[l];k=ES(k,'map',true,function(m){return String(m);});if(k[0].split('%s').length!==k.length)return i('ex args number mismatch: %s',ES('JSON','stringify',false,k));return i._prefix+ES('JSON','stringify',false,k)+i._suffix;};i._prefix='<![EX[';i._suffix=']]>';f.exports=i;},null);\n    __d('invariant',['ex','sprintf'],function a(b,c,d,e,f,g,h,i){'use strict';if(c.__markCompiled)c.__markCompiled();var j=h;function k(l,m){if(!l){var n;if(m===undefined){n=new Error('Minified exception occurred; use the non-minified dev environment '+'for the full error message and additional helpful warnings.');}else{var o=[m];for(var p=2,q=arguments.length;p<q;p++)o.push(arguments[p]);n=new Error(j.apply(null,o));n.name='Invariant Violation';n.messageWithParams=o;}n.framesToPop=1;throw n;}}f.exports=k;},null);\n    __d('URIBase',['URIRFC3986','URISchemes','ex','invariant'],function a(b,c,d,e,f,g,h,i,j,k){if(c.__markCompiled)c.__markCompiled();var l=new RegExp('[\\\\x00-\\\\x2c\\\\x2f\\\\x3b-\\\\x40\\\\x5c\\\\x5e\\\\x60\\\\x7b-\\\\x7f'+'\\\\uFDD0-\\\\uFDEF\\\\uFFF0-\\\\uFFFF'+'\\\\u2047\\\\u2048\\\\uFE56\\\\uFE5F\\\\uFF03\\\\uFF0F\\\\uFF1F]'),m=new RegExp('^(?:[^/]*:|'+'[\\\\x00-\\\\x1f]*/[\\\\x00-\\\\x1f]*/)');function n(q,r,s,t){if(!r)return true;if(r instanceof p){q.setProtocol(r.getProtocol());q.setDomain(r.getDomain());q.setPort(r.getPort());q.setPath(r.getPath());q.setQueryData(t.deserialize(t.serialize(r.getQueryData())));q.setFragment(r.getFragment());q.setForceFragmentSeparator(r.getForceFragmentSeparator());return true;}r=ES(r.toString(),'trim',true);var u=h.parse(r)||{};if(!s&&!i.isAllowed(u.scheme))return false;q.setProtocol(u.scheme||'');if(!s&&l.test(u.host))return false;q.setDomain(u.host||'');q.setPort(u.port||'');q.setPath(u.path||'');if(s){q.setQueryData(t.deserialize(u.query)||{});}else try{q.setQueryData(t.deserialize(u.query)||{});}catch(v){return false;}q.setFragment(u.fragment||'');if(u.fragment==='')q.setForceFragmentSeparator(true);if(u.userinfo!==null)if(s){throw new Error(j('URI.parse: invalid URI (userinfo is not allowed in a URI): %s',q.toString()));}else return false;if(!q.getDomain()&&ES(q.getPath(),'indexOf',true,'\\\\')!==-1)if(s){throw new Error(j('URI.parse: invalid URI (no domain but multiple back-slashes): %s',q.toString()));}else return false;if(!q.getProtocol()&&m.test(r))if(s){throw new Error(j('URI.parse: invalid URI (unsafe protocol-relative URLs): %s',q.toString()));}else return false;return true;}var o=[];function p(q,r){'use strict';!r?k(0):undefined;this.$URIBase1=r;this.$URIBase2='';this.$URIBase3='';this.$URIBase4='';this.$URIBase5='';this.$URIBase6='';this.$URIBase7={};this.$URIBase8=false;n(this,q,true,r);}p.prototype.setProtocol=function(q){'use strict';!i.isAllowed(q)?k(0):undefined;this.$URIBase2=q;return this;};p.prototype.getProtocol=function(q){'use strict';return this.$URIBase2;};p.prototype.setSecure=function(q){'use strict';return this.setProtocol(q?'https':'http');};p.prototype.isSecure=function(){'use strict';return this.getProtocol()==='https';};p.prototype.setDomain=function(q){'use strict';if(l.test(q))throw new Error(j('URI.setDomain: unsafe domain specified: %s for url %s',q,this.toString()));this.$URIBase3=q;return this;};p.prototype.getDomain=function(){'use strict';return this.$URIBase3;};p.prototype.setPort=function(q){'use strict';this.$URIBase4=q;return this;};p.prototype.getPort=function(){'use strict';return this.$URIBase4;};p.prototype.setPath=function(q){'use strict';this.$URIBase5=q;return this;};p.prototype.getPath=function(){'use strict';return this.$URIBase5;};p.prototype.addQueryData=function(q,r){'use strict';if(Object.prototype.toString.call(q)==='[object Object]'){ES('Object','assign',false,this.$URIBase7,q);}else this.$URIBase7[q]=r;return this;};p.prototype.setQueryData=function(q){'use strict';this.$URIBase7=q;return this;};p.prototype.getQueryData=function(){'use strict';return this.$URIBase7;};p.prototype.removeQueryData=function(q){'use strict';if(!ES('Array','isArray',false,q))q=[q];for(var r=0,s=q.length;r<s;++r)delete this.$URIBase7[q[r]];return this;};p.prototype.setFragment=function(q){'use strict';this.$URIBase6=q;this.setForceFragmentSeparator(false);return this;};p.prototype.getFragment=function(){'use strict';return this.$URIBase6;};p.prototype.setForceFragmentSeparator=function(q){'use strict';this.$URIBase8=q;return this;};p.prototype.getForceFragmentSeparator=function(){'use strict';return this.$URIBase8;};p.prototype.isEmpty=function(){'use strict';return !(this.getPath()||this.getProtocol()||this.getDomain()||this.getPort()||ES('Object','keys',false,this.getQueryData()).length>0||this.getFragment());};p.prototype.toString=function(){'use strict';var q=this;for(var r=0;r<o.length;r++)q=o[r](q);return q.$URIBase9();};p.prototype.$URIBase9=function(){'use strict';var q='',r=this.getProtocol();if(r)q+=r+'://';var s=this.getDomain();if(s)q+=s;var t=this.getPort();if(t)q+=':'+t;var u=this.getPath();if(u){q+=u;}else if(q)q+='/';var v=this.$URIBase1.serialize(this.getQueryData());if(v)q+='?'+v;var w=this.getFragment();if(w){q+='#'+w;}else if(this.getForceFragmentSeparator())q+='#';return q;};p.registerFilter=function(q){'use strict';o.push(q);};p.prototype.getOrigin=function(){'use strict';var q=this.getPort();return this.getProtocol()+'://'+this.getDomain()+(q?':'+q:'');};p.isValidURI=function(q,r){return n(new p(null,r),q,false,r);};f.exports=p;},null);\n    __d('sdk.URI',['Assert','QueryString','URIBase'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k,l,m=/\\.facebook\\.com$/,n={serialize:function(p){return p?i.encode(p):'';},deserialize:function(p){return p?i.decode(p):{};}};k=babelHelpers.inherits(o,j);l=k&&k.prototype;function o(p){'use strict';h.isString(p,'The passed argument was of invalid type.');l.constructor.call(this,p,n);}o.prototype.isFacebookURI=function(){'use strict';return m.test(this.getDomain());};o.prototype.valueOf=function(){'use strict';return this.toString();};f.exports=o;},null);\n    __d('Queue',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={};function i(j){'use strict';this._opts=babelHelpers._extends({interval:0,processor:null},j);this._queue=[];this._stopped=true;}i.prototype._dispatch=function(j){'use strict';if(this._stopped||this._queue.length===0)return;if(!this._opts.processor){this._stopped=true;throw new Error('No processor available');}if(this._opts.interval){this._opts.processor.call(this,this._queue.shift());this._timeout=setTimeout(ES(this._dispatch,'bind',true,this),this._opts.interval);}else while(this._queue.length)this._opts.processor.call(this,this._queue.shift());};i.prototype.enqueue=function(j){'use strict';if(this._opts.processor&&!this._stopped){this._opts.processor.call(this,j);}else this._queue.push(j);return this;};i.prototype.start=function(j){'use strict';if(j)this._opts.processor=j;this._stopped=false;this._dispatch();return this;};i.prototype.isStarted=function(){'use strict';return !this._stopped;};i.prototype.dispatch=function(){'use strict';this._dispatch(true);};i.prototype.stop=function(j){'use strict';this._stopped=true;if(j)clearTimeout(this._timeout);return this;};i.prototype.merge=function(j,k){'use strict';this._queue[k?'unshift':'push'].apply(this._queue,j._queue);j._queue=[];this._dispatch();return this;};i.prototype.getLength=function(){'use strict';return this._queue.length;};i.get=function(j,k){'use strict';var l;if(j in h){l=h[j];}else l=h[j]=new i(k);return l;};i.exists=function(j){'use strict';return j in h;};i.remove=function(j){'use strict';return delete h[j];};f.exports=i;},null);\n    __d('DOMEventListener',['wrapFunction'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i,j;if(window.addEventListener){i=function(l,m,n){n.wrapper=h(n,'entry','DOMEventListener.add '+m);l.addEventListener(m,n.wrapper,false);};j=function(l,m,n){l.removeEventListener(m,n.wrapper,false);};}else if(window.attachEvent){i=function(l,m,n){n.wrapper=h(n,'entry','DOMEventListener.add '+m);l.attachEvent('on'+m,n.wrapper);};j=function(l,m,n){l.detachEvent('on'+m,n.wrapper);};}else j=i=function(){};var k={add:function(l,m,n){i(l,m,n);return {remove:function(){j(l,m,n);l=null;}};},remove:j};f.exports=k;},null);\n    __d('UserAgent_DEPRECATED',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=false,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;function x(){if(h)return;h=true;var z=navigator.userAgent,aa=/(?:MSIE.(\\d+\\.\\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\\d+\\.\\d+))|(?:Opera(?:.+Version.|.)(\\d+\\.\\d+))|(?:AppleWebKit.(\\d+(?:\\.\\d+)?))|(?:Trident\\/\\d+\\.\\d+.*rv:(\\d+\\.\\d+))/.exec(z),ba=/(Mac OS X)|(Windows)|(Linux)/.exec(z);t=/\\b(iPhone|iP[ao]d)/.exec(z);u=/\\b(iP[ao]d)/.exec(z);r=/Android/i.exec(z);v=/FBAN\\/\\w+;/i.exec(z);w=/Mobile/i.exec(z);s=!!/Win64/.exec(z);if(aa){i=aa[1]?parseFloat(aa[1]):aa[5]?parseFloat(aa[5]):NaN;if(i&&document&&document.documentMode)i=document.documentMode;var ca=/(?:Trident\\/(\\d+.\\d+))/.exec(z);n=ca?parseFloat(ca[1])+4:i;j=aa[2]?parseFloat(aa[2]):NaN;k=aa[3]?parseFloat(aa[3]):NaN;l=aa[4]?parseFloat(aa[4]):NaN;if(l){aa=/(?:Chrome\\/(\\d+\\.\\d+))/.exec(z);m=aa&&aa[1]?parseFloat(aa[1]):NaN;}else m=NaN;}else i=j=k=m=l=NaN;if(ba){if(ba[1]){var da=/(?:Mac OS X (\\d+(?:[._]\\d+)?))/.exec(z);o=da?parseFloat(da[1].replace('_','.')):true;}else o=false;p=!!ba[2];q=!!ba[3];}else o=p=q=false;}var y={ie:function(){return x()||i;},ieCompatibilityMode:function(){return x()||n>i;},ie64:function(){return y.ie()&&s;},firefox:function(){return x()||j;},opera:function(){return x()||k;},webkit:function(){return x()||l;},safari:function(){return y.webkit();},chrome:function(){return x()||m;},windows:function(){return x()||p;},osx:function(){return x()||o;},linux:function(){return x()||q;},iphone:function(){return x()||t;},mobile:function(){return x()||(t||u||r||w);},nativeApp:function(){return x()||v;},android:function(){return x()||r;},ipad:function(){return x()||u;}};f.exports=y;},null);\n    __d('htmlSpecialChars',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=/&/g,i=/</g,j=/>/g,k=/\"/g,l=/'/g;function m(n){if(typeof n=='undefined'||n===null||!n.toString)return '';if(n===false){return '0';}else if(n===true)return '1';return n.toString().replace(h,'&amp;').replace(k,'&quot;').replace(l,'&#039;').replace(i,'&lt;').replace(j,'&gt;');}f.exports=m;},null);\n    __d('Flash',['DOMEventListener','DOMWrapper','QueryString','UserAgent_DEPRECATED','guid','htmlSpecialChars'],function a(b,c,d,e,f,g,h,i,j,k,l,m){if(c.__markCompiled)c.__markCompiled();var n={},o,p=i.getWindow().document;function q(v){var w=p.getElementById(v);if(w)w.parentNode.removeChild(w);delete n[v];}function r(){for(var v in n)if(n.hasOwnProperty(v))q(v);}function s(v){return v.replace(/\\d+/g,function(w){return '000'.substring(w.length)+w;});}function t(v){if(!o){if(k.ie()>=9)h.add(window,'unload',r);o=true;}n[v]=v;}var u={embed:function(v,w,x,y){var z=l();v=m(v).replace(/&amp;/g,'&');x=babelHelpers._extends({allowscriptaccess:'always',flashvars:y,movie:v},x);if(typeof x.flashvars=='object')x.flashvars=j.encode(x.flashvars);var aa=[];for(var ba in x)if(x.hasOwnProperty(ba)&&x[ba])aa.push('<param name=\"'+m(ba)+'\" value=\"'+m(x[ba])+'\">');var ca=w.appendChild(p.createElement('span')),da='<object '+(k.ie()?'classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" ':'type=\"application/x-shockwave-flash\"')+'data=\"'+v+'\" '+(x.height?'height=\"'+x.height+'\" ':'')+(x.width?'width=\"'+x.width+'\" ':'')+'id=\"'+z+'\">'+aa.join('')+'</object>';ca.innerHTML=da;var ea=ca.firstChild;t(z);return ea;},remove:q,getVersion:function(){var v='Shockwave Flash',w='application/x-shockwave-flash',x='ShockwaveFlash.ShockwaveFlash',y;if(navigator.plugins&&typeof navigator.plugins[v]=='object'){var z=navigator.plugins[v].description;if(z&&navigator.mimeTypes&&navigator.mimeTypes[w]&&navigator.mimeTypes[w].enabledPlugin)y=z.match(/\\d+/g);}if(!y)try{y=new ActiveXObject(x).GetVariable('$version').match(/(\\d+),(\\d+),(\\d+),(\\d+)/);y=Array.prototype.slice.call(y,1);}catch(aa){}return y;},getVersionString:function(){var v=u.getVersion();return v?v.join('.'):'';},checkMinVersion:function(v){var w=u.getVersion();if(!w)return false;return s(w.join('.'))>=s(v);},isAvailable:function(){return !!u.getVersion();}};f.exports=u;},null);\n    __d(\"emptyFunction\",[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(j){return function(){return j;};}function i(){}i.thatReturns=h;i.thatReturnsFalse=h(false);i.thatReturnsTrue=h(true);i.thatReturnsNull=h(null);i.thatReturnsThis=function(){return this;};i.thatReturnsArgument=function(j){return j;};f.exports=i;},null);\n    __d('XDM',['DOMEventListener','DOMWrapper','emptyFunction','Flash','GlobalCallback','guid','Log','UserAgent_DEPRECATED','wrapFunction'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){if(c.__markCompiled)c.__markCompiled();var q={},r={transports:[]},s=i.getWindow();function t(w){var x={},y=w.length,z=r.transports;while(y--)x[w[y]]=1;y=z.length;while(y--){var aa=z[y],ba=q[aa];if(!x[aa]&&ba.isAvailable())return aa;}}var u={register:function(w,x){n.debug('Registering %s as XDM provider',w);r.transports.push(w);q[w]=x;},create:function(w){if(!w.whenReady&&!w.onMessage){n.error('An instance without whenReady or onMessage makes no sense');throw new Error('An instance without whenReady or '+'onMessage makes no sense');}if(!w.channel){n.warn('Missing channel name, selecting at random');w.channel=m();}if(!w.whenReady)w.whenReady=j;if(!w.onMessage)w.onMessage=j;var x=w.transport||t(w.blacklist||[]),y=q[x];if(y&&y.isAvailable()){n.debug('%s is available',x);y.init(w);return x;}}};u.register('flash',(function(){var w=false,x,y=false,z=15000,aa;return {isAvailable:function(){return k.checkMinVersion('8.0.24');},init:function(ba){n.debug('init flash: '+ba.channel);var ca={send:function(fa,ga,ha,ia){n.debug('sending to: %s (%s)',ga,ia);x.postMessage(fa,ga,ia);}};if(w){ba.whenReady(ca);return;}var da=ba.root.appendChild(s.document.createElement('div')),ea=l.create(function(){l.remove(ea);clearTimeout(aa);n.info('xdm.swf called the callback');var fa=l.create(function(ga,ha){ga=decodeURIComponent(ga);ha=decodeURIComponent(ha);n.debug('received message %s from %s',ga,ha);ba.onMessage(ga,ha);},'xdm.swf:onMessage');x.init(ba.channel,fa);ba.whenReady(ca);},'xdm.swf:load');x=k.embed(ba.flashUrl,da,null,{protocol:location.protocol.replace(':',''),host:location.host,callback:ea,log:y});aa=setTimeout(function(){n.warn('The Flash component did not load within %s ms - '+'verify that the container is not set to hidden or invisible '+'using CSS as this will cause some browsers to not load '+'the components',z);},z);w=true;}};})());var v=/\\.facebook\\.com(\\/|$)/;u.register('postmessage',(function(){var w=false;return {isAvailable:function(){return !!s.postMessage;},init:function(x){n.debug('init postMessage: '+x.channel);var y='_FB_'+x.channel,z={send:function(aa,ba,ca,da){if(s===ca){n.error('Invalid windowref, equal to window (self)');throw new Error();}n.debug('sending to: %s (%s)',ba,da);var ea=function(){ca.postMessage('_FB_'+da+aa,ba);};if(o.ie()==8||o.ieCompatibilityMode()){setTimeout(ea,0);}else ea();}};if(w){x.whenReady(z);return;}h.add(s,'message',p(function(event){var aa=event.data,ba=event.origin||'native';if(!/^(https?:\\/\\/|native$)/.test(ba)){n.debug('Received message from invalid origin type: %s',ba);return;}if(ba!=='native'&&!(v.test(location.hostname)||v.test(event.origin)))return;if(typeof aa!='string'){n.warn('Received message of type %s from %s, expected a string',typeof aa,ba);return;}n.debug('received message %s from %s',aa,ba);if(aa.substring(0,y.length)==y)aa=aa.substring(y.length);x.onMessage(aa,ba);},'entry','onMessage'));x.whenReady(z);w=true;}};})());f.exports=u;},null);\n    __d('isFacebookURI',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=null,i=['http','https'];function j(k){if(!h)h=new RegExp('(^|\\\\.)facebook\\\\.com$','i');if(k.isEmpty()&&k.toString()!=='#')return false;if(!k.getDomain()&&!k.getProtocol())return true;return ES(i,'indexOf',true,k.getProtocol())!==-1&&h.test(k.getDomain());}j.setRegex=function(k){h=k;};f.exports=j;},null);\n    __d('sdk.Event',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={SUBSCRIBE:'event.subscribe',UNSUBSCRIBE:'event.unsubscribe',subscribers:function(){if(!this._subscribersMap)this._subscribersMap={};return this._subscribersMap;},subscribe:function(i,j){var k=this.subscribers();if(!k[i]){k[i]=[j];}else if(ES(k[i],'indexOf',true,j)==-1)k[i].push(j);if(i!=this.SUBSCRIBE&&i!=this.UNSUBSCRIBE)this.fire(this.SUBSCRIBE,i,k[i]);},unsubscribe:function(i,j){var k=this.subscribers()[i];if(k)ES(k,'forEach',true,function(l,m){if(l==j)k.splice(m,1);});if(i!=this.SUBSCRIBE&&i!=this.UNSUBSCRIBE)this.fire(this.UNSUBSCRIBE,i,k);},monitor:function(i,j){if(!j()){var k=this,l=function(){if(j.apply(j,arguments))k.unsubscribe(i,l);};this.subscribe(i,l);}},clear:function(i){delete this.subscribers()[i];},fire:function(i){var j=Array.prototype.slice.call(arguments,1),k=this.subscribers()[i];if(k)ES(k,'forEach',true,function(l){if(l)l.apply(this,j);});}};f.exports=h;},null);\n    __d('JSONRPC',['Log'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();function i(j){'use strict';this.$JSONRPC1=0;this.$JSONRPC2={};this.remote=ES(function(k){this.$JSONRPC3=k;return this.remote;},'bind',true,this);this.local={};this.$JSONRPC4=j;}i.prototype.stub=function(j){'use strict';this.remote[j]=ES(function(){var k={jsonrpc:'2.0',method:j};for(var l=arguments.length,m=Array(l),n=0;n<l;n++)m[n]=arguments[n];if(typeof m[m.length-1]=='function'){k.id=++this.$JSONRPC1;this.$JSONRPC2[k.id]=m.pop();}k.params=m;this.$JSONRPC4(ES('JSON','stringify',false,k),this.$JSONRPC3||{method:j});},'bind',true,this);};i.prototype.read=function(j,k){'use strict';var l=ES('JSON','parse',false,j),m=l.id;if(!l.method){if(!this.$JSONRPC2[m]){h.warn('Could not find callback %s',m);return;}var n=this.$JSONRPC2[m];delete this.$JSONRPC2[m];delete l.id;delete l.jsonrpc;n(l);return;}var o=this,p=this.local[l.method],q;if(m){q=function(t,u){var v={jsonrpc:'2.0',id:m};v[t]=u;setTimeout(function(){o.$JSONRPC4(ES('JSON','stringify',false,v),k);},0);};}else q=function(){};if(!p){h.error('Method \"%s\" has not been defined',l.method);q('error',{code:-32601,message:'Method not found',data:l.method});return;}l.params.push(ES(q,'bind',true,null,'result'));l.params.push(ES(q,'bind',true,null,'error'));try{var s=p.apply(k||null,l.params);if(typeof s!=='undefined')q('result',s);}catch(r){h.error('Invokation of RPC method %s resulted in the error: %s',l.method,r.message);q('error',{code:-32603,message:'Internal error',data:r.message});}};f.exports=i;},null);\n    __d('sdk.RPC',['Assert','JSONRPC','Queue'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k=new j(),l=new i(function(n){k.enqueue(n);}),m={local:l.local,remote:l.remote,stub:ES(l.stub,'bind',true,l),setInQueue:function(n){h.isInstanceOf(j,n);n.start(function(o){l.read(o);});},getOutQueue:function(){return k;}};f.exports=m;},null);\n    __d('sdk.Scribe',['QueryString','sdk.Runtime','UrlMap'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();function k(m,n){if(typeof n.extra=='object')n.extra.revision=i.getRevision();new Image().src=h.appendToUrl(j.resolve('www',true)+'/common/scribe_endpoint.php',{c:m,m:ES('JSON','stringify',false,n)});}var l={log:k};f.exports=l;},null);\n    __d('hasNamePropertyBug',['guid','UserAgent_DEPRECATED'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();var j=i.ie()?undefined:false;function k(){var m=document.createElement(\"form\"),n=m.appendChild(document.createElement(\"input\"));n.name=h();j=n!==m.elements[n.name];m=n=null;return j;}function l(){return typeof j==='undefined'?k():j;}f.exports=l;},null);\n    __d('sdk.createIframe',['DOMEventListener','getBlankIframeSrc','guid','hasNamePropertyBug'],function a(b,c,d,e,f,g,h,i,j,k){if(c.__markCompiled)c.__markCompiled();function l(m){m=ES('Object','assign',false,{},m);var n,o=m.name||j(),p=m.root,q=m.style||{border:'none'},r=m.url,s=m.onload,t=m.onerror;if(k()){n=document.createElement('<iframe name=\"'+o+'\"/>');}else{n=document.createElement(\"iframe\");n.name=o;}delete m.style;delete m.name;delete m.url;delete m.root;delete m.onload;delete m.onerror;var u=ES('Object','assign',false,{frameBorder:0,allowTransparency:true,allowFullscreen:true,scrolling:'no'},m);if(u.width)n.width=u.width+'px';if(u.height)n.height=u.height+'px';delete u.height;delete u.width;for(var v in u)if(u.hasOwnProperty(v))n.setAttribute(v,u[v]);ES('Object','assign',false,n.style,q);n.src=i();p.appendChild(n);if(s)var w=h.add(n,'load',function(){w.remove();s();});if(t)var x=h.add(n,'error',function(){x.remove();t();});n.src=r;return n;}f.exports=l;},null);\n    __d('sdk.feature',['JSSDKConfig','invariant'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();function j(k,l){!(arguments.length>=2)?i(0):undefined;if(h.features&&k in h.features){var m=h.features[k];if(typeof m==='object'&&typeof m.rate==='number'){if(m.rate&&Math.random()*100<=m.rate){return m.value||true;}else return m.value?null:false;}else return m;}return l;}f.exports=j;},null);\n    __d('sdk.XD',['sdk.Content','sdk.Event','Log','QueryString','Queue','sdk.RPC','sdk.Runtime','sdk.Scribe','sdk.URI','UrlMap','JSSDKXDConfig','XDM','isFacebookURI','sdk.createIframe','sdk.feature','guid'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w){if(c.__markCompiled)c.__markCompiled();var x=new l(),y=new l(),z=new l(),aa,ba,ca=w(),da=r.useCdn?'cdn':'www',ea=v('use_bundle',false)?r.XdBundleUrl:r.XdUrl,fa=q.resolve(da,false)+ea,ga=q.resolve(da,true)+ea,ha=w(),ia=location.protocol+'//'+location.host,ja,ka=false,la='Facebook Cross Domain Communication Frame',ma={},na=new l();m.setInQueue(na);function oa(ua){j.info('Remote XD can talk to facebook.com (%s)',ua);n.setEnvironment(ua==='canvas'?n.ENVIRONMENTS.CANVAS:n.ENVIRONMENTS.PAGETAB);}function pa(ua,va){if(!va){j.error('No senderOrigin');throw new Error();}var wa=/^https?/.exec(va)[0];switch(ua.xd_action){case 'proxy_ready':var xa,ya;if(wa=='https'){xa=z;ya=ba;n.setLoggedIntoFacebook(ua.logged_in==='true');}else{xa=y;ya=aa;}if(ua.registered){oa(ua.registered);x=xa.merge(x);}j.info('Proxy ready, starting queue %s containing %s messages',wa+'ProxyQueue',xa.getLength());xa.start(function(ab){ja.send(typeof ab==='string'?ab:k.encode(ab),va,ya.contentWindow,ha+'_'+wa);});break;case 'plugin_ready':j.info('Plugin %s ready, protocol: %s',ua.name,wa);ma[ua.name]={protocol:wa};if(l.exists(ua.name)){var za=l.get(ua.name);j.debug('Enqueuing %s messages for %s in %s',za.getLength(),ua.name,wa+'ProxyQueue');(wa=='https'?z:y).merge(za);}break;}if(ua.data)qa(ua.data,va);}function qa(ua,va){if(va&&va!=='native'&&!t(new p(va)))return;if(typeof ua=='string'){if(/^FB_RPC:/.test(ua)){na.enqueue(ua.substring(7));return;}if(ua.substring(0,1)=='{'){try{ua=ES('JSON','parse',false,ua);}catch(wa){j.warn('Failed to decode %s as JSON',ua);return;}}else ua=k.decode(ua);}if(!va)if(ua.xd_sig==ca)va=ua.xd_origin;if(ua.xd_action){pa(ua,va);return;}if(ua.access_token)n.setSecure(/^https/.test(ia));if(ua.cb){var xa=ta._callbacks[ua.cb];if(!ta._forever[ua.cb])delete ta._callbacks[ua.cb];if(xa)xa(ua);}}function ra(ua,va){if(ua=='facebook'){va.relation='parent.parent';x.enqueue(va);}else{va.relation='parent.frames[\"'+ua+'\"]';var wa=ma[ua];if(wa){j.debug('Enqueuing message for plugin %s in %s',ua,wa.protocol+'ProxyQueue');(wa.protocol=='https'?z:y).enqueue(va);}else{j.debug('Buffering message for plugin %s',ua);l.get(ua).enqueue(va);}}}m.getOutQueue().start(function(ua){ra('facebook','FB_RPC:'+ua);});function sa(ua){if(ka)return;var va=h.appendHidden(document.createElement('div')),wa=s.create({blacklist:null,root:va,channel:ha,flashUrl:r.Flash.path,whenReady:function(xa){ja=xa;var ya={channel:ha,origin:location.protocol+'//'+location.host,transport:wa,xd_name:ua},za='#'+k.encode(ya);if(n.getSecure()!==true)aa=u({url:fa+za,name:'fb_xdm_frame_http',id:'fb_xdm_frame_http',root:va,'aria-hidden':true,title:la,tabindex:-1});ba=u({url:ga+za,name:'fb_xdm_frame_https',id:'fb_xdm_frame_https',root:va,'aria-hidden':true,title:la,tabindex:-1});},onMessage:qa});if(!wa)o.log('jssdk_error',{appId:n.getClientID(),error:'XD_TRANSPORT',extra:{message:'Failed to create a valid transport'}});ka=true;}var ta={rpc:m,_callbacks:{},_forever:{},_channel:ha,_origin:ia,onMessage:qa,recv:qa,init:sa,sendToFacebook:ra,inform:function(ua,va,wa,xa){ra('facebook',{method:ua,params:ES('JSON','stringify',false,va||{}),behavior:xa||'p',relation:wa});},handler:function(ua,va,wa,xa){var ya='#'+k.encode({cb:this.registerCallback(ua,wa,xa),origin:ia+'/'+ha,domain:location.hostname,relation:va||'opener'});return (location.protocol=='https:'?ga:fa)+ya;},registerCallback:function(ua,va,wa){wa=wa||w();if(va)ta._forever[wa]=true;ta._callbacks[wa]=ua;return wa;}};i.subscribe('init:post',function(ua){sa(ua.xdProxyName);var va=v('xd_timeout',false);if(va)setTimeout(function(){var wa=ba&&(!!aa==y.isStarted()&&!!ba==z.isStarted());if(!wa)o.log('jssdk_error',{appId:n.getClientID(),error:'XD_INITIALIZATION',extra:{message:'Failed to initialize in '+va+'ms'}});},va);});f.exports=ta;},null);\n    __d('sdk.getContextType',['sdk.Runtime','sdk.UA'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();function j(){if(i.nativeApp())return 3;if(i.mobile())return 2;if(h.isEnvironment(h.ENVIRONMENTS.CANVAS))return 5;return 1;}f.exports=j;},null);\n    __d('sdk.Auth',['sdk.Cookie','sdk.createIframe','DOMWrapper','sdk.feature','sdk.getContextType','guid','sdk.Impressions','Log','ObservableMixin','sdk.Runtime','sdk.SignedRequest','UrlMap','sdk.URI','sdk.XD'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){if(c.__markCompiled)c.__markCompiled();var v='fblo_',w=365*24*60*60*1000,x,y,z=new p();function aa(ga,ha){var ia=q.getUserID(),ja='';if(ga)if(ga.userID){ja=ga.userID;}else if(ga.signedRequest){var ka=r.parse(ga.signedRequest);if(ka&&ka.user_id)ja=ka.user_id;}var la=q.getLoginStatus(),ma=la==='unknown'&&ga||q.getUseCookie()&&q.getCookieUserID()!==ja,na=ia&&!ga,oa=ga&&ia&&ia!=ja,pa=ga!=x,qa=ha!=(la||'unknown');q.setLoginStatus(ha);q.setAccessToken(ga&&ga.accessToken||null);q.setUserID(ja);x=ga;var ra={authResponse:ga,status:ha};if(na||oa)z.inform('logout',ra);if(ma||oa)z.inform('login',ra);if(pa)z.inform('authresponse.change',ra);if(qa)z.inform('status.change',ra);return ra;}function ba(){return x;}function ca(ga,ha,ia){return function(ja){var ka;if(ja&&ja.access_token){var la=r.parse(ja.signed_request);ha={accessToken:ja.access_token,userID:la.user_id,expiresIn:parseInt(ja.expires_in,10),signedRequest:ja.signed_request};if(ja.granted_scopes)ha.grantedScopes=ja.granted_scopes;if(q.getUseCookie()){var ma=ha.expiresIn===0?0:ES('Date','now',false)+ha.expiresIn*1000,na=h.getDomain();if(!na&&ja.base_domain)h.setDomain('.'+ja.base_domain);h.setSignedRequestCookie(ja.signed_request,ma);h.setRaw(v,'',0);}ka='connected';aa(ha,ka);}else if(ia==='logout'||ia==='login_status'){if(ja.error&&ja.error==='not_authorized'){ka='not_authorized';}else ka='unknown';aa(null,ka);if(q.getUseCookie())h.clearSignedRequestCookie();if(ia==='logout')h.setRaw(v,'y',ES('Date','now',false)+w);}if(ja&&ja.https==1)q.setSecure(true);if(ga)ga({authResponse:ha,status:q.getLoginStatus()});return ha;};}function da(ga){var ha,ia=ES('Date','now',false);if(y){clearTimeout(y);y=null;}if(h.getRaw(v)==='y'){var ja='unknown';aa(null,ja);if(ga)ga({authResponse:null,status:ja});return;}var ka=ca(ga,x,'login_status'),la=new t(s.resolve('www',true)+'/connect/ping').setQueryData({client_id:q.getClientID(),response_type:'token,signed_request,code',domain:location.hostname,origin:l(),redirect_uri:u.handler(function(ma){if(k('e2e_ping_tracking',true)){var na={init:ia,close:ES('Date','now',false),method:'ping'};o.debug('e2e: %s',ES('JSON','stringify',false,na));n.log(114,{payload:na});}ha.parentNode.removeChild(ha);if(ka(ma))y=setTimeout(function(){da(function(){});},1200000);},'parent'),sdk:'joey',kid_directed_site:q.getKidDirectedSite()});ha=i({root:j.getRoot(),name:m(),url:la.toString(),style:{display:'none'}});}var ea;function fa(ga,ha){if(!q.getClientID()){o.warn('FB.getLoginStatus() called before calling FB.init().');return;}if(ga)if(!ha&&ea=='loaded'){ga({status:q.getLoginStatus(),authResponse:ba()});return;}else z.subscribe('FB.loginStatus',ga);if(!ha&&ea=='loading')return;ea='loading';var ia=function(ja){ea='loaded';z.inform('FB.loginStatus',ja);z.clearSubscribers('FB.loginStatus');};da(ia);}ES('Object','assign',false,z,{getLoginStatus:fa,fetchLoginStatus:da,setAuthResponse:aa,getAuthResponse:ba,parseSignedRequest:r.parse,xdResponseWrapper:ca});f.exports=z;},null);\n    __d('sdk.DOM',['Assert','sdk.UA','sdk.domReady'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k={};function l(z,aa){var ba=z.getAttribute(aa)||z.getAttribute(aa.replace(/_/g,'-'))||z.getAttribute(aa.replace(/-/g,'_'))||z.getAttribute(aa.replace(/-/g,''))||z.getAttribute(aa.replace(/_/g,''))||z.getAttribute('data-'+aa)||z.getAttribute('data-'+aa.replace(/_/g,'-'))||z.getAttribute('data-'+aa.replace(/-/g,'_'))||z.getAttribute('data-'+aa.replace(/-/g,''))||z.getAttribute('data-'+aa.replace(/_/g,''));return ba?String(ba):null;}function m(z,aa){var ba=l(z,aa);return ba?/^(true|1|yes|on)$/.test(ba):null;}function n(z,aa){h.isTruthy(z,'element not specified');h.isString(aa);try{return String(z[aa]);}catch(ba){throw new Error('Could not read property '+aa+' : '+ba.message);}}function o(z,aa){h.isTruthy(z,'element not specified');h.isString(aa);try{z.innerHTML=aa;}catch(ba){throw new Error('Could not set innerHTML : '+ba.message);}}function p(z,aa){h.isTruthy(z,'element not specified');h.isString(aa);var ba=' '+n(z,'className')+' ';return ES(ba,'indexOf',true,' '+aa+' ')>=0;}function q(z,aa){h.isTruthy(z,'element not specified');h.isString(aa);if(!p(z,aa))z.className=n(z,'className')+' '+aa;}function r(z,aa){h.isTruthy(z,'element not specified');h.isString(aa);var ba=new RegExp('\\\\s*'+aa,'g');z.className=ES(n(z,'className').replace(ba,''),'trim',true);}function s(z,aa,ba){h.isString(z);aa=aa||document.body;ba=ba||'*';if(aa.querySelectorAll)return ES('Array','from',false,aa.querySelectorAll(ba+'.'+z));var ca=aa.getElementsByTagName(ba),da=[];for(var ea=0,fa=ca.length;ea<fa;ea++)if(p(ca[ea],z))da[da.length]=ca[ea];return da;}function t(z,aa){h.isTruthy(z,'element not specified');h.isString(aa);aa=aa.replace(/-(\\w)/g,function(da,ea){return ea.toUpperCase();});var ba=z.currentStyle||document.defaultView.getComputedStyle(z,null),ca=ba[aa];if(/backgroundPosition?/.test(aa)&&/top|left/.test(ca))ca='0%';return ca;}function u(z,aa,ba){h.isTruthy(z,'element not specified');h.isString(aa);aa=aa.replace(/-(\\w)/g,function(ca,da){return da.toUpperCase();});z.style[aa]=ba;}function v(z,aa){var ba=true;for(var ca=0,da;da=aa[ca++];)if(!(da in k)){ba=false;k[da]=true;}if(ba)return;if(i.ie()<11){try{document.createStyleSheet().cssText=z;}catch(ea){if(document.styleSheets[0])document.styleSheets[0].cssText+=z;}}else{var fa=document.createElement('style');fa.type='text/css';fa.textContent=z;document.getElementsByTagName('head')[0].appendChild(fa);}}function w(){var z=document.documentElement&&document.compatMode=='CSS1Compat'?document.documentElement:document.body;return {scrollTop:z.scrollTop||document.body.scrollTop,scrollLeft:z.scrollLeft||document.body.scrollLeft,width:window.innerWidth?window.innerWidth:z.clientWidth,height:window.innerHeight?window.innerHeight:z.clientHeight};}function x(z){h.isTruthy(z,'element not specified');var aa=0,ba=0;do{aa+=z.offsetLeft;ba+=z.offsetTop;}while(z=z.offsetParent);return {x:aa,y:ba};}var y={containsCss:p,addCss:q,removeCss:r,getByClass:s,getStyle:t,setStyle:u,getAttr:l,getBoolAttr:m,getProp:n,html:o,addCssRules:v,getViewportInfo:w,getPosition:x,ready:j};f.exports=y;},null);\n    __d('sdk.ErrorHandling',['ManagedError','sdk.Runtime','sdk.Scribe','sdk.UA','sdk.feature','wrapFunction'],function a(b,c,d,e,f,g,h,i,j,k,l,m){if(c.__markCompiled)c.__markCompiled();var n=l('error_handling',false),o='';function p(v){var w=v._originalError;delete v._originalError;j.log('jssdk_error',{appId:i.getClientID(),error:v.name||v.message,extra:v});throw w;}function q(v){var w={line:v.lineNumber||v.line,message:v.message,name:v.name,script:v.fileName||v.sourceURL||v.script,stack:v.stackTrace||v.stack};w._originalError=v;if(k.chrome()&&/([\\w:\\.\\/]+\\.js):(\\d+)/.test(v.stack)){w.script=RegExp.$1;w.line=parseInt(RegExp.$2,10);}for(var x in w)w[x]==null&&delete w[x];return w;}function r(v,w){return function(){if(!n)return v.apply(this,arguments);try{o=w;return v.apply(this,arguments);}catch(x){if(x instanceof h)throw x;var y=q(x);y.entry=w;var z=ES(Array.prototype.slice.call(arguments),'map',true,function(aa){var ba=Object.prototype.toString.call(aa);return (/^\\[object (String|Number|Boolean|Object|Date)\\]$/.test(ba)?aa:aa.toString());});y.args=ES('JSON','stringify',false,z).substring(0,200);p(y);}finally{o='';}};}function s(v){if(!v.__wrapper)v.__wrapper=function(){try{return v.apply(this,arguments);}catch(w){window.setTimeout(function(){throw w;},0);return false;}};return v.__wrapper;}function t(v,w){return function(x,y){var z=w+':'+(o||'[global]')+':'+(x.name||'[anonymous]'+(arguments.callee.caller.name?'('+arguments.callee.caller.name+')':''));return v(m(x,'entry',z),y);};}if(n){setTimeout=t(setTimeout,'setTimeout');setInterval=t(setInterval,'setInterval');m.setWrapper(r,'entry');}var u={guard:r,unguard:s};f.exports=u;},null);\n    __d('sdk.Insights',['sdk.Impressions'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i={TYPE:{NOTICE:'notice',WARNING:'warn',ERROR:'error'},CATEGORY:{DEPRECATED:'deprecated',APIERROR:'apierror'},log:function(j,k,l){var m={source:'jssdk',type:j,category:k,payload:l};h.log(113,m);},impression:h.impression};f.exports=i;},null);\n    __d('FB',['sdk.Auth','JSSDKCssConfig','dotAccess','sdk.domReady','sdk.DOM','sdk.ErrorHandling','sdk.Content','DOMWrapper','GlobalCallback','sdk.Insights','Log','sdk.Runtime','sdk.Scribe','JSSDKConfig'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){if(c.__markCompiled)c.__markCompiled();var v,w,x=j(u,'api.mode'),y={};v=window.FB={};var z={};r.level=0;p.setPrefix('FB.__globalCallbacks');var aa=document.createElement('div');o.setRoot(aa);k(function(){r.info('domReady');n.appendHidden(aa);if(i.rules)l.addCssRules(i.rules,i.components);});s.subscribe('AccessToken.change',function(da){if(!da&&s.getLoginStatus()==='connected')h.getLoginStatus(null,true);});if(j(u,'api.whitelist.length')){w={};ES(u.api.whitelist,'forEach',true,function(da){w[da]=1;});}function ba(da,ea,fa,ga){var ha;if(/^_/.test(fa)){ha='hide';}else if(w&&!w[ea])ha=x;switch(ha){case 'hide':return;case 'stub':return function(){r.warn('The method FB.%s has been removed from the JS SDK.',ea);};default:return m.guard(function(){if(ha==='warn'){r.warn('The method FB.%s is not officially supported by '+'Facebook and access to it will soon be removed.',ea);if(!y.hasOwnProperty(ea)){q.log(q.TYPE.WARNING,q.CATEGORY.DEPRECATED,'FB.'+ea);t.log('jssdk_error',{appId:s.getClientID(),error:'Private method used',extra:{args:ea}});y[ea]=true;}}function ia(pa){if(ES('Array','isArray',false,pa))return ES(pa,'map',true,ia);if(pa&&typeof pa==='object'&&pa.__wrapped)return pa.__wrapped;return typeof pa==='function'&&/^function/.test(pa.toString())?m.unguard(pa):pa;}var ja=ES(Array.prototype.slice.call(arguments),'map',true,ia),ka=da.apply(ga,ja),la,ma=true;if(ka&&typeof ka==='object'){la=ES('Object','create',false,ka);la.__wrapped=ka;for(var na in ka){var oa=ka[na];if(typeof oa!=='function'||na==='constructor')continue;ma=false;la[na]=ba(oa,ea+':'+na,na,ka);}}if(!ma)return la;return ma?ka:la;},ea);}}function ca(da,ea){var fa=da?j(v,da,true):v;ES(ES('Object','keys',false,ea),'forEach',true,function(ga){var ha=ea[ga];if(typeof ha==='function'){var ia=(da?da+'.':'')+ga,ja=ba(ha,ia,ga,ea);if(ja)fa[ga]=ja;}else if(typeof ha==='object'){ia=(da?da+'.':'')+ga;if(w&&w[ia])fa[ga]=ha;}});}s.setSecure((function(){var da=/iframe_canvas|app_runner/.test(window.name),ea=/dialog/.test(window.name);if(location.protocol=='https:'&&(window==top||!(da||ea)))return true;if(/_fb_https?/.test(window.name))return ES(window.name,'indexOf',true,'_fb_https')!=-1;})());ES('Object','assign',false,z,{provide:ca});f.exports=z;},null);\n    __d('ArgumentError',['ManagedError'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();function i(j,k){h.prototype.constructor.apply(this,arguments);}i.prototype=new h();i.prototype.constructor=i;f.exports=i;},null);\n    __d('CORSRequest',['wrapFunction','QueryString'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();function j(m,n){if(!self.XMLHttpRequest)return null;var o=new XMLHttpRequest(),p=function(){};if('withCredentials' in o){o.open(m,n,true);o.setRequestHeader('Content-type','application/x-www-form-urlencoded');}else if(self.XDomainRequest){o=new XDomainRequest();try{o.open(m,n);o.onprogress=o.ontimeout=p;}catch(q){return null;}}else return null;var r={send:function(u){o.send(u);}},s=h(function(){s=p;if('onload' in r)r.onload(o);},'entry','XMLHttpRequest:load'),t=h(function(){t=p;if('onerror' in r)r.onerror(o);},'entry','XMLHttpRequest:error');o.onload=function(){s();};o.onerror=function(){t();};o.onreadystatechange=function(){if(o.readyState==4)if(o.status==200){s();}else t();};return r;}function k(m,n,o,p){o.suppress_http_code=1;var q=i.encode(o);if(n!='post'){m=i.appendToUrl(m,q);q='';}var r=j(n,m);if(!r)return false;r.onload=function(s){p(ES('JSON','parse',false,s.responseText));};r.onerror=function(s){if(s.responseText){p(ES('JSON','parse',false,s.responseText));}else p({error:{type:'http',message:'unknown error',status:s.status}});};r.send(q);return true;}var l={execute:k};f.exports=l;},null);\n    __d('FlashRequest',['DOMWrapper','Flash','GlobalCallback','QueryString','Queue'],function a(b,c,d,e,f,g,h,i,j,k,l){if(c.__markCompiled)c.__markCompiled();var m,n={},o,p;function q(){if(!o)throw new Error('swfUrl has not been set');var t=j.create(function(){m.start(function(v){var w=p.execute(v.method,v.url,v.body);if(!w)throw new Error('Could create request');n[w]=v.callback;});}),u=j.create(function(v,w,x){var y;try{y=ES('JSON','parse',false,decodeURIComponent(x));}catch(z){y={error:{type:'SyntaxError',message:z.message,status:w,raw:x}};}n[v](y);delete n[v];});p=i.embed(o,h.getRoot(),null,{log:false,initCallback:t,requestCallback:u});}function r(t,u,v,w){v.suppress_http_code=1;if(!v.method)v.method=u;var x=k.encode(v);if(u==='get'&&t.length+x.length<2000){t=k.appendToUrl(t,x);x='';}else u='post';if(!m){if(!i.isAvailable())return false;m=new l();q();}m.enqueue({method:u,url:t,body:x,callback:w});return true;}var s={setSwfUrl:function(t){o=t;},execute:r};f.exports=s;},null);\n    __d('JSONPRequest',['DOMWrapper','GlobalCallback','QueryString'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k=2000;function l(n,o,p,q){var r=document.createElement('script'),s=function(u){s=function(){};i.remove(p.callback);q(u);r.parentNode.removeChild(r);};p.callback=i.create(s);if(!p.method)p.method=o;n=j.appendToUrl(n,p);if(n.length>k){i.remove(p.callback);return false;}r.onerror=function(){s({error:{type:'http',message:'unknown error'}});};var t=function(){setTimeout(function(){s({error:{type:'http',message:'unknown error'}});},0);};if(r.addEventListener){r.addEventListener('load',t,false);}else r.onreadystatechange=function(){if(/loaded|complete/.test(this.readyState))t();};r.src=n;h.getRoot().appendChild(r);return true;}var m={execute:l,MAX_QUERYSTRING_LENGTH:k};f.exports=m;},null);\n    __d('flattenObject',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(i){var j={};for(var k in i)if(i.hasOwnProperty(k)){var l=i[k];if(null===l||undefined===l){}else if(typeof l=='string'){j[k]=l;}else j[k]=ES('JSON','stringify',false,l);}return j;}f.exports=h;},null);\n    __d('ApiClient',['ArgumentError','Assert','CORSRequest','FlashRequest','flattenObject','JSONPRequest','Log','ObservableMixin','QueryString','sprintf','sdk.URI','UrlMap','ApiClientConfig','invariant'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u){if(c.__markCompiled)c.__markCompiled();var v,w,x,y=m.MAX_QUERYSTRING_LENGTH,z={get:true,post:true,'delete':true,put:true},aa={fql_query:true,fql_multiquery:true,friends_get:true,notifications_get:true,stream_get:true,users_getinfo:true},ba=['jsonp','cors','flash'],ca=[],da=[],ea=null,fa=0,ga=[],ha=0,ia=50,ja=105440539523;function ka(ua,va,wa,xa){var ya=ha!==0&&fa>=ha;if(ya){ga.push(function(){return ka(ua,va,wa,xa);});sa.inform('request.queued',ua,va,wa);return;}fa++;if(x)wa=ES('Object','assign',false,{},x,wa);wa.access_token=wa.access_token||v;wa.pretty=wa.pretty||0;wa=l(wa);var za={jsonp:m,cors:j,flash:k},ab;if(wa.transport){ab=[wa.transport];delete wa.transport;}else ab=ba;for(var bb=0;bb<ab.length;bb++){var cb=za[ab[bb]],db=ES('Object','assign',false,{},wa);if(cb.execute(ua,va,db,xa))return;}xa({error:{type:'no-transport',message:'Could not find a usable transport for request'}});}function la(ua,va,wa,xa,ya,za){if(za&&za.error)sa.inform('request.error',va,wa,xa,za,ES('Date','now',false)-ya);sa.inform('request.complete',va,wa,xa,za,ES('Date','now',false)-ya);fa--;if(ua)ua(za);var ab=ga.length>0&&fa<ha;if(ab){var bb=ga.shift();bb();}}function ma(ua){var va=ua.shift();i.isString(va,'Invalid path');if(!/^https?/.test(va)&&va.charAt(0)!=='/')va='/'+va;var wa,xa={};try{wa=new r(va);}catch(ya){throw new h(ya.message,ya);}ES(ua,'forEach',true,function(cb){return xa[typeof cb]=cb;});var za=(xa.string||'get').toLowerCase();i.isTrue(z.hasOwnProperty(za),q('Invalid method passed to ApiClient: %s',za));var ab=xa['function'];if(!ab)n.warn('No callback passed to the ApiClient');if(xa.object)wa.addQueryData(l(xa.object));var bb=wa.getQueryData();bb.method=za;return {uri:wa,callback:ab,params:bb};}function na(){for(var ua=arguments.length,va=Array(ua),wa=0;wa<ua;wa++)va[wa]=arguments[wa];var xa=ma(va),ya=xa.uri,za=xa.callback,ab=xa.params,bb=ab.method;if(ta(ya,bb))bb='post';var cb=ya.getProtocol()&&ya.getDomain()?ya.setQueryData({}).toString():s.resolve('graph')+ya.getPath();sa.inform('request.prepare',cb,ab);ka(cb,bb=='get'?'get':'post',ab,ES(la,'bind',true,null,za,ya.getPath(),bb,ab,ES('Date','now',false)));}function oa(ua){var va=ma(ua),wa=va.uri,xa=va.callback,ya=va.params.method,za,ab=wa.removeQueryData('method').toString();if(ya.toLowerCase()=='post'){za=p.encode(wa.getQueryData());ab=wa.setQueryData({}).toString();}return {body:za,callback:xa,method:ya,relative_url:ab};}function pa(){for(var ua=arguments.length,va=Array(ua),wa=0;wa<ua;wa++)va[wa]=arguments[wa];var xa=oa(va),ya=xa.body,za=xa.callback,ab=xa.method,bb=xa.relative_url,cb={method:ab,relative_url:bb};if(ya)cb.body=ya;ca.push(cb);da.push(za);if(ca.length==ia){if(ea)clearTimeout(ea);qa();}else if(!ea)ea=setTimeout(qa,0);}function qa(){!(ca.length>0)?u(0):undefined;!(ca.length===da.length)?u(0):undefined;var ua=ca,va=da;ca=[];da=[];ea=null;if(ua.length===1){var wa=ua[0],xa=va[0],ya=wa.body?p.decode(wa.body):null;na(wa.relative_url,wa.method,ya,xa);return;}na('/','POST',{batch:ua,include_headers:false,batch_app_id:w||ja},function(za){if(ES('Array','isArray',false,za)){ES(za,'forEach',true,function(ab,bb){va[bb](ES('JSON','parse',false,ab.body));});}else ES(va,'forEach',true,function(ab){return (ab({error:{message:'Fatal: batch call failed.'}}));});});}function ra(ua,va){i.isObject(ua);i.isString(ua.method,'method missing');if(!va)n.warn('No callback passed to the ApiClient');var wa=ua.method.toLowerCase().replace('.','_');ua.format='json-strings';ua.api_key=w;var xa=wa in aa?'api_read':'api',ya=s.resolve(xa)+'/restserver.php',za=ES(la,'bind',true,null,va,'/restserver.php','get',ua,ES('Date','now',false));ka(ya,'get',ua,za);}var sa=ES('Object','assign',false,new o(),{setAccessToken:function(ua){v=ua;},setAccessTokenForClientID:function(ua,va){if(!(v&&w&&w!==va))v=ua;},getAccessToken:function(){return v;},setClientID:function(ua){w=ua;},setDefaultParams:function(ua){x=ua;},setDefaultTransports:function(ua){ba=ua;},setMaxConcurrentRequests:function(ua){ha=ua;},getCurrentlyExecutingRequestCount:function(){return fa;},getQueuedRequestCount:function(){return ga.length;},rest:ra,graph:na,scheduleBatchCall:pa,prepareBatchParams:oa});function ta(ua,va){return ua.toString().length>y&&va==='get';}k.setSwfUrl(t.FlashRequest.swfUrl);f.exports=sa;},null);\n    __d('sdk.PlatformVersioning',['sdk.Runtime','ManagedError'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();var j=/^v\\d+\\.\\d\\d?$/,k={REGEX:j,assertVersionIsSet:function(){if(!h.getVersion())throw new i('init not called with valid version');},assertValidVersion:function(l){if(!j.test(l))throw new i('invalid version specified');}};f.exports=k;},null);\n    __d('sdk.api',['ApiClient','sdk.PlatformVersioning','sdk.Runtime','sdk.Scribe','sdk.URI','sdk.feature'],function a(b,c,d,e,f,g,h,i,j,k,l,m){if(c.__markCompiled)c.__markCompiled();var n=m('should_log_response_error',false),o;j.subscribe('ClientID.change',function(q){return h.setClientID(q);});j.subscribe('AccessToken.change',function(q){o=q;h.setAccessToken(q);});h.setDefaultParams({sdk:'joey'});h.subscribe('request.complete',function(q,r,s,t){var u=false;if(t&&typeof t=='object')if(t.error){if(t.error=='invalid_token'||t.error.type=='OAuthException'&&t.error.code==190)u=true;}else if(t.error_code)if(t.error_code=='190')u=true;if(u&&o===j.getAccessToken())j.setAccessToken(null);});h.subscribe('request.complete',function(q,r,s,t){if((q=='/me/permissions'&&r==='delete'||q=='/restserver.php'&&s.method=='Auth.revokeAuthorization')&&t===true)j.setAccessToken(null);});h.subscribe('request.error',function(q,r,s,t){if(n&&t.error.type==='http')k.log('jssdk_error',{appId:j.getClientID(),error:'transport',extra:{name:'transport',message:ES('JSON','stringify',false,t.error)}});});function p(q){if(typeof q==='string'){if(j.getIsVersioned()){i.assertVersionIsSet();if(!/https?/.test(q)&&q.charAt(0)!=='/')q='/'+q;q=new l(q).setDomain(null).setProtocol(null).toString();if(!i.REGEX.test(q.substring(1,ES(q,'indexOf',true,'/',1))))q='/'+j.getVersion()+q;var r=[q].concat(Array.prototype.slice.call(arguments,1));h.graph.apply(h,r);}else h.graph.apply(h,arguments);}else h.rest.apply(h,arguments);}f.exports=p;},null);\n    __d('legacy:fb.api',['FB','sdk.api'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();h.provide('',{api:i});},3);\n    __d('sdk.AppEvents',['Assert','sdk.Impressions','sdk.Runtime'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k={COMPLETED_REGISTRATION:'fb_mobile_complete_registration',VIEWED_CONTENT:'fb_mobile_content_view',SEARCHED:'fb_mobile_search',RATED:'fb_mobile_rate',COMPLETED_TUTORIAL:'fb_mobile_tutorial_completion',ADDED_TO_CART:'fb_mobile_add_to_cart',ADDED_TO_WISHLIST:'fb_mobile_add_to_wishlist',INITIATED_CHECKOUT:'fb_mobile_initiated_checkout',ADDED_PAYMENT_INFO:'fb_mobile_add_payment_info',ACHIEVED_LEVEL:'fb_mobile_level_achieved',UNLOCKED_ACHIEVEMENT:'fb_mobile_achievement_unlocked',SPENT_CREDITS:'fb_mobile_spent_credits'},l={ACTIVATED_APP:'fb_mobile_activate_app',PURCHASED:'fb_mobile_purchase'},m={CURRENCY:'fb_currency',REGISTRATION_METHOD:'fb_registration_method',CONTENT_TYPE:'fb_content_type',CONTENT_ID:'fb_content_id',SEARCH_STRING:'fb_search_string',SUCCESS:'fb_success',MAX_RATING_VALUE:'fb_max_rating_value',PAYMENT_INFO_AVAILABLE:'fb_payment_info_available',NUM_ITEMS:'fb_num_items',LEVEL:'fb_level',DESCRIPTION:'fb_description'},n=40,o='^[0-9a-zA-Z_]+[0-9a-zA-Z _-]*$';function p(t,u,v,w){h.isTrue(q(u),'Invalid event name: '+u+'. '+'It must be between 1 and '+n+' characters, '+'and must be contain only alphanumerics, _, - or spaces, '+'starting with alphanumeric or _.');var x={ae:1,ev:u,vts:v,canvas:j.isCanvasEnvironment()?1:0};if(w)x.cd=w;i.impression({api_key:t,payload:ES('JSON','stringify',false,x)});}function q(t){if(t===null||t.length===0||t.length>n||!new RegExp(o).test(t))return false;return true;}function r(t,u,v,w){var x={};x[m.CURRENCY]=v;p(t,l.PURCHASED,u,babelHelpers._extends({},w,x));}function s(t){p(t,l.ACTIVATED_APP);}f.exports={activateApp:s,logEvent:p,logPurchase:r,isValidEventName:q,EventNames:k,ParameterNames:m};},null);\n    __d('legacy:fb.appevents',['Assert','sdk.AppEvents','FB','sdk.feature','sdk.Runtime'],function a(b,c,d,e,f,g,h,i,j,k,l){if(c.__markCompiled)c.__markCompiled();j.provide('AppEvents',{logEvent:function(m,n,o){h.isTrue(k('allow_non_canvas_app_events',false)||l.isCanvasEnvironment(),'You can only use this function in Facebook Canvas environment');h.isString(m,'Invalid eventName');h.maybeNumber(n,'Invalid valueToSum');h.maybeObject(o,'Invalid params');var p=l.getClientID();h.isTrue(p!==null&&p.length>0,'You need to call FB.init() with App ID first.');i.logEvent(p,m,n,o);},logPurchase:function(m,n,o){h.isTrue(k('allow_non_canvas_app_events',false)||l.isCanvasEnvironment(),'You can only use this function in Facebook Canvas environment');h.isNumber(m,'Invalid purchaseAmount');h.isString(n,'Invalid currency');h.maybeObject(o,'Invalid params');var p=l.getClientID();h.isTrue(p!==null&&p.length>0,'You need to call FB.init() with App ID first.');i.logPurchase(p,m,n,o);},activateApp:function(){h.isTrue(k('allow_non_canvas_app_events',false)||l.isCanvasEnvironment(),'You can only use this function in Facebook Canvas environment');var m=l.getClientID();h.isTrue(m!==null&&m.length>0,'You need to call FB.init() with App ID first.');i.activateApp(m);},EventNames:i.EventNames,ParameterNames:i.ParameterNames});},3);\n    __d('resolveURI',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(i){if(!i)return window.location.href;i=i.replace(/&/g,'&amp;').replace(/\"/g,'&quot;');var j=document.createElement('div');j.innerHTML='<a href=\"'+i+'\"></a>';return j.firstChild.href;}f.exports=h;},null);\n    __d('sdk.Canvas.Environment',['sdk.RPC'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();function i(l){h.remote.getPageInfo(function(m){l(m.result);});}function j(l,m){h.remote.scrollTo({x:l||0,y:m||0});}h.stub('getPageInfo');h.stub('scrollTo');var k={getPageInfo:i,scrollTo:j};f.exports=k;},null);\n    __d('sdk.fbt',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={_:function(i){return typeof i==='string'?i:i[0];}};f.exports=h;},null);\n    __d('sdk.Dialog',['sdk.Canvas.Environment','sdk.Content','sdk.DOM','DOMEventListener','ObservableMixin','sdk.Runtime','Type','sdk.UA','sdk.fbt','sdk.feature'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){if(c.__markCompiled)c.__markCompiled();var r=30,s=590,t=500,u=240,v=575;function w(){if(q('dialog_resize_refactor',false)){var z=j.getViewportInfo();if(z.height&&z.width)return {width:Math.min(z.width,t),height:Math.min(z.height,s)};}return null;}var x=n.extend({constructor:function z(aa,ba){this.parent();this.id=aa;this.display=ba;this._e2e={};if(!y._dialogs){y._dialogs={};y._addOrientationHandler();}y._dialogs[aa]=this;this.trackEvent('init');},trackEvent:function(z,aa){if(this._e2e[z])return this;this._e2e[z]=aa||ES('Date','now',false);if(z=='close')this.inform('e2e:end',this._e2e);return this;},trackEvents:function(z){if(typeof z==='string')z=ES('JSON','parse',false,z);for(var aa in z)if(z.hasOwnProperty(aa))this.trackEvent(aa,z[aa]);return this;}},l),y={newInstance:function(z,aa){return new x(z,aa);},_dialogs:null,_lastYOffset:0,_overlayListeners:[],_loaderEl:null,_overlayEl:null,_stack:[],_active:null,_forceTabletStyle:null,_closeOnOverlayTap:null,get:function(z){return y._dialogs[z];},_findRoot:function(z){while(z){if(j.containsCss(z,'fb_dialog'))return z;z=z.parentNode;}},_createWWWLoader:function(z){z=z?z:460;return y.create({content:'<div class=\"dialog_title\">'+'  <a id=\"fb_dialog_loader_close\">'+'    <div class=\"fb_dialog_close_icon\"></div>'+'  </a>'+'  <span>Facebook</span>'+'  <div style=\"clear:both;\"></div>'+'</div>'+'<div class=\"dialog_content\"></div>'+'<div class=\"dialog_footer\"></div>',width:z});},_createMobileLoader:function(){var z;if(o.nativeApp()){z='<div class=\"dialog_header\"></div>';}else if(y.isTabletStyle()){z='<div class=\"overlayLoader\">'+'<div id=\"fb_dialog_loader_spinner\"></div>'+'<a id=\"fb_dialog_loader_close\" href=\"#\">'+p._(\"Cancel\")+'</a>'+'</div>';}else z='<div class=\"dialog_header\">'+'<table>'+'  <tbody>'+'    <tr>'+'      <td class=\"header_left\">'+'        <label class=\"touchable_button\">'+'          <input type=\"submit\" value=\"'+p._(\"Cancel\")+'\"'+'            id=\"fb_dialog_loader_close\"/>'+'        </label>'+'      </td>'+'      <td class=\"header_center\">'+'        <div>'+'         '+p._(\"Loading...\")+'        </div>'+'      </td>'+'      <td class=\"header_right\">'+'      </td>'+'    </tr>'+'  </tbody>'+'</table>'+'</div>';return y.create({classes:'loading'+(y.isTabletStyle()?' centered':''),content:z});},_restoreBodyPosition:function(){var z=document.body;if(y.isTabletStyle()){j.removeCss(z,'fb_reposition');}else j.removeCss(z,'fb_hidden');},_setDialogOverlayStyle:function(){if(!y._overlayEl)return;var z=j.getViewportInfo();y._overlayEl.style.minHeight=z.height||z.width?z.height+'px':null;y._overlayEl.style.top=z.scrollTop?z.scrollTop+'px':null;},_showTabletOverlay:function(z){if(!y.isTabletStyle())return;if(!y._overlayEl){y._overlayEl=document.createElement('div');y._overlayEl.setAttribute('id','fb_dialog_ipad_overlay');i.append(y._overlayEl,null);}y._setDialogOverlayStyle();if(y._closeOnOverlayTap){var aa=false;setTimeout(function(){return aa=true;},3000);var ba=k.add(y._overlayEl,'click',function(){if(aa)z();});y._overlayListeners.push(ba);}y._overlayEl.className='';},_hideTabletOverlay:function(){if(y.isTabletStyle()){y._overlayEl.className='hidden';ES(y._overlayListeners,'forEach',true,function(z){return z.remove();});y._overlayListeners=[];}},showLoader:function(z,aa){if(!z)z=function(){};var ba=function(){y._hideLoader();y._restoreBodyPosition();y._hideTabletOverlay();z();};y._showTabletOverlay(ba);if(!y._loaderEl)y._loaderEl=y._findRoot(o.mobile()?y._createMobileLoader():y._createWWWLoader(aa));var ca=document.getElementById('fb_dialog_loader_close');if(ca){j.removeCss(ca,'fb_hidden');var da=k.add(ca,'click',ba);y._overlayListeners.push(da);}y._makeActive(y._loaderEl);},setCloseOnOverlayTap:function(z){y._closeOnOverlayTap=!!z;},_hideLoader:function(){if(y._loaderEl&&y._loaderEl==y._active)y._loaderEl.style.top='-10000px';},_makeActive:function(z){y._setDialogSizes();y._lowerActive();y._active=z;if(m.isEnvironment(m.ENVIRONMENTS.CANVAS))h.getPageInfo(function(aa){y._centerActive(aa);});y._centerActive();},_lowerActive:function(){if(!y._active)return;y._active.style.top='-10000px';y._active=null;},_removeStacked:function(z){y._stack=ES(y._stack,'filter',true,function(aa){return aa!=z;});},_centerActive:function(z){var aa=y._active;if(!aa)return;var ba=j.getViewportInfo(),ca=parseInt(aa.offsetWidth,10),da=parseInt(aa.offsetHeight,10),ea=ba.scrollLeft+(ba.width-ca)/2,fa=(ba.height-da)/2.5;if(ea<fa)fa=ea;var ga=ba.height-da-fa,ha=(ba.height-da)/2;if(z)ha=z.scrollTop-z.offsetTop+(z.clientHeight-da)/2;if(ha<fa){ha=fa;}else if(ha>ga)ha=ga;ha+=ba.scrollTop;if(o.mobile()){var ia=100,ja=document.body;if(y.isTabletStyle()){ia+=(ba.height-da)/2;j.addCss(ja,'fb_reposition');}else{j.addCss(ja,'fb_hidden');if(q('dialog_resize_refactor',false))ja.style.width='auto';ha=10000;}var ka=j.getByClass('fb_dialog_padding',aa);if(ka.length)ka[0].style.height=ia+'px';}aa.style.left=(ea>0?ea:0)+'px';aa.style.top=(ha>0?ha:0)+'px';},_setDialogSizes:function(){var z=arguments.length<=0||arguments[0]===undefined?false:arguments[0];if(!o.mobile())return;for(var aa in y._dialogs)if(y._dialogs.hasOwnProperty(aa)){var ba=document.getElementById(aa);if(ba){ba.style.width=y.getDefaultSize().width+'px';if(!z)ba.style.height=y.getDefaultSize().height+'px';}}},getDefaultSize:function(){if(o.mobile()){var z=w();if(z){if(j.getViewportInfo().width<=z.width)z.width=j.getViewportInfo().width-r;if(j.getViewportInfo().height<=z.height)z.height=j.getViewportInfo().height-r;return z;}if(o.ipad())return {width:t,height:s};if(o.android()){return {width:screen.availWidth,height:screen.availHeight};}else{var aa=window.innerWidth,ba=window.innerHeight,ca=aa/ba>1.2;return {width:aa,height:Math.max(ba,ca?screen.width:screen.height)};}}return {width:v,height:u};},_handleOrientationChange:function(){var z=q('dialog_resize_refactor',false)?j.getViewportInfo().width:screen.availWidth;y._availScreenWidth=z;if(y.isTabletStyle()){y._setDialogSizes(true);y._centerActive();y._setDialogOverlayStyle();}else{var aa=y.getDefaultSize().width;for(var ba in y._dialogs)if(y._dialogs.hasOwnProperty(ba)){var ca=document.getElementById(ba);if(ca)ca.style.width=aa+'px';}}},_addOrientationHandler:function(){if(!o.mobile())return;var z=\"onorientationchange\" in window?'orientationchange':'resize';y._availScreenWidth=q('dialog_resize_refactor',false)?j.getViewportInfo().width:screen.availWidth;k.add(window,z,function(aa){return setTimeout(y._handleOrientationChange,50);});},create:function(z){z=z||{};var aa=document.createElement('div'),ba=document.createElement('div'),ca='fb_dialog';if(z.closeIcon&&z.onClose){var da=document.createElement('a');da.className='fb_dialog_close_icon';da.onclick=z.onClose;aa.appendChild(da);}ca+=' '+(z.classes||'');if(o.ie()){ca+=' fb_dialog_legacy';ES(['vert_left','vert_right','horiz_top','horiz_bottom','top_left','top_right','bottom_left','bottom_right'],'forEach',true,function(ga){var ha=document.createElement('span');ha.className='fb_dialog_'+ga;aa.appendChild(ha);});}else ca+=o.mobile()?' fb_dialog_mobile':' fb_dialog_advanced';if(z.content)i.append(z.content,ba);aa.className=ca;var ea=parseInt(z.width,10);if(!isNaN(ea))aa.style.width=ea+'px';ba.className='fb_dialog_content';aa.appendChild(ba);if(o.mobile()){var fa=document.createElement('div');fa.className='fb_dialog_padding';aa.appendChild(fa);}i.append(aa);if(z.visible)y.show(aa);return ba;},show:function(z){var aa=y._findRoot(z);if(aa){y._removeStacked(aa);y._hideLoader();y._makeActive(aa);y._stack.push(aa);if('fbCallID' in z)y.get(z.fbCallID).inform('iframe_show').trackEvent('show');}},hide:function(z){var aa=y._findRoot(z);y._hideLoader();if(aa==y._active){y._lowerActive();y._restoreBodyPosition();y._hideTabletOverlay();if('fbCallID' in z)y.get(z.fbCallID).inform('iframe_hide').trackEvent('hide');}},remove:function(z){z=y._findRoot(z);if(z){var aa=y._active==z;y._removeStacked(z);if(aa){y._hideLoader();if(y._stack.length>0){y.show(y._stack.pop());}else{y._lowerActive();y._restoreBodyPosition();y._hideTabletOverlay();}}else if(y._active===null&&y._stack.length>0)y.show(y._stack.pop());setTimeout(function(){z.parentNode.removeChild(z);},3000);}},isActive:function(z){var aa=y._findRoot(z);return aa&&aa===y._active;},setForceTabletStyle:function(z){y._forceTabletStyle=!!z;},isTabletStyle:function(){var z;if(!o.mobile())return false;if(y._forceTabletStyle)return true;if(q('dialog_resize_refactor',false)){var aa=w();z=aa&&(aa.height>=s||aa.width>=t);}else z=!!o.ipad();return z;}};f.exports=y;},null);\n    __d('sdk.Frictionless',['sdk.Auth','sdk.api','sdk.Event','sdk.Dialog'],function a(b,c,d,e,f,g,h,i,j,k){if(c.__markCompiled)c.__markCompiled();var l={_allowedRecipients:{},_useFrictionless:false,_updateRecipients:function(){l._allowedRecipients={};i('/me/apprequestformerrecipients',function(m){if(!m||m.error)return;ES(m.data,'forEach',true,function(n){l._allowedRecipients[n.recipient_id]=true;});});},init:function(){l._useFrictionless=true;h.getLoginStatus(function(m){if(m.status=='connected')l._updateRecipients();});j.subscribe('auth.login',function(m){if(m.authResponse)l._updateRecipients();});},_processRequestResponse:function(m,n){return function(o){var p=o&&o.updated_frictionless;if(l._useFrictionless&&p)l._updateRecipients();if(o){if(!n&&o.frictionless){k._hideLoader();k._restoreBodyPosition();k._hideIPadOverlay();}delete o.frictionless;delete o.updated_frictionless;}m&&m(o);};},isAllowed:function(m){if(!m)return false;if(typeof m==='number')return m in l._allowedRecipients;if(typeof m==='string')m=m.split(',');m=ES(m,'map',true,function(p){return ES(String(p),'trim',true);});var n=true,o=false;ES(m,'forEach',true,function(p){n=n&&p in l._allowedRecipients;o=true;});return n&&o;}};j.subscribe('init:post',function(m){if(m.frictionlessRequests)l.init();});f.exports=l;},null);\n    __d('sdk.Native',['Log','sdk.UA'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();var j='fbNativeReady',k={onready:function(l){if(!i.nativeApp()){h.error('FB.Native.onready only works when the page is rendered '+'in a WebView of the native Facebook app. Test if this is the '+'case calling FB.UA.nativeApp()');return;}if(window.__fbNative&&!this.nativeReady)ES('Object','assign',false,this,window.__fbNative);if(this.nativeReady){l();}else{var m=function(n){window.removeEventListener(j,m);this.onready(l);};window.addEventListener(j,m,false);}}};f.exports=k;},null);\n    __d('sdk.UIServer',['sdk.Auth','sdk.Content','sdk.DOM','sdk.Dialog','sdk.Event','sdk.Frictionless','Log','sdk.Native','QueryString','sdk.RPC','sdk.Runtime','JSSDKConfig','sdk.UA','UrlMap','sdk.XD','createObjectFrom','sdk.feature','sdk.fbt','flattenObject','sdk.getContextType','guid','insertIframe','resolveURI'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,ba,ca,da){if(c.__markCompiled)c.__markCompiled();var ea={transform:function(ka){if(ka.params.display==='touch'&&ja.canIframe(ka.params)&&window.postMessage){ka.params.channel=ja._xdChannelHandler(ka.id,'parent');if(!t.nativeApp())ka.params.in_iframe=1;return ka;}else return ja.genericTransform(ka);},getXdRelation:function(ka){var la=ka.display;if(la==='touch'&&window.postMessage&&ka.in_iframe)return 'parent';return ja.getXdRelation(ka);}},fa={'stream.share':{size:{width:670,height:340},url:'sharer.php',transform:function(ka){if(!ka.params.u)ka.params.u=window.location.toString();ka.params.display='popup';return ka;}},apprequests:{transform:function(ka){ka=ea.transform(ka);ka.params.frictionless=m&&m._useFrictionless;if(ka.params.frictionless){if(m.isAllowed(ka.params.to)){ka.params.display='iframe';ka.params.in_iframe=true;ka.hideLoader=true;}ka.cb=m._processRequestResponse(ka.cb,ka.hideLoader);}ka.closeIcon=false;return ka;},getXdRelation:ea.getXdRelation},feed:ea,'permissions.oauth':{url:'dialog/oauth',size:{width:t.mobile()?null:475,height:t.mobile()?null:183},transform:function(ka){if(!r.getClientID()){n.error('FB.login() called before FB.init().');return;}if(h.getAuthResponse()&&!ka.params.scope&&!ka.params.auth_type){n.error('FB.login() called when user is already connected.');ka.cb&&ka.cb({status:r.getLoginStatus(),authResponse:h.getAuthResponse()});return;}var la=ka.cb,ma=ka.id;delete ka.cb;var na=ES('Object','keys',false,ES('Object','assign',false,ka.params.response_type?w(ka.params.response_type.split(',')):{},{token:true,signed_request:true})).join(',');if(ka.params.display==='async'){ES('Object','assign',false,ka.params,{client_id:r.getClientID(),origin:aa(),response_type:na,domain:location.hostname});ka.cb=h.xdResponseWrapper(la,h.getAuthResponse(),'permissions.oauth');}else ES('Object','assign',false,ka.params,{client_id:r.getClientID(),redirect_uri:da(ja.xdHandler(la,ma,'opener',h.getAuthResponse(),'permissions.oauth')),origin:aa(),response_type:na,domain:location.hostname});return ka;}},'auth.logout':{url:'logout.php',transform:function(ka){if(!r.getClientID()){n.error('FB.logout() called before calling FB.init().');}else if(!h.getAuthResponse()){n.error('FB.logout() called without an access token.');}else{ka.params.next=ja.xdHandler(ka.cb,ka.id,'parent',h.getAuthResponse(),'logout');return ka;}}},'login.status':{url:'dialog/oauth',transform:function(ka){var la=ka.cb,ma=ka.id;delete ka.cb;ES('Object','assign',false,ka.params,{client_id:r.getClientID(),redirect_uri:ja.xdHandler(la,ma,'parent',h.getAuthResponse(),'login_status'),origin:aa(),response_type:'token,signed_request,code',domain:location.hostname});return ka;}},pay:{size:{width:555,height:120},connectDisplay:'popup'}},ga={};function ha(ka,la){ga[la]=true;return function(ma){delete ga[la];ka(ma);};}function ia(ka){if(!x('should_force_single_dialog_instance',true))return false;var la=ka.method.toLowerCase();if(la==='pay'&&ka.display==='async')return true;return false;}var ja={Methods:fa,_loadedNodes:{},_defaultCb:{},_resultToken:'\"xxRESULTTOKENxx\"',genericTransform:function(ka){if(ka.params.display=='dialog'||ka.params.display=='iframe')ES('Object','assign',false,ka.params,{display:'iframe',channel:ja._xdChannelHandler(ka.id,'parent.parent')},true);return ka;},checkOauthDisplay:function(ka){var la=ka.scope||ka.perms||r.getScope();if(!la)return ka.display;var ma=la.split(/\\s|,/g);for(var na=0;na<ma.length;na++)if(!s.initSitevars.iframePermissions[ES(ma[na],'trim',true)])return 'popup';return ka.display;},prepareCall:function(ka,la){var ma=ka.method.toLowerCase(),na=ja.Methods.hasOwnProperty(ma)?ES('Object','assign',false,{},ja.Methods[ma]):{},oa=ba(),pa=r.getSecure()||ma!=='auth.status'&&ma!='login.status';ES('Object','assign',false,ka,{app_id:r.getClientID(),locale:r.getLocale(),sdk:'joey',access_token:pa&&r.getAccessToken()||undefined});if(ma==='share'||ma==='share_open_graph')if(ka.iframe_test)na=ES('Object','assign',false,{},ea);ka.display=ja.getDisplayMode(na,ka);if(!na.url)na.url='dialog/'+ma;if((na.url=='dialog/oauth'||na.url=='dialog/permissions.request')&&(ka.display=='iframe'||ka.display=='touch'&&ka.in_iframe))ka.display=ja.checkOauthDisplay(ka);if(ka.display=='popup')delete ka.access_token;if(r.getIsVersioned()&&na.url.substring(0,7)==='dialog/')na.url=ka.version+'/'+na.url;if(ia(ka)){if(ga[ma]){var qa='Dialog \"'+ma+'\" is trying to run more than once.';n.warn(qa);la({error_code:-100,error_message:qa});return;}la=ha(la,ma);}var ra={cb:la,id:oa,size:na.size||ja.getDefaultSize(),url:u.resolve(ka.display=='touch'?'m':'www',pa)+'/'+na.url,params:ka,name:ma,dialog:k.newInstance(oa,ka.display)},sa=na.transform?na.transform:ja.genericTransform;if(sa){ra=sa(ra);if(!ra)return;}if(ka.display==='touch'&&ka.in_iframe)ra.params.parent_height=window.innerHeight;var ta=na.getXdRelation||ja.getXdRelation,ua=ta(ra.params);if(!(ra.id in ja._defaultCb)&&!('next' in ra.params)&&!('redirect_uri' in ra.params))ra.params.next=ja._xdResult(ra.cb,ra.id,ua,true);if(ua==='parent')ES('Object','assign',false,ra.params,{channel_url:ja._xdChannelHandler(oa,'parent.parent')},true);ra=ja.prepareParams(ra);return ra;},prepareParams:function(ka){if(ka.params.display!=='async')delete ka.params.method;ka.params=z(ka.params);var la=p.encode(ka.params);if(!t.nativeApp()&&ja.urlTooLongForIE(ka.url+'?'+la)){ka.post=true;}else if(la)ka.url+='?'+la;return ka;},urlTooLongForIE:function(ka){return t.ie()&&t.ie()<=8&&ka.length>2048;},getDisplayMode:function(ka,la){if(la.display==='hidden'||la.display==='none')return la.display;var ma=r.isEnvironment(r.ENVIRONMENTS.CANVAS)||r.isEnvironment(r.ENVIRONMENTS.PAGETAB);if(ma&&!la.display)return 'async';if(t.mobile()&&la.method!=='feed'||la.display==='touch')return 'touch';if(la.display=='iframe'||la.display=='dialog')if(!ja.canIframe(la)){n.error('\"dialog\" mode can only be used when the user is connected.');return 'popup';}if(ka.connectDisplay&&!ma)return ka.connectDisplay;return la.display||(ja.canIframe(la)?'dialog':'popup');},canIframe:function(ka){if(r.getAccessToken())return true;if(t.mobile()&&r.getLoggedIntoFacebook())return !!ka.iframe_test;return false;},getXdRelation:function(ka){var la=ka.display;if(la==='popup'||la==='touch')return 'opener';if(la==='dialog'||la==='iframe'||la==='hidden'||la==='none')return 'parent';if(la==='async')return 'parent.frames['+window.name+']';},popup:function(ka){var la=typeof window.screenX!='undefined'?window.screenX:window.screenLeft,ma=typeof window.screenY!='undefined'?window.screenY:window.screenTop,na=typeof window.outerWidth!='undefined'?window.outerWidth:document.documentElement.clientWidth,oa=typeof window.outerHeight!='undefined'?window.outerHeight:document.documentElement.clientHeight-22,pa=t.mobile()?null:ka.size.width,qa=t.mobile()?null:ka.size.height,ra=la<0?window.screen.width+la:la,sa=parseInt(ra+(na-pa)/2,10),ta=parseInt(ma+(oa-qa)/2.5,10),ua=[];if(pa!==null)ua.push('width='+pa);if(qa!==null)ua.push('height='+qa);ua.push('left='+sa);ua.push('top='+ta);ua.push('scrollbars=1');if(ka.name=='permissions.request'||ka.name=='permissions.oauth')ua.push('location=1,toolbar=0');ua=ua.join(',');var va;if(ka.post){va=window.open('about:blank',ka.id,ua);if(va){ja.setLoadedNode(ka,va,'popup');i.submitToTarget({url:ka.url,target:ka.id,params:ka.params});}}else{va=window.open(ka.url,ka.id,ua);if(va)ja.setLoadedNode(ka,va,'popup');}if(!va)return;if(ka.id in ja._defaultCb)ja._popupMonitor();},setLoadedNode:function(ka,la,ma){if(ma==='iframe')la.fbCallID=ka.id;la={node:la,type:ma,fbCallID:ka.id};ja._loadedNodes[ka.id]=la;},getLoadedNode:function(ka){var la=typeof ka=='object'?ka.id:ka,ma=ja._loadedNodes[la];return ma?ma.node:null;},hidden:function(ka){ka.className='FB_UI_Hidden';ka.root=i.appendHidden('');ja._insertIframe(ka);},iframe:function(ka){ka.className='FB_UI_Dialog';if(ka.params.iframe_test){k.setForceTabletStyle(true);k.setCloseOnOverlayTap(true);}var la=function(){var ma=ES('JSON','stringify',false,{error_code:4201,error_message:y._(\"User canceled the Dialog flow\")});ja._triggerDefault(ka.id,ma);};ka.root=k.create({onClose:la,closeIcon:ka.closeIcon===undefined?true:ka.closeIcon,classes:k.isTabletStyle()?'centered':''});if(!ka.hideLoader)k.showLoader(la,ka.size.width);j.addCss(ka.root,'fb_dialog_iframe');ja._insertIframe(ka);},touch:function(ka){if(ka.params&&ka.params.in_iframe){if(ka.ui_created){k.showLoader(function(){ja._triggerDefault(ka.id,null);},0);}else ja.iframe(ka);}else if(t.nativeApp()&&!ka.ui_created){ka.frame=ka.id;o.onready(function(){ja.setLoadedNode(ka,o.open(ka.url+'#cb='+ka.frameName),'native');});ja._popupMonitor();}else if(!ka.ui_created)ja.popup(ka);},async:function(ka){ka.params.redirect_uri=location.protocol+'//'+location.host+location.pathname;delete ka.params.access_token;q.remote.showDialog(ka.params,function(la){var ma=la.result;if(ma&&ma.e2e){var na=k.get(ka.id);na.trackEvents(ma.e2e);na.trackEvent('close');delete ma.e2e;}ka.cb(ma);});},getDefaultSize:function(){return k.getDefaultSize();},_insertIframe:function(ka){ja._loadedNodes[ka.id]=false;var la=function(ma){if(ka.id in ja._loadedNodes)ja.setLoadedNode(ka,ma,'iframe');};if(ka.post){ca({url:'about:blank',root:ka.root,className:ka.className,width:ka.size.width,height:ka.size.height,id:ka.id,onInsert:la,onload:function(ma){i.submitToTarget({url:ka.url,target:ma.name,params:ka.params});}});}else ca({url:ka.url,root:ka.root,className:ka.className,width:ka.size.width,height:ka.size.height,id:ka.id,name:ka.frameName,onInsert:la});},_handleResizeMessage:function(ka,la){var ma=ja.getLoadedNode(ka);if(!ma)return;if(la.height)ma.style.height=la.height+'px';if(la.width)ma.style.width=la.width+'px';v.inform('resize.ack',la||{},'parent.frames['+ma.name+']');if(!k.isActive(ma)){k.show(ma);}else k._centerActive();},_triggerDefault:function(ka,la){var ma={frame:ka};if(la)ma.result=la;ja._xdRecv(ma,ja._defaultCb[ka]||function(){});},_popupMonitor:function(){var ka;for(var la in ja._loadedNodes)if(ja._loadedNodes.hasOwnProperty(la)&&la in ja._defaultCb){var ma=ja._loadedNodes[la];if(ma.type!='popup'&&ma.type!='native')continue;var na=ma.node;try{if(na.closed){ja._triggerDefault(la,null);}else ka=true;}catch(oa){}}if(ka&&!ja._popupInterval){ja._popupInterval=setInterval(ja._popupMonitor,100);}else if(!ka&&ja._popupInterval){clearInterval(ja._popupInterval);ja._popupInterval=null;}},_xdChannelHandler:function(ka,la){return v.handler(function(ma){var na=ja.getLoadedNode(ka);if(!na)return;if(ma.type=='resize'){ja._handleResizeMessage(ka,ma);}else if(ma.type=='hide'){k.hide(na);}else if(ma.type=='rendered'){var oa=k._findRoot(na);k.show(oa);}else if(ma.type=='fireevent')l.fire(ma.event);},la,true,null);},_xdNextHandler:function(ka,la,ma,na){if(na)ja._defaultCb[la]=ka;return v.handler(function(oa){ja._xdRecv(oa,ka);},ma)+'&frame='+la;},_xdRecv:function(ka,la){var ma=ja.getLoadedNode(ka.frame);if(ma)if(ma.close){try{ma.close();if(/iPhone.*Version\\/(5|6)/.test(navigator.userAgent)&&RegExp.$1!=='5')window.focus();ja._popupCount--;}catch(na){}}else if(j.containsCss(ma,'FB_UI_Hidden')){setTimeout(function(){ma.parentNode.parentNode.removeChild(ma.parentNode);},3000);}else if(j.containsCss(ma,'FB_UI_Dialog'))k.remove(ma);delete ja._loadedNodes[ka.frame];delete ja._defaultCb[ka.frame];if(ka.e2e){var oa=k.get(ka.frame);oa.trackEvents(ka.e2e);oa.trackEvent('close');delete ka.e2e;}la(ka);},_xdResult:function(ka,la,ma,na){return (ja._xdNextHandler(function(oa){ka&&ka(oa.result&&oa.result!=ja._resultToken&&ES('JSON','parse',false,oa.result));},la,ma,na)+'&result='+encodeURIComponent(ja._resultToken));},xdHandler:function(ka,la,ma,na,oa){return ja._xdNextHandler(h.xdResponseWrapper(ka,na,oa),la,ma,true);}};q.stub('showDialog');f.exports=ja;},null);\n    __d('sdk.ui',['Assert','sdk.Impressions','Log','sdk.PlatformVersioning','sdk.Runtime','sdk.UIServer','sdk.feature'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n){if(c.__markCompiled)c.__markCompiled();function o(p,q){h.isObject(p);h.maybeFunction(q);if(l.getIsVersioned()){k.assertVersionIsSet();if(p.version){k.assertValidVersion(p.version);}else p.version=l.getVersion();}p=ES('Object','assign',false,{},p);if(!p.method){j.error('\"method\" is a required parameter for FB.ui().');return null;}if(p.method=='pay.prompt')p.method='pay';var r=p.method;if(p.redirect_uri){j.warn('When using FB.ui, you should not specify a redirect_uri.');delete p.redirect_uri;}if((r=='permissions.request'||r=='permissions.oauth')&&(p.display=='iframe'||p.display=='dialog'))p.display=m.checkOauthDisplay(p);var s=n('e2e_tracking',true);if(s)p.e2e={};var t=m.prepareCall(p,q||function(){});if(!t)return null;var u=t.params.display;if(u==='dialog'){u='iframe';}else if(u==='none')u='hidden';var v=m[u];if(!v){j.error('\"display\" must be one of \"popup\", '+'\"dialog\", \"iframe\", \"touch\", \"async\", \"hidden\", or \"none\"');return null;}if(s)t.dialog.subscribe('e2e:end',function(w){w.method=r;w.display=u;j.debug('e2e: %s',ES('JSON','stringify',false,w));i.log(114,{payload:w});});v(t);return t.dialog;}f.exports=o;},null);\n    __d('legacy:fb.auth',['sdk.Auth','sdk.Cookie','sdk.Event','FB','Log','sdk.Runtime','sdk.SignedRequest','sdk.ui'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o){if(c.__markCompiled)c.__markCompiled();k.provide('',{getLoginStatus:function(){return h.getLoginStatus.apply(h,arguments);},getAuthResponse:function(){return h.getAuthResponse();},getAccessToken:function(){return m.getAccessToken()||null;},getUserID:function(){return m.getUserID()||m.getCookieUserID();},login:function(p,q){if(q&&q.perms&&!q.scope){q.scope=q.perms;delete q.perms;l.warn('OAuth2 specification states that \\'perms\\' '+'should now be called \\'scope\\'.  Please update.');}var r=m.isEnvironment(m.ENVIRONMENTS.CANVAS)||m.isEnvironment(m.ENVIRONMENTS.PAGETAB);o(babelHelpers._extends({method:'permissions.oauth',display:r?'async':'popup',domain:location.hostname},q||{}),p);},logout:function(p){o({method:'auth.logout',display:'hidden'},p);}});h.subscribe('logout',ES(j.fire,'bind',true,j,'auth.logout'));h.subscribe('login',ES(j.fire,'bind',true,j,'auth.login'));h.subscribe('authresponse.change',ES(j.fire,'bind',true,j,'auth.authResponseChange'));h.subscribe('status.change',ES(j.fire,'bind',true,j,'auth.statusChange'));j.subscribe('init:post',function(p){if(p.status)h.getLoginStatus();if(m.getClientID())if(p.authResponse){h.setAuthResponse(p.authResponse,'connected');}else if(m.getUseCookie()){var q=i.loadSignedRequest(),r;if(q){try{r=n.parse(q);}catch(s){i.clearSignedRequestCookie();}if(r&&r.user_id)m.setCookieUserID(r.user_id);}i.loadMeta();}});},3);\n    __d('sdk.Canvas.IframeHandling',['DOMWrapper','sdk.RPC'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();var j=null,k;function l(){var p=h.getWindow().document,q=p.body,r=p.documentElement,s=Math.max(q.offsetTop,0),t=Math.max(r.offsetTop,0),u=q.scrollHeight+s,v=q.offsetHeight+s,w=r.scrollHeight+t,x=r.offsetHeight+t;return Math.max(u,v,w,x);}function m(p){if(typeof p!='object')p={};var q=0,r=0;if(!p.height){p.height=l();q=16;r=4;}if(!p.frame)p.frame=window.name||'iframe_canvas';if(k){var s=k.height,t=p.height-s;if(t<=r&&t>=-q)return false;}k=p;i.remote.setSize(p);return true;}function n(p,q){if(q===undefined&&typeof p==='number'){q=p;p=true;}if(p||p===undefined){if(j===null)j=setInterval(function(){m();},q||100);m();}else if(j!==null){clearInterval(j);j=null;}}i.stub('setSize');var o={setSize:m,setAutoGrow:n};f.exports=o;},null);\n    __d('sdk.Canvas.Navigation',['sdk.RPC'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();function i(k){h.local.navigate=function(l){k({path:l});};h.remote.setNavigationEnabled(true);}h.stub('setNavigationEnabled');var j={setUrlHandler:i};f.exports=j;},null);\n    __d('sdk.Canvas.Plugin',['Log','sdk.RPC','sdk.Runtime','sdk.UA','sdk.api'],function a(b,c,d,e,f,g,h,i,j,k,l){if(c.__markCompiled)c.__markCompiled();var m='CLSID:D27CDB6E-AE6D-11CF-96B8-444553540000',n='CLSID:444785F1-DE89-4295-863A-D46C3A781394',o=null,p=k.osx()&&k.osx.getVersionParts(),q=!(p&&p[0]>10&&p[1]>10&&(k.chrome()>=31||k.webkit()>=537.71||k.firefox()>=25));function r(ba){ba._hideunity_savedstyle={};ba._hideunity_savedstyle.left=ba.style.left;ba._hideunity_savedstyle.position=ba.style.position;ba._hideunity_savedstyle.width=ba.style.width;ba._hideunity_savedstyle.height=ba.style.height;ba.style.left='-10000px';ba.style.position='absolute';ba.style.width='1px';ba.style.height='1px';}function s(ba){if(ba._hideunity_savedstyle){ba.style.left=ba._hideunity_savedstyle.left;ba.style.position=ba._hideunity_savedstyle.position;ba.style.width=ba._hideunity_savedstyle.width;ba.style.height=ba._hideunity_savedstyle.height;}}function t(ba){ba._old_visibility=ba.style.visibility;ba.style.visibility='hidden';}function u(ba){ba.style.visibility=ba._old_visibility||'';delete ba._old_visibility;}function v(ba){var ca=ba.type?ba.type.toLowerCase():null,da=ca==='application/x-shockwave-flash'||ba.classid&&ba.classid.toUpperCase()==m;if(!da)return false;var ea=/opaque|transparent/i;if(ea.test(ba.getAttribute('wmode')))return false;for(var fa=0;fa<ba.childNodes.length;fa++){var ga=ba.childNodes[fa];if(/param/i.test(ga.nodeName)&&/wmode/i.test(ga.name)&&ea.test(ga.value))return false;}return true;}function w(ba){var ca=ba.type?ba.type.toLowerCase():null;return ca==='application/vnd.unity'||ba.classid&&ba.classid.toUpperCase()==n;}function x(ba){var ca=ES('Array','from',false,window.document.getElementsByTagName('object'));ca=ca.concat(ES('Array','from',false,window.document.getElementsByTagName('embed')));var da=false,ea=false;ES(ca,'forEach',true,function(ga){var ha=v(ga),ia=q&&w(ga);if(!ha&&!ia)return;da=da||ha;ea=ea||ia;var ja=function(){if(ba.state==='opened'){if(ha){t(ga);}else r(ga);}else if(ha){u(ga);}else s(ga);};if(o){h.info('Calling developer specified callback');var ka={state:ba.state,elem:ga};o(ka);setTimeout(ja,200);}else ja();});if(Math.random()<=1/1000){var fa={unity:ea,flash:da};l(j.getClientID()+'/occludespopups','post',fa);}}i.local.hidePluginObjects=function(){h.info('hidePluginObjects called');x({state:'opened'});};i.local.showPluginObjects=function(){h.info('showPluginObjects called');x({state:'closed'});};i.local.showFlashObjects=i.local.showPluginObjects;i.local.hideFlashObjects=i.local.hidePluginObjects;function y(){t();r();}function z(){u();s();}var aa={_setHidePluginCallback:function(ba){o=ba;},hidePluginElement:y,showPluginElement:z};f.exports=aa;},null);\n    __d('sdk.Canvas.Tti',['sdk.RPC','sdk.Runtime'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();function j(o,p){var q={appId:i.getClientID(),time:ES('Date','now',false),name:p},r=[q];if(o)r.push(function(s){o(s.result);});h.remote.logTtiMessage.apply(null,r);}function k(){j(null,'StartIframeAppTtiTimer');}function l(o){j(o,'StopIframeAppTtiTimer');}function m(o){j(o,'RecordIframeAppTti');}h.stub('logTtiMessage');var n={setDoneLoading:m,startTimer:k,stopTimer:l};f.exports=n;},null);\n    __d('legacy:fb.canvas',['Assert','sdk.Canvas.Environment','sdk.Event','FB','sdk.Canvas.IframeHandling','sdk.Canvas.Navigation','sdk.Canvas.Plugin','sdk.RPC','sdk.Runtime','sdk.Canvas.Tti'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){if(c.__markCompiled)c.__markCompiled();k.provide('Canvas',{setSize:function(r){h.maybeObject(r,'Invalid argument');return l.setSize.apply(null,arguments);},setAutoGrow:function(){return l.setAutoGrow.apply(null,arguments);},getPageInfo:function(r){h.isFunction(r,'Invalid argument');return i.getPageInfo.apply(null,arguments);},scrollTo:function(r,s){h.maybeNumber(r,'Invalid argument');h.maybeNumber(s,'Invalid argument');return i.scrollTo.apply(null,arguments);},setDoneLoading:function(r){h.maybeFunction(r,'Invalid argument');return q.setDoneLoading.apply(null,arguments);},startTimer:function(){return q.startTimer.apply(null,arguments);},stopTimer:function(r){h.maybeFunction(r,'Invalid argument');return q.stopTimer.apply(null,arguments);},getHash:function(r){h.isFunction(r,'Invalid argument');return m.getHash.apply(null,arguments);},setHash:function(r){h.isString(r,'Invalid argument');return m.setHash.apply(null,arguments);},setUrlHandler:function(r){h.isFunction(r,'Invalid argument');return m.setUrlHandler.apply(null,arguments);}});o.local.fireEvent=ES(j.fire,'bind',true,j);j.subscribe('init:post',function(r){if(p.isEnvironment(p.ENVIRONMENTS.CANVAS)){h.isTrue(!r.hideFlashCallback||!r.hidePluginCallback,'cannot specify deprecated hideFlashCallback and new hidePluginCallback');n._setHidePluginCallback(r.hidePluginCallback||r.hideFlashCallback);}});},3);\n    __d('sdk.Canvas.Prefetcher',['JSSDKCanvasPrefetcherConfig','sdk.Runtime','sdk.api'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k={AUTOMATIC:0,MANUAL:1},l=h.sampleRate,m=h.blacklist,n=k.AUTOMATIC,o=[];function p(){var u={object:'data',link:'href',script:'src'};if(n==k.AUTOMATIC)ES(ES('Object','keys',false,u),'forEach',true,function(v){var w=u[v];ES(ES('Array','from',false,document.getElementsByTagName(v)),'forEach',true,function(x){if(x[w])o.push(x[w]);});});if(o.length===0)return;j(i.getClientID()+'/staticresources','post',{urls:ES('JSON','stringify',false,o),is_https:location.protocol==='https:'});o=[];}function q(){if(!i.isEnvironment(i.ENVIRONMENTS.CANVAS)||!i.getClientID()||!l)return;if(Math.random()>1/l||m=='*'||~ES(m,'indexOf',true,i.getClientID()))return;setTimeout(p,30000);}function r(u){n=u;}function s(u){o.push(u);}var t={COLLECT_AUTOMATIC:k.AUTOMATIC,COLLECT_MANUAL:k.MANUAL,addStaticResource:s,setCollectionMode:r,_maybeSample:q};f.exports=t;},null);\n    __d('legacy:fb.canvas.prefetcher',['FB','sdk.Canvas.Prefetcher','sdk.Event','sdk.Runtime'],function a(b,c,d,e,f,g,h,i,j,k){if(c.__markCompiled)c.__markCompiled();h.provide('Canvas.Prefetcher',i);j.subscribe('init:post',function(l){if(k.isEnvironment(k.ENVIRONMENTS.CANVAS))i._maybeSample();});},3);\n    __d('legacy:fb.canvas.presence',['sdk.RPC','sdk.Event'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();i.subscribe(i.SUBSCRIBE,j);i.subscribe(i.UNSUBSCRIBE,k);h.stub('useFriendsOnline');function j(l,m){if(l!='canvas.friendsOnlineUpdated')return;if(m.length===1)h.remote.useFriendsOnline(true);}function k(l,m){if(l!='canvas.friendsOnlineUpdated')return;if(m.length===0)h.remote.useFriendsOnline(false);}},3);\n    __d('legacy:fb.canvas.syncrequests',['sdk.RPC','sdk.Event'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();h.stub('initPendingSyncRequests');function j(k,l){if(k!='canvas.syncRequestUpdated')return;h.remote.initPendingSyncRequests();i.unsubscribe(i.SUBSCRIBE,j);}i.subscribe(i.SUBSCRIBE,j);},3);\n    __d('legacy:fb.event',['FB','sdk.Event','sdk.Runtime','sdk.Scribe','sdk.feature'],function a(b,c,d,e,f,g,h,i,j,k,l){if(c.__markCompiled)c.__markCompiled();var m=[],n=null,o=l('event_subscriptions_log',false);h.provide('Event',{subscribe:function(p,q){if(o){m.push(p);if(!n)n=setTimeout(function(){k.log('jssdk_error',{appId:j.getClientID(),error:'EVENT_SUBSCRIPTIONS_LOG',extra:{line:0,name:'EVENT_SUBSCRIPTIONS_LOG',script:'N/A',stack:'N/A',message:m.sort().join(',')}});m.length=0;n=null;},o);}return i.subscribe(p,q);},unsubscribe:ES(i.unsubscribe,'bind',true,i)});},3);\n    __d('legacy:fb.frictionless',['FB','sdk.Frictionless'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();h.provide('Frictionless',i);},3);\n    __d('sdk.init',['sdk.Cookie','sdk.ErrorHandling','sdk.Event','sdk.Impressions','Log','ManagedError','sdk.PlatformVersioning','QueryString','sdk.Runtime','sdk.URI','sdk.feature'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r){if(c.__markCompiled)c.__markCompiled();function s(u){var v=typeof u=='number'&&u>0||typeof u=='string'&&/^[0-9a-f]{21,}$|^[0-9]{1,21}$/.test(u);if(v)return u.toString();l.warn('Invalid App Id: Must be a number or numeric string representing '+'the application id.');return null;}function t(u){if(p.getInitialized())l.warn('FB.init has already been called - this could indicate a problem');if(p.getIsVersioned()){if(Object.prototype.toString.call(u)!=='[object Object]')throw new m('Invalid argument');if(u.authResponse)l.warn('Setting authResponse is not supported');if(!u.version)u.version=new q(location.href).getQueryData().sdk_version;n.assertValidVersion(u.version);p.setVersion(u.version);}else{if(/number|string/.test(typeof u)){l.warn('FB.init called with invalid parameters');u={apiKey:u};}u=ES('Object','assign',false,{status:true},u||{});}var v=s(u.appId||u.apiKey);if(v!==null)p.setClientID(v);if('scope' in u)p.setScope(u.scope);if(u.cookie){p.setUseCookie(true);if(typeof u.cookie==='string')h.setDomain(u.cookie);}if(u.kidDirectedSite)p.setKidDirectedSite(true);p.setInitialized(true);if(r('js_sdk_impression_on_load',true))k.log(115,{});j.fire('init:post',u);}setTimeout(function(){var u=/(connect\\.facebook\\.net|\\.facebook\\.com\\/assets.php).*?#(.*)/;ES(ES('Array','from',false,fb_fif_window.document.getElementsByTagName('script')),'forEach',true,function(v){if(v.src){var w=u.exec(v.src);if(w){var x=o.decode(w[2]);for(var y in x)if(x.hasOwnProperty(y)){var z=x[y];if(z=='0')x[y]=0;}t(x);}}});if(window.fbAsyncInit&&!window.fbAsyncInit.hasRun){window.fbAsyncInit.hasRun=true;i.unguard(window.fbAsyncInit)();}},0);f.exports=t;},null);\n    __d('legacy:fb.init',['FB','sdk.init'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();h.provide('',{init:i});},3);\n    __d('legacy:fb.ui',['FB','sdk.ui'],function a(b,c,d,e,f,g,h,i){if(c.__markCompiled)c.__markCompiled();h.provide('',{ui:i});},3);\n    __d('legacy:fb.versioned-sdk',['sdk.Runtime'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();h.setIsVersioned(true);},3);\n    __d(\"runOnce\",[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(i){var j,k;return function(){if(!j){j=true;k=i();}return k;};}f.exports=h;},null);\n    __d('XFBML',['Assert','sdk.DOM','Log','ObservableMixin','sdk.UA','runOnce'],function a(b,c,d,e,f,g,h,i,j,k,l,m){if(c.__markCompiled)c.__markCompiled();var n={},o={},p=0,q=new k();function r(y,z){return ES(y[z]+'','trim',true);}function s(y){return y.scopeName?y.scopeName+':'+y.nodeName:'';}function t(y){return n[r(y,'nodeName').toLowerCase()]||n[s(y).toLowerCase()];}function u(y){var z=ES(r(y,'className').split(/\\s+/),'filter',true,function(aa){return o.hasOwnProperty(aa);});if(z.length===0)return undefined;if(y.getAttribute('fb-xfbml-state')||!y.childNodes||y.childNodes.length===0||y.childNodes.length===1&&y.childNodes[0].nodeType===3||y.children.length===1&&r(y.children[0],'className')==='fb-xfbml-parse-ignore')return o[z[0]];}function v(y){var z={};ES(ES('Array','from',false,y.attributes),'forEach',true,function(aa){z[r(aa,'name')]=r(aa,'value');});return z;}function w(y,z,aa){var ba=document.createElement('div');i.addCss(y,z+'-'+aa);ES(ES('Array','from',false,y.childNodes),'forEach',true,function(ca){ba.appendChild(ca);});ES(ES('Array','from',false,y.attributes),'forEach',true,function(ca){ba.setAttribute(ca.name,ca.value);});y.parentNode.replaceChild(ba,y);return ba;}function x(y,z,aa){h.isTrue(y&&y.nodeType&&y.nodeType===1&&!!y.getElementsByTagName,'Invalid DOM node passed to FB.XFBML.parse()');h.isFunction(z,'Invalid callback passed to FB.XFBML.parse()');var ba=++p;j.info('XFBML Parsing Start %s',ba);var ca=1,da=0,ea=function(){ca--;if(ca===0){j.info('XFBML Parsing Finish %s, %s tags found',ba,da);z();q.inform('render',ba,da);}h.isTrue(ca>=0,'onrender() has been called too many times');};ES(ES('Array','from',false,y.getElementsByTagName('*')),'forEach',true,function(ga){if(!aa&&ga.getAttribute('fb-xfbml-state'))return;if(ga.nodeType!==1)return;var ha=t(ga)||u(ga);if(!ha)return;if(l.ie()<9&&ga.scopeName)ga=w(ga,ha.xmlns,ha.localName);ca++;da++;var ia=new ha.ctor(ga,ha.xmlns,ha.localName,v(ga));ia.subscribe('render',m(function(){ga.setAttribute('fb-xfbml-state','rendered');ea();}));var ja=function(){if(ga.getAttribute('fb-xfbml-state')=='parsed'){q.subscribe('render.queue',ja);}else{ga.setAttribute('fb-xfbml-state','parsed');ia.process();}};ja();});q.inform('parse',ba,da);var fa=30000;setTimeout(function(){if(ca>0)j.warn('%s tags failed to render in %s ms',ca,fa);},fa);ea();}q.subscribe('render',function(){var y=q.getSubscribers('render.queue');q.clearSubscribers('render.queue');ES(y,'forEach',true,function(z){z();});});ES('Object','assign',false,q,{registerTag:function(y){var z=y.xmlns+':'+y.localName;h.isUndefined(n[z],z+' already registered');n[z]=y;o[y.xmlns+'-'+y.localName]=y;},parse:function(y,z){x(y||document.body,z||function(){},true);},parseNew:function(){x(document.body,function(){},false);}});f.exports=q;},null);\n    __d('PluginPipe',['sdk.Content','sdk.feature','guid','insertIframe','Miny','ObservableMixin','JSSDKPluginPipeConfig','sdk.Runtime','sdk.UA','UrlMap','XFBML'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r){if(c.__markCompiled)c.__markCompiled();var s=new m(),t=n.threshold,u=[];function v(){return !!(i('plugin_pipe',false)&&o.getSecure()!==undefined&&(p.chrome()||p.firefox())&&n.enabledApps[o.getClientID()]);}function w(){var y=u;u=[];if(y.length<=t){ES(y,'forEach',true,function(ba){k(ba.config);});return;}var z=y.length+1;function aa(){z--;if(z===0)x(y);}ES(y,'forEach',true,function(ba){var ca={};for(var da in ba.config)ca[da]=ba.config[da];ca.url=q.resolve('www',o.getSecure())+'/plugins/plugin_pipe_shell.php';ca.onload=aa;k(ca);});aa();}r.subscribe('parse',w);function x(y){var z=document.createElement('span');h.appendHidden(z);var aa={};ES(y,'forEach',true,function(fa){aa[fa.config.name]={plugin:fa.tag,params:fa.params};});var ba=ES('JSON','stringify',false,aa),ca=l.encode(ba);ES(y,'forEach',true,function(fa){var ga=document.getElementsByName(fa.config.name)[0];ga.onload=fa.config.onload;});var da=q.resolve('www',o.getSecure())+'/plugins/pipe.php',ea=j();k({url:'about:blank',root:z,name:ea,className:'fb_hidden fb_invisible',onload:function(){h.submitToTarget({url:da,target:ea,params:{plugins:ca.length<ba.length?ca:ba}});}});}ES('Object','assign',false,s,{add:function(y){var z=v();z&&u.push({config:y._config,tag:y._tag,params:y._params});return z;}});f.exports=s;},null);\n    __d('IframePlugin',['sdk.Auth','sdk.DOM','sdk.Event','Log','ObservableMixin','sdk.PlatformVersioning','PluginPipe','QueryString','sdk.Runtime','Type','sdk.UA','sdk.URI','UrlMap','sdk.XD','sdk.createIframe','sdk.feature','guid','resolveURI'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y){if(c.__markCompiled)c.__markCompiled();var z={skin:'string',font:'string',width:'px',height:'px',ref:'string',color_scheme:'string'};function aa(ia,ja,ka){if(ja||ja===0)if(ja==='100%'){ia.style.width='100%';}else ia.style.width=ja+'px';if(ka||ka===0)ia.style.height=ka+'px';}function ba(ia){return function(ja){var ka={width:ja.width,height:ja.height,pluginID:ia};j.fire('xfbml.resize',ka);};}var ca={string:function(ia){return ia;},bool:function(ia){return ia?/^(?:true|1|yes|on)$/i.test(ia):undefined;},url:function(ia){return y(ia);},url_maybe:function(ia){return ia?y(ia):ia;},hostname:function(ia){return ia||window.location.hostname;},px:function(ia){return (/^(\\d+)(?:px)?$/.test(ia)?parseInt(RegExp.$1,10):undefined);},text:function(ia){return ia;}};function da(ia,ja){var ka=ia[ja]||ia[ja.replace(/_/g,'-')]||ia[ja.replace(/_/g,'')]||ia['data-'+ja]||ia['data-'+ja.replace(/_/g,'-')]||ia['data-'+ja.replace(/_/g,'')]||undefined;return ka;}function ea(ia,ja,ka,la){ES(ES('Object','keys',false,ia),'forEach',true,function(ma){if(ia[ma]=='text'&&!ka[ma]){ka[ma]=ja.textContent||ja.innerText||'';ja.setAttribute(ma,ka[ma]);}la[ma]=ca[ia[ma]](da(ka,ma));});}function fa(ia){if(ia==='100%')return '100%';return ia||ia==='0'||ia===0?parseInt(ia,10):undefined;}function ga(ia){if(ia)aa(ia,0,0);}var ha=q.extend({constructor:function(ia,ja,ka,la){this.parent();ka=ka.replace(/-/g,'_');var ma=da(la,'plugin_id');this.subscribe('xd.resize',ba(ma));this.subscribe('xd.resize.flow',ba(ma));this.subscribe('xd.resize.flow',ES(function(sa){ES('Object','assign',false,this._iframeOptions.root.style,{verticalAlign:'bottom',overflow:''});aa(this._iframeOptions.root,fa(sa.width),fa(sa.height));this.updateLift();clearTimeout(this._timeoutID);},'bind',true,this));this.subscribe('xd.resize',ES(function(sa){ES('Object','assign',false,this._iframeOptions.root.style,{verticalAlign:'bottom',overflow:''});aa(this._iframeOptions.root,fa(sa.width),fa(sa.height));aa(this._iframe,fa(sa.width),fa(sa.height));this._isIframeResized=true;this.updateLift();clearTimeout(this._timeoutID);},'bind',true,this));this.subscribe('xd.resize.iframe',ES(function(sa){if(sa.reposition==='true'&&w('reposition_iframe',false))this.reposition(fa(sa.width));aa(this._iframe,fa(sa.width),fa(sa.height));this._isIframeResized=true;this.updateLift();clearTimeout(this._timeoutID);},'bind',true,this));this.subscribe('xd.sdk_event',function(sa){var ta=ES('JSON','parse',false,sa.data);ta.pluginID=ma;j.fire(sa.event,ta,ia);});var na=p.getSecure()||window.location.protocol=='https:',oa=t.resolve('www',na)+'/plugins/'+ka+'.php?',pa={};ea(this.getParams(),ia,la,pa);ea(z,ia,la,pa);ES('Object','assign',false,pa,{app_id:p.getClientID(),locale:p.getLocale(),sdk:'joey',kid_directed_site:p.getKidDirectedSite(),channel:u.handler(ES(function(sa){return this.inform('xd.'+sa.type,sa);},'bind',true,this),'parent.parent',true)});pa.container_width=ia.offsetWidth;i.addCss(ia,'fb_iframe_widget');var qa=x();this.subscribe('xd.verify',function(sa){u.sendToFacebook(qa,{method:'xd/verify',params:ES('JSON','stringify',false,sa.token)});});this.subscribe('xd.refreshLoginStatus',ES(h.getLoginStatus,'bind',true,h,ES(this.inform,'bind',true,this,'login.status'),true));var ra=document.createElement('span');ES('Object','assign',false,ra.style,{verticalAlign:'top',width:'0px',height:'0px',overflow:'hidden'});this._element=ia;this._ns=ja;this._tag=ka;this._params=pa;this._config=this.getConfig();this._iframeOptions={root:ra,url:oa+o.encode(pa),name:qa,width:this._config.mobile_fullsize&&r.mobile()?void 0:pa.width||1000,height:pa.height||1000,style:{border:'none',visibility:'hidden'},title:this._ns+':'+this._tag+' Facebook Social Plugin',onload:ES(function(){return this.inform('render');},'bind',true,this),onerror:ES(function(){return ga(this._iframe);},'bind',true,this)};if(this.isFluid()){i.addCss(this._element,'fb_iframe_widget_fluid_desktop');if(!pa.width&&this._config.full_width){this._element.style.width='100%';this._iframeOptions.root.style.width='100%';this._iframeOptions.style.width='100%';this._params.container_width=this._element.offsetWidth;this._iframeOptions.url=oa+o.encode(this._params);}}},process:function(){if(p.getIsVersioned()){m.assertVersionIsSet();var ia=new s(this._iframeOptions.url);this._iframeOptions.url=ia.setPath('/'+p.getVersion()+ia.getPath()).toString();}var ja=ES('Object','assign',false,{},this._params);delete ja.channel;var ka=o.encode(ja);if(this._element.getAttribute('fb-iframe-plugin-query')==ka){k.info('Skipping render: %s:%s %s',this._ns,this._tag,ka);this.inform('render');return;}this._element.setAttribute('fb-iframe-plugin-query',ka);this.subscribe('render',ES(function(){this._iframe.style.visibility='visible';if(!this._isIframeResized)ga(this._iframe);},'bind',true,this));while(this._element.firstChild)this._element.removeChild(this._element.firstChild);this._element.appendChild(this._iframeOptions.root);var la=r.mobile()?120:45;this._timeoutID=setTimeout(ES(function(){ga(this._iframe);k.warn('%s:%s failed to resize in %ss',this._ns,this._tag,la);},'bind',true,this),la*1000);if(!n.add(this))this._iframe=v(this._iframeOptions);if(r.mobile()){i.addCss(this._element,'fb_iframe_widget_fluid');if(!this._iframeOptions.width){ES('Object','assign',false,this._element.style,{display:'block',width:'100%',height:'auto'});ES('Object','assign',false,this._iframeOptions.root.style,{width:'100%',height:'auto'});var ma={height:'auto',position:'static',width:'100%'};if(r.iphone()||r.ipad())ES('Object','assign',false,ma,{width:'220px','min-width':'100%'});ES('Object','assign',false,this._iframe.style,ma);}}},getConfig:function(){return {};},isFluid:function(){var ia=this.getConfig();return ia.fluid;},reposition:function(ia){var ja=i.getPosition(this._iframe).x,ka=i.getViewportInfo().width,la=parseInt(i.getStyle(this._iframe,'width'),10),ma={};if(ja+ia>ka&&ja>ia){this._iframe.style.left=parseInt(i.getStyle(this._iframe,'width'),10)-ia+'px';this._isRepositioned=true;ma.type='reposition';}else if(this._isRepositioned&&la-ia!==0){this._iframe.style.left='0px';this._isRepositioned=false;ma.type='restore';}else return;u.sendToFacebook(this._iframe.name,{method:'xd/reposition',params:ES('JSON','stringify',false,ma)});},updateLift:function(){var ia=this._iframe.style.width===this._iframeOptions.root.style.width&&this._iframe.style.height===this._iframeOptions.root.style.height;i[ia?'removeCss':'addCss'](this._iframe,'fb_iframe_widget_lift');}},l);ha.getVal=da;ha.withParams=function(ia,ja){return ha.extend({getParams:function(){return ia;},getConfig:function(){return ja?ja:{};}});};f.exports=ha;},null);\n    __d('PluginConfig',['sdk.feature'],function a(b,c,d,e,f,g,h){if(c.__markCompiled)c.__markCompiled();var i={messengerpreconfirmation:{mobile_fullsize:true},messengeraccountconfirmation:{mobile_fullsize:true},messengerbusinesslink:{mobile_fullsize:true},messengertoggle:{mobile_fullsize:true},messengermessageus:{mobile_fullsize:true},post:{fluid:h('fluid_embed',false),mobile_fullsize:true}};f.exports=i;},null);\n    __d('PluginTags',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={composer:{action_type:'string',action_properties:'string'},create_event_button:{},follow:{href:'url',layout:'string',show_faces:'bool'},like:{href:'url',layout:'string',show_faces:'bool',share:'bool',action:'string',send:'bool'},like_box:{href:'string',show_faces:'bool',header:'bool',stream:'bool',force_wall:'bool',show_border:'bool',id:'string',connections:'string',profile_id:'string',name:'string'},page:{href:'string',hide_cta:'bool',hide_cover:'bool',small_header:'bool',adapt_container_width:'bool',show_facepile:'bool',show_posts:'bool',tabs:'string'},messengerpreconfirmation:{messenger_app_id:'string'},messengeraccountconfirmation:{messenger_app_id:'string',state:'string'},messengerbusinesslink:{messenger_app_id:'string',state:'string'},messengertoggle:{messenger_app_id:'string',token:'string'},messengermessageus:{messenger_app_id:'string',color:'string',size:'string'},page_events:{href:'url'},post:{href:'url',show_border:'bool'},profile_pic:{uid:'string',linked:'bool',href:'string',size:'string',facebook_logo:'bool'},send:{href:'url'},send_to_mobile:{max_rows:'string',show_faces:'bool',size:'string'}},i={subscribe:'follow',fan:'like_box',likebox:'like_box'};ES(ES('Object','keys',false,i),'forEach',true,function(j){h[j]=h[i[j]];});f.exports=h;},null);\n    __d('sdk.Arbiter',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h={BEHAVIOR_EVENT:'e',BEHAVIOR_PERSISTENT:'p',BEHAVIOR_STATE:'s'};f.exports=h;},null);\n    __d('sdk.XFBML.Element',['sdk.DOM','Type','ObservableMixin'],function a(b,c,d,e,f,g,h,i,j){if(c.__markCompiled)c.__markCompiled();var k=i.extend({constructor:function(l){this.parent();this.dom=l;},fire:function(){this.inform.apply(this,arguments);},getAttribute:function(l,m,n){var o=h.getAttr(this.dom,l);return o?n?n(o):o:m;},_getBoolAttribute:function(l,m){var n=h.getBoolAttr(this.dom,l);return n===null?m:n;},_getPxAttribute:function(l,m){return this.getAttribute(l,m,function(n){var o=parseInt(n,10);return isNaN(o)?m:o;});},_getLengthAttribute:function(l,m){return this.getAttribute(l,m,function(n){if(n==='100%')return n;var o=parseInt(n,10);return isNaN(o)?m:o;});},_getAttributeFromList:function(l,m,n){return this.getAttribute(l,m,function(o){o=o.toLowerCase();return ES(n,'indexOf',true,o)>-1?o:m;});},isValid:function(){for(var l=this.dom;l;l=l.parentNode)if(l==document.body)return true;},clear:function(){h.html(this.dom,'');}},j);f.exports=k;},null);\n    __d('sdk.XFBML.IframeWidget',['sdk.Arbiter','sdk.Auth','sdk.Content','sdk.DOM','sdk.Event','sdk.XFBML.Element','guid','insertIframe','QueryString','sdk.Runtime','sdk.ui','UrlMap','sdk.XD'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){if(c.__markCompiled)c.__markCompiled();var u=m.extend({_iframeName:null,_showLoader:true,_refreshOnAuthChange:false,_allowReProcess:false,_fetchPreCachedLoader:false,_visibleAfter:'load',_widgetPipeEnabled:false,_borderReset:false,_repositioned:false,getUrlBits:function(){throw new Error('Inheriting class needs to implement getUrlBits().');},setupAndValidate:function(){return true;},oneTimeSetup:function(){},getSize:function(){},getIframeName:function(){return this._iframeName;},getIframeTitle:function(){return 'Facebook Social Plugin';},getChannelUrl:function(){if(!this._channelUrl){var y=this;this._channelUrl=t.handler(function(z){y.fire('xd.'+z.type,z);},'parent.parent',true);}return this._channelUrl;},getIframeNode:function(){return this.dom.getElementsByTagName('iframe')[0];},arbiterInform:function(event,y,z){t.sendToFacebook(this.getIframeName(),{method:event,params:ES('JSON','stringify',false,y||{}),behavior:z||h.BEHAVIOR_PERSISTENT});},_arbiterInform:function(event,y,z){var aa='parent.frames[\"'+this.getIframeNode().name+'\"]';t.inform(event,y,aa,z);},getDefaultWebDomain:function(){return s.resolve('www');},process:function(y){if(this._done){if(!this._allowReProcess&&!y)return;this.clear();}else this._oneTimeSetup();this._done=true;this._iframeName=this.getIframeName()||this._iframeName||n();if(!this.setupAndValidate()){this.fire('render');return;}if(this._showLoader)this._addLoader();k.addCss(this.dom,'fb_iframe_widget');if(this._visibleAfter!='immediate'){k.addCss(this.dom,'fb_hide_iframes');}else this.subscribe('iframe.onload',ES(this.fire,'bind',true,this,'render'));var z=this.getSize()||{},aa=this.getFullyQualifiedURL();if(z.width=='100%')k.addCss(this.dom,'fb_iframe_widget_fluid');this.clear();o({url:aa,root:this.dom.appendChild(document.createElement('span')),name:this._iframeName,title:this.getIframeTitle(),className:q.getRtl()?'fb_rtl':'fb_ltr',height:z.height,width:z.width,onload:ES(this.fire,'bind',true,this,'iframe.onload')});this._resizeFlow(z);this.loaded=false;this.subscribe('iframe.onload',ES(function(){this.loaded=true;if(!this._isResizeHandled)k.addCss(this.dom,'fb_hide_iframes');},'bind',true,this));},generateWidgetPipeIframeName:function(){v++;return 'fb_iframe_'+v;},getFullyQualifiedURL:function(){var y=this._getURL();y+='?'+p.encode(this._getQS());if(y.length>2000){y='about:blank';var z=ES(function(){this._postRequest();this.unsubscribe('iframe.onload',z);},'bind',true,this);this.subscribe('iframe.onload',z);}return y;},_getWidgetPipeShell:function(){return s.resolve('www')+'/common/widget_pipe_shell.php';},_oneTimeSetup:function(){this.subscribe('xd.resize',ES(this._handleResizeMsg,'bind',true,this));this.subscribe('xd.resize',ES(this._bubbleResizeEvent,'bind',true,this));this.subscribe('xd.resize.iframe',ES(this._resizeIframe,'bind',true,this));this.subscribe('xd.resize.flow',ES(this._resizeFlow,'bind',true,this));this.subscribe('xd.resize.flow',ES(this._bubbleResizeEvent,'bind',true,this));this.subscribe('xd.refreshLoginStatus',function(){i.getLoginStatus(function(){},true);});this.subscribe('xd.logout',function(){r({method:'auth.logout',display:'hidden'},function(){});});if(this._refreshOnAuthChange)this._setupAuthRefresh();if(this._visibleAfter=='load')this.subscribe('iframe.onload',ES(this._makeVisible,'bind',true,this));this.subscribe('xd.verify',ES(function(y){this.arbiterInform('xd/verify',y.token);},'bind',true,this));this.oneTimeSetup();},_makeVisible:function(){this._removeLoader();k.removeCss(this.dom,'fb_hide_iframes');this.fire('render');},_setupAuthRefresh:function(){i.getLoginStatus(ES(function(y){var z=y.status;l.subscribe('auth.statusChange',ES(function(aa){if(!this.isValid())return;if(z=='unknown'||aa.status=='unknown')this.process(true);z=aa.status;},'bind',true,this));},'bind',true,this));},_handleResizeMsg:function(y){if(!this.isValid())return;this._resizeIframe(y);this._resizeFlow(y);if(!this._borderReset){this.getIframeNode().style.border='none';this._borderReset=true;}this._isResizeHandled=true;this._makeVisible();},_bubbleResizeEvent:function(y){var z={height:y.height,width:y.width,pluginID:this.getAttribute('plugin-id')};l.fire('xfbml.resize',z);},_resizeIframe:function(y){var z=this.getIframeNode();if(y.reposition===\"true\")this._repositionIframe(y);y.height&&(z.style.height=y.height+'px');y.width&&(z.style.width=y.width+'px');this._updateIframeZIndex();},_resizeFlow:function(y){var z=this.dom.getElementsByTagName('span')[0];y.height&&(z.style.height=y.height+'px');y.width&&(z.style.width=y.width+'px');this._updateIframeZIndex();},_updateIframeZIndex:function(){var y=this.dom.getElementsByTagName('span')[0],z=this.getIframeNode(),aa=z.style.height===y.style.height&&z.style.width===y.style.width,ba=aa?'removeCss':'addCss';k[ba](z,'fb_iframe_widget_lift');},_repositionIframe:function(y){var z=this.getIframeNode(),aa=parseInt(k.getStyle(z,'width'),10),ba=k.getPosition(z).x,ca=k.getViewportInfo().width,da=parseInt(y.width,10);if(ba+da>ca&&ba>da){z.style.left=aa-da+'px';this.arbiterInform('xd/reposition',{type:'horizontal'});this._repositioned=true;}else if(this._repositioned){z.style.left='0px';this.arbiterInform('xd/reposition',{type:'restore'});this._repositioned=false;}},_addLoader:function(){if(!this._loaderDiv){k.addCss(this.dom,'fb_iframe_widget_loader');this._loaderDiv=document.createElement('div');this._loaderDiv.className='FB_Loader';this.dom.appendChild(this._loaderDiv);}},_removeLoader:function(){if(this._loaderDiv){k.removeCss(this.dom,'fb_iframe_widget_loader');if(this._loaderDiv.parentNode)this._loaderDiv.parentNode.removeChild(this._loaderDiv);this._loaderDiv=null;}},_getQS:function(){return ES('Object','assign',false,{api_key:q.getClientID(),locale:q.getLocale(),sdk:'joey',kid_directed_site:q.getKidDirectedSite(),ref:this.getAttribute('ref')},this.getUrlBits().params);},_getURL:function(){var y=this.getDefaultWebDomain(),z='';return y+'/plugins/'+z+this.getUrlBits().name+'.php';},_postRequest:function(){j.submitToTarget({url:this._getURL(),target:this.getIframeNode().name,params:this._getQS()});}}),v=0,w={};function x(){var y={};for(var z in w){var aa=w[z];y[z]={widget:aa.getUrlBits().name,params:aa._getQS()};}return y;}f.exports=u;},null);\n    __d('sdk.XFBML.Comments',['sdk.Event','sdk.XFBML.IframeWidget','QueryString','sdk.Runtime','JSSDKConfig','sdk.UA','UrlMap'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n){if(c.__markCompiled)c.__markCompiled();var o=i.extend({_visibleAfter:'immediate',_refreshOnAuthChange:true,setupAndValidate:function(){var p={channel_url:this.getChannelUrl(),colorscheme:this.getAttribute('colorscheme'),skin:this.getAttribute('skin'),numposts:this.getAttribute('num-posts',10),width:this._getLengthAttribute('width'),href:this.getAttribute('href'),permalink:this.getAttribute('permalink'),publish_feed:this.getAttribute('publish_feed'),order_by:this.getAttribute('order_by'),mobile:this._getBoolAttribute('mobile'),version:this.getAttribute('version')};if(!p.width&&!p.permalink)p.width=550;if(l.initSitevars.enableMobileComments&&m.mobile()&&p.mobile!==false){p.mobile=true;delete p.width;}if(!p.skin)p.skin=p.colorscheme;if(!p.href){p.migrated=this.getAttribute('migrated');p.xid=this.getAttribute('xid');p.title=this.getAttribute('title',document.title);p.url=this.getAttribute('url',document.URL);p.quiet=this.getAttribute('quiet');p.reverse=this.getAttribute('reverse');p.simple=this.getAttribute('simple');p.css=this.getAttribute('css');p.notify=this.getAttribute('notify');if(!p.xid){var q=ES(document.URL,'indexOf',true,'#');if(q>0){p.xid=encodeURIComponent(document.URL.substring(0,q));}else p.xid=encodeURIComponent(document.URL);}if(p.migrated)p.href=n.resolve('www')+'/plugins/comments_v1.php?'+'app_id='+k.getClientID()+'&xid='+encodeURIComponent(p.xid)+'&url='+encodeURIComponent(p.url);}else{var r=this.getAttribute('fb_comment_id');if(!r){r=j.decode(document.URL.substring(ES(document.URL,'indexOf',true,'?')+1)).fb_comment_id;if(r&&ES(r,'indexOf',true,'#')>0)r=r.substring(0,ES(r,'indexOf',true,'#'));}if(r){p.fb_comment_id=r;this.subscribe('render',ES(function(){if(!window.location.hash)window.location.hash=this.getIframeNode().id;},'bind',true,this));}}if(!p.version)p.version=k.getVersion();this._attr=p;return true;},oneTimeSetup:function(){this.subscribe('xd.sdk_event',function(p){h.fire(p.event,ES('JSON','parse',false,p.data));});},getSize:function(){if(!this._attr.permalink)return {width:this._attr.mobile?'100%':this._attr.width,height:100};},getUrlBits:function(){return {name:'comments',params:this._attr};},getDefaultWebDomain:function(){return n.resolve('www',true);}});f.exports=o;},null);\n    __d('sdk.XFBML.CommentsCount',['ApiClient','sdk.DOM','sdk.XFBML.Element','sprintf'],function a(b,c,d,e,f,g,h,i,j,k){if(c.__markCompiled)c.__markCompiled();var l=j.extend({process:function(){i.addCss(this.dom,'fb_comments_count_zero');var m=this.getAttribute('href',window.location.href);h.scheduleBatchCall('/v2.1/'+encodeURIComponent(m),{fields:'share'},ES(function(n){var o=n.share&&n.share.comment_count||0;i.html(this.dom,k('<span class=\"fb_comments_count\">%s</span>',o));if(o>0)i.removeCss(this.dom,'fb_comments_count_zero');this.fire('render');},'bind',true,this));}});f.exports=l;},null);\n    __d('safeEval',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();function h(i,j){if(i===null||typeof i==='undefined')return;if(typeof i!=='string')return i;if(/^\\w+$/.test(i)&&typeof window[i]==='function')return window[i].apply(null,j||[]);return Function('return eval(\"'+i.replace(/\"/g,'\\\\\"')+'\");').apply(null,j||[]);}f.exports=h;},null);\n    __d('sdk.Helper',['sdk.ErrorHandling','sdk.Event','UrlMap','safeEval','sprintf'],function a(b,c,d,e,f,g,h,i,j,k,l){if(c.__markCompiled)c.__markCompiled();var m={isUser:function(n){return n<2.2e+09||n>=1e+14&&n<=100099999989999||n>=8.9e+13&&n<=89999999999999||n>=6.000001e+13&&n<=60000019999999;},upperCaseFirstChar:function(n){if(n.length>0){return n.substr(0,1).toUpperCase()+n.substr(1);}else return n;},getProfileLink:function(n,o,p){if(!p&&n)p=l('%s/profile.php?id=%s',j.resolve('www'),n.uid||n.id);if(p)o=l('<a class=\"fb_link\" href=\"%s\">%s</a>',p,o);return o;},invokeHandler:function(n,o,p){if(n)if(typeof n==='string'){h.unguard(k)(n,p);}else if(n.apply)h.unguard(n).apply(o,p||[]);},fireEvent:function(n,o){var p=o._attr.href;o.fire(n,p);i.fire(n,p,o);},executeFunctionByName:function(n){var o=Array.prototype.slice.call(arguments,1),p=n.split(\".\"),q=p.pop(),r=window;for(var s=0;s<p.length;s++)r=r[p[s]];return r[q].apply(this,o);}};f.exports=m;},null);\n    __d('sdk.XFBML.LoginButton',['sdk.Helper','IframePlugin','Log','sdk.ui'],function a(b,c,d,e,f,g,h,i,j,k){if(c.__markCompiled)c.__markCompiled();var l=i.extend({constructor:function(m,n,o,p){this.parent(m,n,o,p);var q=i.getVal(p,'on_login'),r=null;if(q){r=function(s){if(s.error_code){j.debug('Plugin Return Error (%s): %s',s.error_code,s.error_message||s.error_description);return;}h.invokeHandler(q,null,[s]);};this.subscribe('login.status',r);}this.subscribe('xd.login_button_native_open',function(s){k(ES('JSON','parse',false,s.params),r);});},getParams:function(){return {scope:'string',perms:'string',size:'string',login_text:'text',show_faces:'bool',max_rows:'string',show_login_face:'bool',registration_url:'url_maybe',auto_logout_link:'bool',one_click:'bool',show_banner:'bool',auth_type:'string',default_audience:'string'};}});f.exports=l;},null);\n    __d('escapeHTML',[],function a(b,c,d,e,f,g){if(c.__markCompiled)c.__markCompiled();var h=/[&<>\"'\\/]/g,i={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#039;','/':'&#x2F;'};function j(k){return k.replace(h,function(l){return i[l];});}f.exports=j;},null);\n    __d('sdk.XFBML.Name',['ApiClient','escapeHTML','sdk.Event','sdk.XFBML.Element','sdk.Helper','Log','sdk.Runtime'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n){if(c.__markCompiled)c.__markCompiled();var o=({}).hasOwnProperty,p=k.extend({process:function(){ES('Object','assign',false,this,{_uid:this.getAttribute('uid'),_firstnameonly:this._getBoolAttribute('first-name-only'),_lastnameonly:this._getBoolAttribute('last-name-only'),_possessive:this._getBoolAttribute('possessive'),_reflexive:this._getBoolAttribute('reflexive'),_objective:this._getBoolAttribute('objective'),_linked:this._getBoolAttribute('linked',true),_subjectId:this.getAttribute('subject-id')});if(!this._uid){m.error('\"uid\" is a required attribute for <fb:name>');this.fire('render');return;}var q=[];if(this._firstnameonly){q.push('first_name');}else if(this._lastnameonly){q.push('last_name');}else q.push('name');if(this._subjectId){q.push('gender');if(this._subjectId==n.getUserID())this._reflexive=true;}j.monitor('auth.statusChange',ES(function(){if(!this.isValid()){this.fire('render');return true;}if(!this._uid||this._uid=='loggedinuser')this._uid=n.getUserID();if(!this._uid)return;h.scheduleBatchCall('/v1.0/'+this._uid,{fields:q.join(',')},ES(function(r){if(o.call(r,'error')){m.warn('The name is not found for ID: '+this._uid);return;}if(this._subjectId==this._uid){this._renderPronoun(r);}else this._renderOther(r);this.fire('render');},'bind',true,this));},'bind',true,this));},_renderPronoun:function(q){var r='',s=this._objective;if(this._subjectId){s=true;if(this._subjectId===this._uid)this._reflexive=true;}if(this._uid==n.getUserID()&&this._getBoolAttribute('use-you',true)){if(this._possessive){if(this._reflexive){r='your own';}else r='your';}else if(this._reflexive){r='yourself';}else r='you';}else switch(q.gender){case 'male':if(this._possessive){r=this._reflexive?'his own':'his';}else if(this._reflexive){r='himself';}else if(s){r='him';}else r='he';break;case 'female':if(this._possessive){r=this._reflexive?'her own':'her';}else if(this._reflexive){r='herself';}else if(s){r='her';}else r='she';break;default:if(this._getBoolAttribute('use-they',true)){if(this._possessive){if(this._reflexive){r='their own';}else r='their';}else if(this._reflexive){r='themselves';}else if(s){r='them';}else r='they';}else if(this._possessive){if(this._reflexive){r='his/her own';}else r='his/her';}else if(this._reflexive){r='himself/herself';}else if(s){r='him/her';}else r='he/she';break;}if(this._getBoolAttribute('capitalize',false))r=l.upperCaseFirstChar(r);this.dom.innerHTML=r;},_renderOther:function(q){var r='',s='';if(this._uid==n.getUserID()&&this._getBoolAttribute('use-you',true)){if(this._reflexive){if(this._possessive){r='your own';}else r='yourself';}else if(this._possessive){r='your';}else r='you';}else if(q){if(null===q.first_name)q.first_name='';if(null===q.last_name)q.last_name='';if(this._firstnameonly&&q.first_name!==undefined){r=i(q.first_name);}else if(this._lastnameonly&&q.last_name!==undefined)r=i(q.last_name);if(!r)r=i(q.name);if(r!==''&&this._possessive)r+='\\'s';}if(!r)r=i(this.getAttribute('if-cant-see','Facebook User'));if(r){if(this._getBoolAttribute('capitalize',false))r=l.upperCaseFirstChar(r);if(q&&this._linked){s=l.getProfileLink(q,r,this.getAttribute('href',null));}else s=r;}this.dom.innerHTML=s;}});f.exports=p;},null);\n    __d('sdk.XFBML.ShareButton',['IframePlugin','sdk.ui'],function a(b,c,d,e,f,g,h,i){'use strict';if(c.__markCompiled)c.__markCompiled();var j=h.extend({constructor:function(k,l,m,n){this.parent(k,l,m,n);this.subscribe('xd.shareTriggerIframe',function(o){var p=ES('JSON','parse',false,o.data);i({method:'share',href:p.href,iframe_test:true});});},getParams:function(){return {href:'url',layout:'string',type:'string'};}});f.exports=j;},null);\n    __d('sdk.XFBML.Video',['Assert','sdk.Event','IframePlugin','ObservableMixin','sdk.XD'],function a(b,c,d,e,f,g,h,i,j,k,l){if(c.__markCompiled)c.__markCompiled();function m(p){'use strict';this.$VideoCache1=p.isMuted;this.$VideoCache2=p.volume;this.$VideoCache3=p.timePosition;this.$VideoCache4=p.duration;}m.prototype.update=function(p){'use strict';if(p.isMuted!==undefined)this.$VideoCache1=p.isMuted;if(p.volume!==undefined)this.$VideoCache2=p.volume;if(p.timePosition!==undefined)this.$VideoCache3=p.timePosition;if(p.duration!==undefined)this.$VideoCache4=p.duration;};m.prototype.isMuted=function(){'use strict';return this.$VideoCache1;};m.prototype.getVolume=function(){'use strict';return this.$VideoCache1?0:this.$VideoCache2;};m.prototype.getCurrentPosition=function(){'use strict';return this.$VideoCache3;};m.prototype.getDuration=function(){'use strict';return this.$VideoCache4;};function n(p,q,r){'use strict';this.$VideoController1=p;this.$VideoController2=q;this.$VideoController3=r;}n.prototype.play=function(){'use strict';l.sendToFacebook(this.$VideoController1,{method:'play',params:ES('JSON','stringify',false,{})});};n.prototype.pause=function(){'use strict';l.sendToFacebook(this.$VideoController1,{method:'pause',params:ES('JSON','stringify',false,{})});};n.prototype.seek=function(p){'use strict';h.isNumber(p,'Invalid argument');l.sendToFacebook(this.$VideoController1,{method:'seek',params:ES('JSON','stringify',false,{target:p})});};n.prototype.mute=function(){'use strict';l.sendToFacebook(this.$VideoController1,{method:'mute',params:ES('JSON','stringify',false,{})});};n.prototype.unmute=function(){'use strict';l.sendToFacebook(this.$VideoController1,{method:'unmute',params:ES('JSON','stringify',false,{})});};n.prototype.setVolume=function(p){'use strict';h.isNumber(p,'Invalid argument');l.sendToFacebook(this.$VideoController1,{method:'setVolume',params:ES('JSON','stringify',false,{volume:p})});};n.prototype.isMuted=function(){'use strict';return this.$VideoController3.isMuted();};n.prototype.getVolume=function(){'use strict';return this.$VideoController3.getVolume();};n.prototype.getCurrentPosition=function(){'use strict';return this.$VideoController3.getCurrentPosition();};n.prototype.getDuration=function(){'use strict';return this.$VideoController3.getDuration();};n.prototype.subscribe=function(event,p){'use strict';h.isString(event,'Invalid argument');h.isFunction(p,'Invalid argument');this.$VideoController2.subscribe(event,p);return {release:ES(function(){this.$VideoController2.unsubscribe(event,p);},'bind',true,this)};};var o=j.extend({constructor:function(p,q,r,s){this.parent(p,q,r,s);this._videoController=null;this._sharedObservable=null;this._sharedVideoCache=null;this.subscribe('xd.onVideoAPIReady',function(t){this._sharedObservable=new k();this._sharedVideoCache=new m(ES('JSON','parse',false,t.data));this._videoController=new n(this._iframeOptions.name,this._sharedObservable,this._sharedVideoCache);i.fire('xfbml.ready',{type:'video',id:s.id,instance:this._videoController});});this.subscribe('xd.stateChange',function(t){this._sharedObservable.inform(t.state);});this.subscribe('xd.cachedStateUpdateRequest',function(t){this._sharedVideoCache.update(ES('JSON','parse',false,t.data));});},getParams:function(){return {allowfullscreen:'bool',autoplay:'bool',controls:'bool',href:'url'};},getConfig:function(){return {fluid:true,full_width:true};}});f.exports=o;},null);\n    __d('legacy:fb.xfbml',['Assert','sdk.Event','FB','IframePlugin','PluginConfig','PluginTags','XFBML','sdk.domReady','sdk.feature','wrapFunction','sdk.XFBML.Comments','sdk.XFBML.CommentsCount','sdk.XFBML.LoginButton','sdk.XFBML.Name','sdk.XFBML.ShareButton','sdk.XFBML.Video'],function a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q){if(c.__markCompiled)c.__markCompiled();var r={comments:c('sdk.XFBML.Comments'),comments_count:c('sdk.XFBML.CommentsCount'),login_button:c('sdk.XFBML.LoginButton'),name:c('sdk.XFBML.Name'),share_button:c('sdk.XFBML.ShareButton'),video:c('sdk.XFBML.Video')},s=p('plugin_tags_blacklist',[]);ES(ES('Object','keys',false,m),'forEach',true,function(u){if(ES(s,'indexOf',true,u)!==-1)return;n.registerTag({xmlns:'fb',localName:u.replace(/_/g,'-'),ctor:k.withParams(m[u],l[u])});});ES(ES('Object','keys',false,r),'forEach',true,function(u){if(ES(s,'indexOf',true,u)!==-1)return;n.registerTag({xmlns:'fb',localName:u.replace(/_/g,'-'),ctor:r[u]});});j.provide('XFBML',{parse:function(u){h.maybeXfbml(u,'Invalid argument');if(u&&u.nodeType===9)u=u.body;return n.parse.apply(null,arguments);}});n.subscribe('parse',ES(i.fire,'bind',true,i,'xfbml.parse'));n.subscribe('render',ES(i.fire,'bind',true,i,'xfbml.render'));i.subscribe('init:post',function(u){if(u.xfbml)setTimeout(q(ES(o,'bind',true,null,n.parse),'entry','init:post:xfbml.parse'),0);});h.define('Xfbml',function(u){return (u.nodeType===1||u.nodeType===9)&&typeof u.nodeName==='string';});try{if(document.namespaces&&!document.namespaces.item.fb)document.namespaces.add('fb');}catch(t){}},3);\n}  }).call(global);})(window.inDapIF ? parent.window : window, window);} catch (e) {new Image().src=\"https:\\/\\/www.facebook.com\\/\" + 'common/scribe_endpoint.php?c=jssdk_error&m='+encodeURIComponent('{\"error\":\"LOAD\", \"extra\": {\"name\":\"'+e.name+'\",\"line\":\"'+(e.lineNumber||e.line)+'\",\"script\":\"'+(e.fileName||e.sourceURL||e.script)+'\",\"stack\":\"'+(e.stackTrace||e.stack)+'\",\"revision\":\"2136283\",\"namespace\":\"FB\",\"message\":\"'+e.message+'\"}}');}\n"
  },
  {
    "path": "public/js/app.js",
    "content": "angular.module('mean', ['ngCookies', 'ngResource', 'ui.router', 'ui.bootstrap', 'ui.route', 'mean.system', 'mean.articles', 'mean.auth','satellizer','angularFblogin'])\n.config(function ($authProvider) {\n\n    $authProvider.twitter({\n        url: '/auth/twitter',\n        authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',\n        redirectUri:  'http://localhost:3000/auth/twitter/callback',\n        oauthType: '1.0',\n        popupOptions: { width: 495, height: 645 }\n    });\n\n    $authProvider.google({\n        clientId: 'your google client id here', // google client id\n        url: '/auth/google',\n        redirectUri: 'http://localhost:3000/auth/google/callback'\n    });\n\n});\n\nangular.module('mean.system', []);\nangular.module('mean.articles', []);\nangular.module('mean.auth', []);"
  },
  {
    "path": "public/js/config.js",
    "content": "//Setting up route\nangular.module('mean').config(['$stateProvider','$urlRouterProvider', function($stateProvider,$urlRouterProvider) {\n\n    $urlRouterProvider.otherwise(function($injector, $location){\n        $injector.invoke(['$state', function($state) {\n            $state.go('404');\n        }]);\n    });\n    $stateProvider\n        .state('home',{\n            url : '/',\n            controller : 'IndexController',\n            templateUrl: 'views/index.html'\n        })\n        .state('SignIn',{\n            url : '/signin',\n            templateUrl: 'views/users/signin.html'\n        })\n        .state('SignUp',{\n            url : '/signup',\n            templateUrl: 'views/users/signup.html'\n        })\n        .state('articles',{\n            url : '/article',\n            controller : 'ArticlesController',\n            templateUrl: 'views/articles/list.html'\n        })\n        .state('createArticle',{\n            url : '/article/create',\n            controller : 'ArticlesController',\n            templateUrl: 'views/articles/create.html'\n        })\n        .state('editArticles',{\n            url : '/article/{articleId}/edit',\n            controller : 'ArticlesController',\n            templateUrl: 'views/articles/edit.html'\n        })\n        .state('viewArticle',{\n            url : '/article/{articleId}',\n            controller : 'ArticlesController',\n            templateUrl: 'views/articles/view.html'\n        })\n        .state('404',{\n            templateUrl: 'views/404.html'\n        })\n}\n]);\n\n//Setting HTML5 Location Mode\nangular.module('mean').config(['$locationProvider', function ($locationProvider) {\n    $locationProvider.html5Mode(true);\n\n}]);"
  },
  {
    "path": "public/js/controllers/articles.js",
    "content": "angular.module('mean.articles').controller('ArticlesController', ['$scope', '$stateParams', 'Global', 'Articles', '$state', function ($scope, $stateParams, Global, Articles, $state) {\n    $scope.global = Global;\n\n    $scope.create = function() {\n        var article = new Articles({\n            title: this.title,\n            content: this.content\n        });\n\n        article.$save(function(response) {\n            $state.go('viewArticle',{articleId : response.id})\n        });\n\n        this.title = \"\";\n        this.content = \"\";\n    };\n\n    $scope.remove = function(article) {\n        if (article) {\n            article.$remove();  \n\n            for (var i in $scope.articles) {\n                if ($scope.articles[i] === article) {\n                    $scope.articles.splice(i, 1);\n                }\n            }\n        }\n        else {\n            $scope.article.$remove();\n            $state.go('articles');\n        }\n    };\n\n    $scope.update = function() {\n        var article = $scope.article;\n        if (!article.updated) {\n            article.updated = [];\n        }\n        article.updated.push(new Date().getTime());\n        article.$update(function() {\n        $state.go('viewArticle',{articleId : article.id})\n\n        });\n    };\n\n    $scope.find = function() {\n        Articles.query(function(articles) {\n            $scope.articles = articles;\n        });\n    };\n\n    $scope.findOne = function() {\n        Articles.get({\n            articleId: $stateParams.articleId\n        }, function(article) {\n            $scope.article = article;\n        });\n    };\n    $scope.find = function() {\n        Articles.query(function(articles) {\n            $scope.articles = articles;\n        });\n    };\n\n\n\n}]);"
  },
  {
    "path": "public/js/controllers/header.js",
    "content": "angular.module('mean.system').controller('HeaderController', ['$scope', 'Global', 'SignOut', '$state', function ($scope, Global, SignOut, $state) {\n    $scope.global = Global;\n\n    $scope.menu = [{\n        \"title\": \"Articles\",\n        \"state\": \"articles\"\n    }, {\n        \"title\": \"Create New Article\",\n        \"state\": \"createArticle\"\n    }];\n    \n    $scope.isCollapsed = false;\n\n    $scope.SignOut = function(){\n        SignOut.get(function(response){\n            if(response.status === 'success'){\n                $scope.global = null;\n                $state.go('home');\n            }\n        });\n    }\n\n\n}]);"
  },
  {
    "path": "public/js/controllers/index.js",
    "content": "angular.module('mean.system').controller('IndexController', ['$scope', 'Global', function ($scope, Global) {\n    $scope.global = Global;\n}]);"
  },
  {
    "path": "public/js/controllers/users/auth.js",
    "content": "angular.module('mean.auth').controller('socialAuth', ['$scope', 'Global','$state', '$fblogin', 'SocialAuth','$window','$auth', function ($scope, Global, $state, $fblogin, SocialAuth, $window, $auth) {\n    $scope.global = Global;\n\n    $scope.menu = [{\n        \"title\": \"Articles\",\n        \"state\": \"articles\"\n    }, {\n        \"title\": \"Create New Article\",\n        \"state\": \"createArticle\"\n    }];\n\n    $scope.isCollapsed = false;\n\n    $scope.fbAuth = function(){\n        $fblogin({\n            fbId: \"102551953548872\",\n            permissions: 'email,user_birthday',\n            fields: 'first_name,last_name,email,birthday,picture'\n        }).then(function () {\n            SocialAuth.FbLogin(FB.getAuthResponse()).then(function (response) {\n                if(response.status === 'success' || 200){\n                    $window.location.href = '/';\n                }\n            });\n        }).catch(function () {\n            $window.location.reload();\n        })\n    };\n    $scope.twitterAuth = function(){\n        $auth.authenticate('twitter').then(function(response) {\n            if(response.status === 'success' || 200){\n                $window.location.href = '/';\n            }\n        });\n    };\n\n    $scope.googleAuth = function(){\n\n        $auth.authenticate('google').then(function(response) {\n            if(response.status === 'success' || 200){\n                $window.location.href = '/';\n            }\n        });\n    };\n\n\n}]);"
  },
  {
    "path": "public/js/controllers/users/signIn.js",
    "content": "angular.module('mean.auth').controller('signIn', ['$scope', '$window', 'Global', '$state', 'LogIn', function ($scope, $window, Global, $state, LogIn) {\n    $scope.global = Global;\n\n\n    $scope.signIn = function(user) {\n\n        var logIn = new LogIn({\n            email: user.email,\n            password: user.password\n        });\n\n        logIn.$save(function(response) {\n            if(response.status === 'success'){\n                $window.location.href = '/';\n            }\n        });\n    };\n\n\n}]);"
  },
  {
    "path": "public/js/controllers/users/signUp.js",
    "content": "angular.module('mean.auth').controller('signUp', ['$scope', '$window', 'Global','$state', 'SignUp', function ($scope, $window, Global, $state, SignUp) {\n    $scope.global = Global;\n\n\n    $scope.signUp = function(user) {\n\n        var signUp = new SignUp({\n            name: user.name,\n            email: user.email,\n            username : user.userName,\n            password : user.password\n        });\n\n        signUp.$save(function(response) {\n            if(response.status === 'success'){\n                $window.location.href = '/';\n            }\n        });\n    };\n\n\n}]);"
  },
  {
    "path": "public/js/directives.js",
    "content": ""
  },
  {
    "path": "public/js/filters.js",
    "content": ""
  },
  {
    "path": "public/js/init.js",
    "content": "angular.element(document).ready(function() {\n    //Fixing facebook bug with redirect\n    if (window.location.hash === \"#_=_\") {\n        window.location.hash = \"#!\";\n    }\n\n    //Then init the app\n    angular.bootstrap(document, ['mean']);\n});"
  },
  {
    "path": "public/js/services/articles.js",
    "content": "//Articles service used for articles REST endpoint\nangular.module('mean.articles').factory(\"Articles\", ['$resource', function($resource) {\n    return $resource('articles/:articleId', {\n        articleId: '@id'\n    }, {\n        update: {\n            method: 'PUT'\n        }\n    });\n}]);"
  },
  {
    "path": "public/js/services/authenticate.js",
    "content": "\nangular.module('mean.auth').factory(\"SocialAuth\", ['$http', function ($http) {\n    return {\n        FbLogin: function (token) {\n            return $http.post('/auth/facebook/token', {\"access_token\": token.accessToken})\n                .then(function (res) {\n                    return res;\n                });\n        }\n    }\n}]);\nangular.module('mean.auth').service(\"SignOut\", ['$resource', function($resource) {\n    return $resource('/signout');\n}]);\nangular.module('mean.auth').service(\"LogIn\", ['$resource', function($resource) {\n    return $resource('/users/session');\n}]);\nangular.module('mean.auth').service(\"SignUp\", ['$resource', function($resource) {\n    return $resource('/users');\n}]);"
  },
  {
    "path": "public/js/services/global.js",
    "content": "//Global service for global variables\nangular.module('mean.system').factory(\"Global\", [\n    function() {\n        var _this = this;\n        _this._data = {\n            user: window.user,\n            authenticated: !! window.user\n        };\n        return _this._data;\n    }\n]);\n"
  },
  {
    "path": "public/robots.txt",
    "content": "# robotstxt.org/\n\nUser-agent: *\n"
  },
  {
    "path": "public/views/404.html",
    "content": "<section>\n    <h1>ERROR #404</h1>\n    <h3>The link you followed may be broken, or the page may have been removed.</h3>\n</section>"
  },
  {
    "path": "public/views/articles/create.html",
    "content": "<section>\n\t<form class=\"form-horizontal\" data-ng-submit=\"create()\">\n\t\t<div class=\"control-group\">\n\t\t\t<label class=\"control-label\" for=\"title\">Title</label>\n\t\t\t<div class=\"controls\">\n\t\t\t\t<input type=\"text\" data-ng-model=\"title\" id=\"title\" placeholder=\"Title\" required>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"control-group\">\n\t\t\t<label class=\"control-label\" for=\"content\">Content</label>\n\t\t\t<div class=\"controls\">\n\t\t\t\t<textarea data-ng-model=\"content\" id=\"content\" cols=\"30\" rows=\"10\" placeholder=\"Content\"></textarea>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"control-group\">\n\t\t\t<div class=\"controls\">\n\t\t\t\t<input type=\"submit\" class=\"btn\">\n\t\t\t</div>\n\t\t</div>\n\t</form>\n</section>"
  },
  {
    "path": "public/views/articles/edit.html",
    "content": "<section data-ng-init=\"findOne()\">\n\t<form class=\"form-horizontal\" data-ng-submit=\"update()\">\n\t\t<div class=\"control-group\">\n\t\t\t<label class=\"control-label\" for=\"title\">Title</label>\n\n\t\t\t<div class=\"controls\">\n\t\t\t\t<input type=\"text\" data-ng-model=\"article.title\" id=\"title\" placeholder=\"Title\" required>\n\t\t\t\t</input>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"control-group\">\n\t\t\t<label class=\"control-label\" for=\"content\">Content</label>\n\n\t\t\t<div class=\"controls\">\n\t\t\t\t<textarea data-ng-model=\"article.content\" id=\"content\" cols=\"30\" rows=\"10\" placeholder=\"Content\">\n\t\t\t\t</textarea>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"control-group\">\n\t\t\t<div class=\"controls\">\n\t\t\t\t<input type=\"submit\" class=\"btn\">\n\t\t\t</div>\n\t\t</div>\n\t</form>\n</section>"
  },
  {
    "path": "public/views/articles/list.html",
    "content": "<section data-ng-init=\"find()\">\n\t<ul class=\"articles unstyled\">\n\t\t<li data-ng-repeat=\"article in articles\">\n\t\t\t<span>{{article.updatedAt | date:'medium'}}</span> /\n\t\t\t<span>{{article.User.name}}</span>\n\t\t\t<h2><a ui-sref=\"viewArticle({articleId : article.id})\">{{article.title}}</a></h2>\n\t\t\t<div>{{article.content}}</div>\n\t\t</li>\n\t</ul>\n\t<h1 data-ng-hide=\"!articles || articles.length\">No articles yet. <br> Why don't you <a ui-sref=\"createArticle\">Create One</a>?</h1>\n</section>"
  },
  {
    "path": "public/views/articles/view.html",
    "content": "<section data-ng-init=\"findOne()\">\n    <span>{{article.updatedAt | date:'medium'}}</span>/\n    <span>{{article.User.name}}</span>\n    <h2>{{article.title}}</h2>\n    <div data-ng-show=\"global.user.id == article.User.id\">\n        <a class=\"btn\" ui-sref=\"editArticles({articleId : article.id})\">Edit</a>\n        <a class=\"btn\" data-ng-click=\"remove();\">Delete</a>\n    </div>\n    <div>{{article.content}}</div>\n</section>\n"
  },
  {
    "path": "public/views/header.html",
    "content": "<div class=\"navbar-inner\" data-ng-controller=\"HeaderController\">\n    <ul class=\"nav\">\n        <li>\n            <a class=\"brand\" ui-sref=\"home\">MEAN - A Modern Stack</a>\n        </li>\n        <li data-ng-repeat=\"item in menu\" data-ng-show=\"global.user\" ui-route=\"/{{item.link}}\" ng-class=\"{active: $uiRoute}\">\n            <a ui-sref=\"{{item.state}}\">{{item.title}}</a>\n        </li>\n    </ul>\n    <ul class=\"nav pull-right\" data-ng-hide=\"global.authenticated\">\n        <li><a ui-sref=\"SignUp\">Signup</a>\n        </li>\n        <li class=\"divider-vertical\"></li>\n        <li><a ui-sref=\"SignIn\">Signin</a>\n        </li>\n    </ul>\n    <ul class=\"nav pull-right\" data-ng-show=\"global.authenticated\">\n        <li class=\"dropdown\">\n            <a class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n\t\t\t\t{{global.user.name}} <b class=\"caret\"></b>\n\t\t\t</a>\n            <ul class=\"dropdown-menu\">\n                <li><a ng-click=\"SignOut()\">Signout</a>\n                </li>\n            </ul>\n        </li>\n    </ul>\n</div>"
  },
  {
    "path": "public/views/index.html",
    "content": "<section>\n\t<h1>This is the home view</h1>\n</section>"
  },
  {
    "path": "public/views/users/auth.html",
    "content": "<div class=\"row\" data-ng-controller=\"socialAuth\">\n    <div class=\"span6\"><a ng-click=\"fbAuth();\"><img src=\"/img/icons/facebook.png\"/></a><a ng-click=\"twitterAuth();\"><img src=\"/img/icons/twitter.png\"/></a><a ng-click=\"googleAuth();\"><img src=\"/img/icons/google.png\"/></a></div>\n    <div class=\"span6\">\n    </div>\n</div>"
  },
  {
    "path": "public/views/users/signin.html",
    "content": "\n<span ng-include=\"'../views/users/auth.html'\"></span>\n<span ng-controller=\"signIn\">\n    <form ng-submit=\"signIn(user)\" class=\"signin form-horizontal\" name=\"signInForm\">\n        <div class=\"control-group\">\n            <label for=\"email\" class=\"control-label\">Email</label>\n\n            <div class=\"controls\">\n                <input id=\"email\" type=\"text\" name=\"email\" placeholder=\"Email\" ng-model=\"user.email\" required>\n            </div>\n        </div>\n        <div class=\"control-group\">\n            <label for=\"password\" class=\"control-label\">Password</label>\n\n            <div class=\"controls\">\n                <input id=\"password\" type=\"password\" name=\"password\" placeholder=\"Password\" ng-model=\"user.password\" required>\n            </div>\n        </div>\n        <div class=\"form-actions\">\n            <button type=\"submit\" class=\"btn btn-primary\">Sign in&nbsp;</button>\n            or&nbsp;<a ui-sref=\"SignUp\" class=\"show-signup\">Sign up</a>\n        </div>\n    </form>\n</span>\n"
  },
  {
    "path": "public/views/users/signup.html",
    "content": "<div ng-include=\"'../views/users/auth.html'\"></div>\n<div ng-controller=\"signUp\">\n    <form ng-submit=\"signUp(user)\"  class=\"signup form-horizontal\">\n        <div class=\"control-group\">\n            <label for=\"name\" class=\"control-label\">Full name</label>\n            <div class=\"controls\">\n                <input id=\"name\" type=\"text\" name=\"name\" placeholder=\"Full name\" ng-model=\"user.name\" required>\n            </div>\n        </div>\n        <div class=\"control-group\">\n            <label for=\"email\" class=\"control-label\">Email</label>\n            <div class=\"controls\">\n                <input id=\"email\" type=\"text\" name=\"email\" placeholder=\"Email\" ng-model=\"user.email\" required>\n            </div>\n        </div>\n        <div class=\"control-group\">\n            <label for=\"username\" class=\"control-label\">Username</label>\n            <div class=\"controls\">\n                <input id=\"username\" type=\"text\" name=\"username\" placeholder=\"Username\" ng-model=\"user.userName\" required>\n            </div>\n        </div>\n        <div class=\"control-group\">\n            <label for=\"password\" class=\"control-label\">Password</label>\n            <div class=\"controls\">\n                <input id=\"password\" type=\"password\" name=\"password\" placeholder=\"Password\" ng-model=\"user.password\" required>\n            </div>\n        </div>\n        <div class=\"form-actions\">\n            <button type=\"submit\" class=\"btn btn-primary\">Sign up&nbsp;</button>or&nbsp;<a ui-sref=\"SignIn\" class=\"show-login\">login</a>\n        </div>\n    </form>\n</div>"
  },
  {
    "path": "test/karma/karma.conf.js",
    "content": "// Karma configuration\n// Generated on Sat Oct 05 2013 22:00:14 GMT+0700 (ICT)\n\nmodule.exports = function(config) {\n    config.set({\n\n        // base path, that will be used to resolve files and exclude\n        basePath: '../../',\n\n\n        // frameworks to use\n        frameworks: ['jasmine'],\n\n\n        // list of files / patterns to load in the browser\n        files: [\n            'public/lib/angular/angular.js',\n            'public/lib/angular-mocks/angular-mocks.js',\n            'public/lib/angular-cookies/angular-cookies.js',\n            'public/lib/angular-resource/angular-resource.js',\n            'public/lib/angular-route/angular-route.js',\n            'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',\n            'public/lib/angular-bootstrap/ui-bootstrap.js',\n            'public/lib/angular-ui-utils/modules/route/route.js',\n            'public/js/app.js',\n            'public/js/config.js',\n            'public/js/directives.js',\n            'public/js/filters.js',\n            'public/js/services/global.js',\n            'public/js/services/articles.js',\n            'public/js/controllers/articles.js',\n            'public/js/controllers/index.js',\n            'public/js/controllers/header.js',\n            'public/js/init.js',\n            'test/karma/unit/**/*.js'\n        ],\n\n\n        // list of files to exclude\n        exclude: [\n\n        ],\n\n\n        // test results reporter to use\n        // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'\n        //reporters: ['progress'],\n        reporters: ['progress', 'coverage'],\n\n        // coverage\n        preprocessors: {\n            // source files, that you wanna generate coverage for\n            // do not include tests or libraries\n            // (these files will be instrumented by Istanbul)\n            'public/js/controllers/*.js': ['coverage'],\n            'public/js/services/*.js': ['coverage']\n        },\n\n        coverageReporter: {\n            type: 'html',\n            dir: 'test/coverage/'\n        },\n\n        // web server port\n        port: 9876,\n\n\n        // enable / disable colors in the output (reporters and logs)\n        colors: true,\n\n\n        // level of logging\n        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n        logLevel: config.LOG_INFO,\n\n\n        // enable / disable watching file and executing tests whenever any file changes\n        autoWatch: true,\n\n\n        // Start these browsers, currently available:\n        // - Chrome\n        // - ChromeCanary\n        // - Firefox\n        // - Opera\n        // - Safari (only Mac)\n        // - PhantomJS\n        // - IE (only Windows)\n        browsers: ['PhantomJS'],\n\n\n        // If browser does not capture in given timeout [ms], kill it\n        captureTimeout: 60000,\n\n\n        // Continuous Integration mode\n        // if true, it capture browsers, run tests and exit\n        singleRun: true\n    });\n};"
  },
  {
    "path": "test/karma/unit/controllers/articles.spec.js",
    "content": "(function() {\n    'use strict';\n\n    // Articles Controller Spec\n    describe('MEAN controllers', function() {\n\n        describe('ArticlesController', function() {\n\n            // The $resource service augments the response object with methods for updating and deleting the resource.\n            // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match\n            // the responses exactly. To solve the problem, we use a newly-defined toEqualData Jasmine matcher.\n            // When the toEqualData matcher compares two objects, it takes only object properties into\n            // account and ignores methods.\n            beforeEach(function() {\n                this.addMatchers({\n                    toEqualData: function(expected) {\n                        return angular.equals(this.actual, expected);\n                    }\n                });\n            });\n\n            // Load the controllers module\n            beforeEach(module('mean'));\n\n            // Initialize the controller and a mock scope\n            var ArticlesController,\n                scope,\n                $httpBackend,\n                $routeParams,\n                $location;\n\n            // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).\n            // This allows us to inject a service but then attach it to a variable\n            // with the same name as the service.\n            beforeEach(inject(function($controller, $rootScope, _$location_, _$routeParams_, _$httpBackend_) {\n\n                scope = $rootScope.$new();\n\n                ArticlesController = $controller('ArticlesController', {\n                    $scope: scope\n                });\n\n                $routeParams = _$routeParams_;\n\n                $httpBackend = _$httpBackend_;\n\n                $location = _$location_;\n\n            }));\n\n            it('$scope.find() should create an array with at least one article object ' +\n                'fetched from XHR', function() {\n\n                    // test expected GET request\n                    $httpBackend.expectGET('articles').respond([{\n                        title: 'An Article about MEAN',\n                        content: 'MEAN rocks!'\n                    }]);\n\n                    // run controller\n                    scope.find();\n                    $httpBackend.flush();\n\n                    // test scope value\n                    expect(scope.articles).toEqualData([{\n                        title: 'An Article about MEAN',\n                        content: 'MEAN rocks!'\n                    }]);\n\n                });\n\n            it('$scope.findOne() should create an array with one article object fetched ' +\n                'from XHR using a articleId URL parameter', function() {\n                    // fixture URL parament\n                    $routeParams.articleId = '525a8422f6d0f87f0e407a33';\n\n                    // fixture response object\n                    var testArticleData = function() {\n                        return {\n                            title: 'An Article about MEAN',\n                            content: 'MEAN rocks!'\n                        };\n                    };\n\n                    // test expected GET request with response object\n                    $httpBackend.expectGET(/articles\\/([0-9a-fA-F]{24})$/).respond(testArticleData());\n\n                    // run controller\n                    scope.findOne();\n                    $httpBackend.flush();\n\n                    // test scope value\n                    expect(scope.article).toEqualData(testArticleData());\n\n                });\n\n            it('$scope.create() with valid form data should send a POST request ' +\n                'with the form input values and then ' +\n                'locate to new object URL', function() {\n\n                    // fixture expected POST data\n                    var postArticleData = function() {\n                        return {\n                            title: 'An Article about MEAN',\n                            content: 'MEAN rocks!'\n                        };\n                    };\n\n                    // fixture expected response data\n                    var responseArticleData = function() {\n                        return {\n                            _id: '525cf20451979dea2c000001',\n                            title: 'An Article about MEAN',\n                            content: 'MEAN rocks!'\n                        };\n                    };\n\n                    // fixture mock form input values\n                    scope.title = 'An Article about MEAN';\n                    scope.content = 'MEAN rocks!';\n\n                    // test post request is sent\n                    $httpBackend.expectPOST('articles', postArticleData()).respond(responseArticleData());\n\n                    // Run controller\n                    scope.create();\n                    $httpBackend.flush();\n\n                    // test form input(s) are reset\n                    expect(scope.title).toEqual('');\n                    expect(scope.content).toEqual('');\n\n                    // test URL location to new object\n                    expect($location.path()).toBe('/articles/' + responseArticleData()._id);\n                });\n\n            it('$scope.update() should update a valid article', inject(function(Articles) {\n\n                // fixture rideshare\n                var putArticleData = function() {\n                    return {\n                        _id: '525a8422f6d0f87f0e407a33',\n                        title: 'An Article about MEAN',\n                        to: 'MEAN is great!'\n                    };\n                };\n\n                // mock article object from form\n                var article = new Articles(putArticleData());\n\n                // mock article in scope\n                scope.article = article;\n\n                // test PUT happens correctly\n                $httpBackend.expectPUT(/articles\\/([0-9a-fA-F]{24})$/).respond();\n\n                // testing the body data is out for now until an idea for testing the dynamic updated array value is figured out\n                //$httpBackend.expectPUT(/articles\\/([0-9a-fA-F]{24})$/, putArticleData()).respond();\n                /*\n                Error: Expected PUT /articles\\/([0-9a-fA-F]{24})$/ with different data\n                EXPECTED: {\"_id\":\"525a8422f6d0f87f0e407a33\",\"title\":\"An Article about MEAN\",\"to\":\"MEAN is great!\"}\n                GOT:      {\"_id\":\"525a8422f6d0f87f0e407a33\",\"title\":\"An Article about MEAN\",\"to\":\"MEAN is great!\",\"updated\":[1383534772975]}\n                */\n\n                // run controller\n                scope.update();\n                $httpBackend.flush();\n\n                // test URL location to new object\n                expect($location.path()).toBe('/articles/' + putArticleData()._id);\n\n            }));\n\n            it('$scope.remove() should send a DELETE request with a valid articleId' +\n                'and remove the article from the scope', inject(function(Articles) {\n\n                    // fixture rideshare\n                    var article = new Articles({\n                        _id: '525a8422f6d0f87f0e407a33'\n                    });\n\n                    // mock rideshares in scope\n                    scope.articles = [];\n                    scope.articles.push(article);\n\n                    // test expected rideshare DELETE request\n                    $httpBackend.expectDELETE(/articles\\/([0-9a-fA-F]{24})$/).respond(204);\n\n                    // run controller\n                    scope.remove(article);\n                    $httpBackend.flush();\n\n                    // test after successful delete URL location articles lis\n                    //expect($location.path()).toBe('/articles');\n                    expect(scope.articles.length).toBe(0);\n\n                }));\n\n        });\n\n    });\n}());"
  },
  {
    "path": "test/karma/unit/controllers/headers.spec.js",
    "content": "(function() {\n    'use strict';\n\n    describe('MEAN controllers', function() {\n\n        describe('HeaderController', function() {\n\n            // Load the controllers module\n            beforeEach(module('mean'));\n\n            var scope,\n                HeaderController;\n\n            beforeEach(inject(function($controller, $rootScope) {\n                scope = $rootScope.$new();\n\n                HeaderController = $controller('HeaderController', {\n                    $scope: scope\n                });\n            }));\n\n            it('should expose some global scope', function() {\n\n                expect(scope.global).toBeTruthy();\n\n            });\n\n        });\n\n    });\n\n})();"
  },
  {
    "path": "test/karma/unit/controllers/index.spec.js",
    "content": "(function() {\n    'use strict';\n\n    describe('MEAN controllers', function() {\n\n        describe('IndexController', function() {\n\n            // Load the controllers module\n            beforeEach(module('mean'));\n\n            var scope,\n                IndexController;\n\n            beforeEach(inject(function($controller, $rootScope) {\n                scope = $rootScope.$new();\n\n                IndexController = $controller('IndexController', {\n                    $scope: scope\n                });\n            }));\n\n            it('should expose some global scope', function() {\n\n                expect(scope.global).toBeTruthy();\n\n            });\n\n        });\n\n    });\n\n})();"
  },
  {
    "path": "test/mocha/controllers/articleControllerSpec.js",
    "content": "/**\n * Created by Ahmed Hassan on 12/11/15.\n * Set of tests demonstrating how controllers can be tested by stubbing out database dependency\n * The tests are pretty basic, intended for demonstration of technique\n */\n\"use strict\";\n\nvar proxyquire = require('proxyquire').noCallThru(),\n    dbStub = {},\n\n    article = proxyquire('../../../app/controllers/articles', {\n        '../../config/sequelize': dbStub\n    }),\n    chai = require('chai'),\n    Promise = require('sequelize').Promise;\n\nchai.should();\nvar expect = chai.expect;\n\nvar req = {};\nvar res = {};\n\ndescribe('Articles Controller', function () {\n\n    describe('Create Article', function () {\n\n        beforeEach(function () {\n\n            req.user = {id: 1};\n            req.body = {\n                id: 1,\n                title: 'test title',\n                content: 'this is test content to test functionality of Create Article'\n            };\n\n        });\n\n        it('should return article on successful creation', function (done) {\n\n            dbStub.Article = {\n                create: function (obj) {\n                    return Promise.resolve(obj);\n                }\n            };\n\n            res.jsonp = function (article) {\n\n\n                article.should.have.property('id');\n                article.should.have.property('title');\n                article.should.have.property('content');\n                article.should.have.property('UserId');\n                done();\n            };\n\n            article.create(req, res);\n\n        });\n\n        it('should return error if Article could not be created', function (done) {\n\n            dbStub.Article = {\n                create: function (obj) {\n                    return Promise.resolve();\n                }\n            };\n\n            res.send = function (path, err) {\n\n                path.should.equal('users/signup');\n                err.should.have.property('errors');\n\n                done();\n            };\n\n            article.create(req, res);\n\n        });\n\n        it('should return error if error occurs while executing query', function (done) {\n\n            dbStub.Article = {\n                create: function (obj) {\n                    return Promise.reject('error while executing query');\n                }\n            };\n\n            res.send = function (path, err) {\n\n                path.should.equal('users/signup');\n                err.should.have.property('errors');\n                err.should.have.property('status');\n                err.status.should.equal(500);\n\n                done();\n            };\n\n            article.create(req, res);\n\n        });\n\n\n    });\n\n    describe('Update Article', function () {\n\n        beforeEach(function () {\n            req = {\n                article: {\n                    id: 1,\n                    title: 'test title',\n                    content: 'this is test content to test functionality of Create Article',\n                    UserId: 1,\n                    updateAttributes: function () {\n\n                        var updatedArticle = {\n                            id: 1,\n                            title: 'test title updated',\n                            content: 'this is updated test content to test functionality of Create Article',\n                            UserId: 1\n                        };\n\n                        return Promise.resolve(updatedArticle);\n                    }\n\n\n                },\n\n                body: {\n\n                    title: 'test title updated',\n                    content: 'this is updated test content to test functionality of Create Article'\n                }\n\n            }\n\n\n        });\n\n        it('should return updated article on success', function (done) {\n\n\n            res.jsonp = function (updatedArticle) {\n                updatedArticle.should.have.property('id');\n                updatedArticle.should.have.property('title');\n                updatedArticle.title.should.equal('test title updated');\n                updatedArticle.should.have.property('content');\n                updatedArticle.content.should.equal('this is updated test content to test functionality of Create Article');\n                updatedArticle.should.have.property('UserId');\n                done();\n            };\n\n            article.update(req, res);\n\n        });\n\n        it('should return error if error occurs while executing query', function (done) {\n            req.article.updateAttributes = function () {\n                // note: the rejection value here is symbolic,\n                // the key thing is that the same error should be propagated ahead\n                return Promise.reject('error occurred while executing query');\n            };\n\n\n            res.render = function (err, obj) {\n\n\n                err.should.equal('error');\n                obj.should.have.property('error');\n                obj.should.have.property('status');\n                obj.error.should.equal('error occurred while executing query');\n                obj.status.should.equal(500);\n\n                done();\n            };\n\n            article.update(req, res);\n\n        });\n\n    });\n\n\n    describe('Destroy Article', function () {\n\n        beforeEach(function () {\n            req = {\n                article: {\n                    id: 1,\n                    title: 'test title',\n                    content: 'this is test content to test functionality of destroy Article',\n                    UserId: 1,\n                    destroy: function () {\n                        return Promise.resolve();\n                    }\n                }\n            }\n        });\n\n        it('should return destroyed article on successful destroy', function (done) {\n\n            res.jsonp = function (article) {\n\n                article.should.have.property('id');\n                article.should.have.property('title');\n                article.title.should.equal('test title');\n                article.should.have.property('content');\n                article.content.should.equal('this is test content to test functionality of destroy Article');\n                article.should.have.property('UserId');\n                done();\n            };\n\n            article.destroy(req, res);\n\n        });\n\n        it('should return error if error occurs while executing query', function (done) {\n            req.article.destroy = function () {\n                return Promise.reject('error occurred while executing query');\n            };\n\n            res.render = function (err, obj) {\n                err.should.equal('error');\n                obj.should.have.property('error');\n                obj.should.have.property('status');\n                obj.error.should.equal('error occurred while executing query');\n                obj.status.should.equal(500);\n\n                done();\n            };\n\n            article.destroy(req, res);\n\n        });\n\n    });\n\n\n    describe('Fetch all articles', function () {\n\n\n        it('should return the received list of articles on successful query', function (done) {\n\n            dbStub.Article = {\n                findAll: function (obj) {\n                    var Articles = [{\n                        id: 1,\n                        title: 'test',\n                        content: 'this is test content',\n                        UserId: 1\n                    },{\n                        id: 2,\n                        title: 'test',\n                        content: 'this is test content',\n                        UserId: 1\n                    }];\n\n                    return Promise.resolve(Articles);\n                }\n            };\n            dbStub.User = {id: 1};\n\n            res.jsonp = function (articles) {\n                articles[0].should.have.property('id');\n                articles[0].should.have.property('title');\n                articles[0].title.should.equal('test');\n                articles[0].should.have.property('content');\n                articles[0].content.should.equal('this is test content');\n                articles[0].should.have.property('UserId');\n                done();\n            };\n\n            article.all(req, res);\n\n        });\n        it('should return error if error occurs while executing query', function (done) {\n\n            dbStub.Article = {\n                findAll: function (obj) {\n                    return Promise.reject('error occurred while executing query');\n                }\n            };\n            dbStub.User = {id: 1};\n\n            res.render = function (err, obj) {\n                err.should.equal('error');\n                obj.should.have.property('error');\n                obj.should.have.property('status');\n                obj.error.should.equal('error occurred while executing query');\n                obj.status.should.equal(500);\n\n                done();\n            };\n\n            article.all(req, res);\n\n        });\n\n    });\n\n    describe('Has Authorization', function () {\n\n\n        it('should give error if user is not authorized', function (done) {\n\n            req = {\n                article: {\n                    User: {\n                        id: 1\n                    }\n                },\n                user: {\n                    id: 2\n                }\n\n            },\n            res.send = function (httpStatus, msg) {\n\n\n                httpStatus.should.equal(401);\n                msg.should.equal('User is not authorized');\n\n                done();\n            };\n\n            article.hasAuthorization(req, res);\n\n        });\n\n    });\n\n\n});\n"
  },
  {
    "path": "test/mocha/controllers/usersControllerSpec.js",
    "content": "'use strict';\n\n/* Users controller tests */"
  },
  {
    "path": "test/mocha/models/userModelSpec.js",
    "content": "'use strict';\n\n/**\n * Module dependencies.\n */\nvar chai = require('chai'),\n    expect = chai.expect,\n    _ = require('lodash'),\n    winston = require('../../../config/winston'),\n    User = require('../../../app/models/user');\n\nchai.should();\n\n//The tests\ndescribe('User model', function() {\n\n    var userModel;\n    before(function() {\n\n        var sequelizeStub = {\n            define: function(modelName, fields, properties){\n                return {\n                    name : modelName,\n                    fields: fields,\n                    properties: properties\n                };\n            }\n        };\n\n        var datatypesStub = {\n            STRING: 'string',\n            INTEGER: 'integer'\n        };\n\n        userModel = User(sequelizeStub, datatypesStub);\n\n    });\n\n    describe('name', function(){\n        it('should be equal to: User', function(){\n            userModel.name.should.equal('User');\n        });\n    });\n\n    describe('data', function() {\n        it('should have username', function() {\n            userModel.fields.username.should.exist.and.equal('string');\n        });\n        it('should have email', function() {\n            userModel.fields.email.should.exist.and.equal('string');\n        });\n        it('should have hashedPassword', function() {\n            userModel.fields.hashedPassword.should.exist.and.equal('string');\n        });\n    });\n\n    describe('properties', function(){\n        describe('instance methods', function(){\n            describe('makeSalt', function(){\n                it('should generate salt of length 16', function(){\n                    var salt = userModel.properties.instanceMethods.makeSalt();\n                    salt.should.be.a('string').with.length(24);\n                });\n            });\n            describe('encryptPassword', function(){\n                it('should return empty if password is undefined', function(){\n                    var encryptedPassword = userModel.properties.instanceMethods.encryptPassword(undefined,'salt');\n                    encryptedPassword.should.be.a('string').with.length(0);\n                });\n                it('should return empty if salt is undefined', function(){\n                    var encryptedPassword = userModel.properties.instanceMethods.encryptPassword('password');\n                    encryptedPassword.should.be.a('string').with.length(0);\n                });\n                it('should return encrypted password if both password and salt are supplied', function(){\n                    var encryptedPassword = userModel.properties.instanceMethods.encryptPassword('password','salt');\n                    encryptedPassword.should.be.a('string').with.length(88);\n                });\n            });\n            describe('authenticate', function(){\n                it('should return true if password is correct', function(){\n                    var authResult = userModel.properties.instanceMethods.authenticate.call({\n                        salt: 'salt',\n                        hashedPassword: userModel.properties.instanceMethods.encryptPassword('password','salt'),\n                        encryptPassword: userModel.properties.instanceMethods.encryptPassword\n                    }, 'password');\n                    authResult.should.equal(true);\n                });\n                it('should return false if password is incorrect', function(){\n                    var authResult = userModel.properties.instanceMethods.authenticate.call({\n                        salt: 'salt',\n                        hashedPassword: userModel.properties.instanceMethods.encryptPassword('password','salt'),\n                        encryptPassword: userModel.properties.instanceMethods.encryptPassword\n                    }, 'NOTpassword');\n                    authResult.should.equal(false);\n                });\n            });\n        });\n    });\n\n    after(function(done) {\n        done();\n    });\n\n});\n"
  }
]