[{"data":1,"prerenderedAt":10432},["ShallowReactive",2],{"article_list_websockets_":3},[4,2745,4416],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"publishDate":11,"tags":12,"excerpt":10,"body":16,"_type":2736,"_id":2737,"_source":2738,"_file":2739,"_stem":2740,"_extension":2741,"author":2742},"/ckeefer/2016-4/djangochannels2","2016-4",false,"","Django Channels: From the Ground Up - Part 2","Last time, we decided to embark on a brave new adventure and give our Django framework a big upgrade with the inclusion of Django Channels. We got just far enough to get the development server running, but while this may be an adequate start, it's better to develop against something like what we intend to deploy, right?","2016-06-15",[13,14,15],"django","python","websockets",{"type":17,"children":18,"toc":2727},"root",[19,52,57,64,69,78,307,315,477,498,504,509,514,593,598,604,616,621,626,631,772,903,916,982,987,1008,1014,1019,1040,1046,1059,1073,1094,1281,1286,1429,1434,1455,1460,1664,1684,1704,1718,1891,1912,1917,2015,2028,2048,2053,2059,2071,2076,2097,2640,2647,2652,2672,2677,2684,2696,2708,2721],{"type":20,"tag":21,"props":22,"children":23},"element","p",{},[24,32,34,42,44,50],{"type":20,"tag":25,"props":26,"children":28},"a",{"href":27},"/search/user:ckeefer/django/channels/",[29],{"type":30,"value":31},"text","Last time",{"type":30,"value":33},", we decided to embark on a brave new adventure and give our Django framework a big upgrade with the inclusion of ",{"type":20,"tag":25,"props":35,"children":39},{"href":36,"rel":37},"https://channels.readthedocs.io/en/latest/index.html",[38],"nofollow",[40],{"type":30,"value":41},"Django Channels",{"type":30,"value":43},". We got just far enough to get the development server running, but while this may be an ",{"type":20,"tag":45,"props":46,"children":47},"em",{},[48],{"type":30,"value":49},"adequate",{"type":30,"value":51}," start, it's better to develop against something like what we intend to deploy, right?",{"type":20,"tag":21,"props":53,"children":54},{},[55],{"type":30,"value":56},"So, let's go the rest of the way and get ready to develop against something that at least resembles a standard production-ready environment with Django Channels.",{"type":20,"tag":58,"props":59,"children":61},"h3",{"id":60},"post-receive-redux",[62],{"type":30,"value":63},"Post-Receive Redux",{"type":20,"tag":21,"props":65,"children":66},{},[67],{"type":30,"value":68},"Since we're transitioning away from the Django development server, we'll want to alter our post-receive scripts to tie into supervisorctl instead. So, let's edit our post-receive script like so:",{"type":20,"tag":21,"props":70,"children":71},{},[72],{"type":20,"tag":73,"props":74,"children":75},"strong",{},[76],{"type":30,"value":77},"Ubuntu (bash) example:",{"type":20,"tag":79,"props":80,"children":84},"pre",{"className":81,"code":82,"language":83,"meta":8,"style":8},"language-bash shiki shiki-themes github-light github-dark","#!/bin/bash\n\nGIT_WORK_TREE=/home/web/www/ git checkout -f\n\nsource /home/web/venv/bin/activate\npushd /home/web/www/\n\n# Install python libs via pip and perform database migrations\npip install --upgrade -r requirements.txt\npython manage.py migrate\n\npopd\ndeactivate\nsupervisorctl restart server_workers\nsupervisorctl restart server_interface\n","bash",[85],{"type":20,"tag":86,"props":87,"children":88},"code",{"__ignoreMap":8},[89,101,111,150,158,172,181,189,198,227,245,253,262,271,290],{"type":20,"tag":90,"props":91,"children":94},"span",{"class":92,"line":93},"line",1,[95],{"type":20,"tag":90,"props":96,"children":98},{"style":97},"--shiki-default:#6A737D;--shiki-dark:#6A737D",[99],{"type":30,"value":100},"#!/bin/bash\n",{"type":20,"tag":90,"props":102,"children":104},{"class":92,"line":103},2,[105],{"type":20,"tag":90,"props":106,"children":108},{"emptyLinePlaceholder":107},true,[109],{"type":30,"value":110},"\n",{"type":20,"tag":90,"props":112,"children":114},{"class":92,"line":113},3,[115,121,127,133,139,144],{"type":20,"tag":90,"props":116,"children":118},{"style":117},"--shiki-default:#24292E;--shiki-dark:#E1E4E8",[119],{"type":30,"value":120},"GIT_WORK_TREE",{"type":20,"tag":90,"props":122,"children":124},{"style":123},"--shiki-default:#D73A49;--shiki-dark:#F97583",[125],{"type":30,"value":126},"=",{"type":20,"tag":90,"props":128,"children":130},{"style":129},"--shiki-default:#032F62;--shiki-dark:#9ECBFF",[131],{"type":30,"value":132},"/home/web/www/",{"type":20,"tag":90,"props":134,"children":136},{"style":135},"--shiki-default:#6F42C1;--shiki-dark:#B392F0",[137],{"type":30,"value":138}," git",{"type":20,"tag":90,"props":140,"children":141},{"style":129},[142],{"type":30,"value":143}," checkout",{"type":20,"tag":90,"props":145,"children":147},{"style":146},"--shiki-default:#005CC5;--shiki-dark:#79B8FF",[148],{"type":30,"value":149}," -f\n",{"type":20,"tag":90,"props":151,"children":153},{"class":92,"line":152},4,[154],{"type":20,"tag":90,"props":155,"children":156},{"emptyLinePlaceholder":107},[157],{"type":30,"value":110},{"type":20,"tag":90,"props":159,"children":161},{"class":92,"line":160},5,[162,167],{"type":20,"tag":90,"props":163,"children":164},{"style":146},[165],{"type":30,"value":166},"source",{"type":20,"tag":90,"props":168,"children":169},{"style":129},[170],{"type":30,"value":171}," /home/web/venv/bin/activate\n",{"type":20,"tag":90,"props":173,"children":175},{"class":92,"line":174},6,[176],{"type":20,"tag":90,"props":177,"children":178},{"style":117},[179],{"type":30,"value":180},"pushd /home/web/www/\n",{"type":20,"tag":90,"props":182,"children":184},{"class":92,"line":183},7,[185],{"type":20,"tag":90,"props":186,"children":187},{"emptyLinePlaceholder":107},[188],{"type":30,"value":110},{"type":20,"tag":90,"props":190,"children":192},{"class":92,"line":191},8,[193],{"type":20,"tag":90,"props":194,"children":195},{"style":97},[196],{"type":30,"value":197},"# Install python libs via pip and perform database migrations\n",{"type":20,"tag":90,"props":199,"children":201},{"class":92,"line":200},9,[202,207,212,217,222],{"type":20,"tag":90,"props":203,"children":204},{"style":135},[205],{"type":30,"value":206},"pip",{"type":20,"tag":90,"props":208,"children":209},{"style":129},[210],{"type":30,"value":211}," install",{"type":20,"tag":90,"props":213,"children":214},{"style":146},[215],{"type":30,"value":216}," --upgrade",{"type":20,"tag":90,"props":218,"children":219},{"style":146},[220],{"type":30,"value":221}," -r",{"type":20,"tag":90,"props":223,"children":224},{"style":129},[225],{"type":30,"value":226}," requirements.txt\n",{"type":20,"tag":90,"props":228,"children":230},{"class":92,"line":229},10,[231,235,240],{"type":20,"tag":90,"props":232,"children":233},{"style":135},[234],{"type":30,"value":14},{"type":20,"tag":90,"props":236,"children":237},{"style":129},[238],{"type":30,"value":239}," manage.py",{"type":20,"tag":90,"props":241,"children":242},{"style":129},[243],{"type":30,"value":244}," migrate\n",{"type":20,"tag":90,"props":246,"children":248},{"class":92,"line":247},11,[249],{"type":20,"tag":90,"props":250,"children":251},{"emptyLinePlaceholder":107},[252],{"type":30,"value":110},{"type":20,"tag":90,"props":254,"children":256},{"class":92,"line":255},12,[257],{"type":20,"tag":90,"props":258,"children":259},{"style":117},[260],{"type":30,"value":261},"popd\n",{"type":20,"tag":90,"props":263,"children":265},{"class":92,"line":264},13,[266],{"type":20,"tag":90,"props":267,"children":268},{"style":135},[269],{"type":30,"value":270},"deactivate\n",{"type":20,"tag":90,"props":272,"children":274},{"class":92,"line":273},14,[275,280,285],{"type":20,"tag":90,"props":276,"children":277},{"style":135},[278],{"type":30,"value":279},"supervisorctl",{"type":20,"tag":90,"props":281,"children":282},{"style":129},[283],{"type":30,"value":284}," restart",{"type":20,"tag":90,"props":286,"children":287},{"style":129},[288],{"type":30,"value":289}," server_workers\n",{"type":20,"tag":90,"props":291,"children":293},{"class":92,"line":292},15,[294,298,302],{"type":20,"tag":90,"props":295,"children":296},{"style":135},[297],{"type":30,"value":279},{"type":20,"tag":90,"props":299,"children":300},{"style":129},[301],{"type":30,"value":284},{"type":20,"tag":90,"props":303,"children":304},{"style":129},[305],{"type":30,"value":306}," server_interface\n",{"type":20,"tag":21,"props":308,"children":309},{},[310],{"type":20,"tag":73,"props":311,"children":312},{},[313],{"type":30,"value":314},"FreeBSD (csh) example:",{"type":20,"tag":79,"props":316,"children":318},{"className":81,"code":317,"language":83,"meta":8,"style":8},"#!/bin/csh\n\nenv GIT_WORK_TREE=/home/web/www/ git checkout -f\nsource /home/web/venv/bin/activate.csh\npushd /home/web/www/\n\npip install --upgrade -r requirements.txt\npython manage.py migrate\n\npopd\ndeactivate\nsupervisorctl restart server_workers\nsupervisorctl restart server_interface\n",[319],{"type":20,"tag":86,"props":320,"children":321},{"__ignoreMap":8},[322,330,337,362,374,381,388,411,426,433,440,447,462],{"type":20,"tag":90,"props":323,"children":324},{"class":92,"line":93},[325],{"type":20,"tag":90,"props":326,"children":327},{"style":97},[328],{"type":30,"value":329},"#!/bin/csh\n",{"type":20,"tag":90,"props":331,"children":332},{"class":92,"line":103},[333],{"type":20,"tag":90,"props":334,"children":335},{"emptyLinePlaceholder":107},[336],{"type":30,"value":110},{"type":20,"tag":90,"props":338,"children":339},{"class":92,"line":113},[340,345,350,354,358],{"type":20,"tag":90,"props":341,"children":342},{"style":135},[343],{"type":30,"value":344},"env",{"type":20,"tag":90,"props":346,"children":347},{"style":129},[348],{"type":30,"value":349}," GIT_WORK_TREE=/home/web/www/",{"type":20,"tag":90,"props":351,"children":352},{"style":129},[353],{"type":30,"value":138},{"type":20,"tag":90,"props":355,"children":356},{"style":129},[357],{"type":30,"value":143},{"type":20,"tag":90,"props":359,"children":360},{"style":146},[361],{"type":30,"value":149},{"type":20,"tag":90,"props":363,"children":364},{"class":92,"line":152},[365,369],{"type":20,"tag":90,"props":366,"children":367},{"style":146},[368],{"type":30,"value":166},{"type":20,"tag":90,"props":370,"children":371},{"style":129},[372],{"type":30,"value":373}," /home/web/venv/bin/activate.csh\n",{"type":20,"tag":90,"props":375,"children":376},{"class":92,"line":160},[377],{"type":20,"tag":90,"props":378,"children":379},{"style":117},[380],{"type":30,"value":180},{"type":20,"tag":90,"props":382,"children":383},{"class":92,"line":174},[384],{"type":20,"tag":90,"props":385,"children":386},{"emptyLinePlaceholder":107},[387],{"type":30,"value":110},{"type":20,"tag":90,"props":389,"children":390},{"class":92,"line":183},[391,395,399,403,407],{"type":20,"tag":90,"props":392,"children":393},{"style":135},[394],{"type":30,"value":206},{"type":20,"tag":90,"props":396,"children":397},{"style":129},[398],{"type":30,"value":211},{"type":20,"tag":90,"props":400,"children":401},{"style":146},[402],{"type":30,"value":216},{"type":20,"tag":90,"props":404,"children":405},{"style":146},[406],{"type":30,"value":221},{"type":20,"tag":90,"props":408,"children":409},{"style":129},[410],{"type":30,"value":226},{"type":20,"tag":90,"props":412,"children":413},{"class":92,"line":191},[414,418,422],{"type":20,"tag":90,"props":415,"children":416},{"style":135},[417],{"type":30,"value":14},{"type":20,"tag":90,"props":419,"children":420},{"style":129},[421],{"type":30,"value":239},{"type":20,"tag":90,"props":423,"children":424},{"style":129},[425],{"type":30,"value":244},{"type":20,"tag":90,"props":427,"children":428},{"class":92,"line":200},[429],{"type":20,"tag":90,"props":430,"children":431},{"emptyLinePlaceholder":107},[432],{"type":30,"value":110},{"type":20,"tag":90,"props":434,"children":435},{"class":92,"line":229},[436],{"type":20,"tag":90,"props":437,"children":438},{"style":117},[439],{"type":30,"value":261},{"type":20,"tag":90,"props":441,"children":442},{"class":92,"line":247},[443],{"type":20,"tag":90,"props":444,"children":445},{"style":135},[446],{"type":30,"value":270},{"type":20,"tag":90,"props":448,"children":449},{"class":92,"line":255},[450,454,458],{"type":20,"tag":90,"props":451,"children":452},{"style":135},[453],{"type":30,"value":279},{"type":20,"tag":90,"props":455,"children":456},{"style":129},[457],{"type":30,"value":284},{"type":20,"tag":90,"props":459,"children":460},{"style":129},[461],{"type":30,"value":289},{"type":20,"tag":90,"props":463,"children":464},{"class":92,"line":264},[465,469,473],{"type":20,"tag":90,"props":466,"children":467},{"style":135},[468],{"type":30,"value":279},{"type":20,"tag":90,"props":470,"children":471},{"style":129},[472],{"type":30,"value":284},{"type":20,"tag":90,"props":474,"children":475},{"style":129},[476],{"type":30,"value":306},{"type":20,"tag":21,"props":478,"children":479},{},[480,482,488,490,496],{"type":30,"value":481},"We can also work in things like running ",{"type":20,"tag":86,"props":483,"children":485},{"className":484},[],[486],{"type":30,"value":487},"npm",{"type":30,"value":489}," and ",{"type":20,"tag":86,"props":491,"children":493},{"className":492},[],[494],{"type":30,"value":495},"grunt",{"type":30,"value":497}," in there to build and minify files, or whatever other processes you need to do when pushing new code. This will likely be a little different for every project.",{"type":20,"tag":58,"props":499,"children":501},{"id":500},"postgresql-setup",[502],{"type":30,"value":503},"Postgresql Setup",{"type":20,"tag":21,"props":505,"children":506},{},[507],{"type":30,"value":508},"Now, let's get our main database up and ready for our application. Up to this point, we've been relying on sqlite, which is a good starting place, but no match for a world-class hitter like PostgreSQL.",{"type":20,"tag":21,"props":510,"children":511},{},[512],{"type":30,"value":513},"We'll su in as the standard postgres user, and pass user and database creation commands to psql:",{"type":20,"tag":79,"props":515,"children":517},{"className":81,"code":516,"language":83,"meta":8,"style":8},"vsudo su - postgres \u003C\u003CEOF\necho \"CREATE ROLE web LOGIN ENCRYPTED PASSWORD '';\" | psql\ncreatedb \"your_postgres_db\" --owner \"web\"\necho \"GRANT ALL PRIVILEGES ON DATABASE your_postgres_db TO web\" | psql\nservice postgresql reload\nEOF\n",[518],{"type":20,"tag":86,"props":519,"children":520},{"__ignoreMap":8},[521,554,562,570,578,586],{"type":20,"tag":90,"props":522,"children":523},{"class":92,"line":93},[524,529,534,539,544,549],{"type":20,"tag":90,"props":525,"children":526},{"style":135},[527],{"type":30,"value":528},"vsudo",{"type":20,"tag":90,"props":530,"children":531},{"style":129},[532],{"type":30,"value":533}," su",{"type":20,"tag":90,"props":535,"children":536},{"style":129},[537],{"type":30,"value":538}," -",{"type":20,"tag":90,"props":540,"children":541},{"style":129},[542],{"type":30,"value":543}," postgres",{"type":20,"tag":90,"props":545,"children":546},{"style":123},[547],{"type":30,"value":548}," \u003C\u003C",{"type":20,"tag":90,"props":550,"children":551},{"style":129},[552],{"type":30,"value":553},"EOF\n",{"type":20,"tag":90,"props":555,"children":556},{"class":92,"line":103},[557],{"type":20,"tag":90,"props":558,"children":559},{"style":129},[560],{"type":30,"value":561},"echo \"CREATE ROLE web LOGIN ENCRYPTED PASSWORD '';\" | psql\n",{"type":20,"tag":90,"props":563,"children":564},{"class":92,"line":113},[565],{"type":20,"tag":90,"props":566,"children":567},{"style":129},[568],{"type":30,"value":569},"createdb \"your_postgres_db\" --owner \"web\"\n",{"type":20,"tag":90,"props":571,"children":572},{"class":92,"line":152},[573],{"type":20,"tag":90,"props":574,"children":575},{"style":129},[576],{"type":30,"value":577},"echo \"GRANT ALL PRIVILEGES ON DATABASE your_postgres_db TO web\" | psql\n",{"type":20,"tag":90,"props":579,"children":580},{"class":92,"line":160},[581],{"type":20,"tag":90,"props":582,"children":583},{"style":129},[584],{"type":30,"value":585},"service postgresql reload\n",{"type":20,"tag":90,"props":587,"children":588},{"class":92,"line":174},[589],{"type":20,"tag":90,"props":590,"children":591},{"style":129},[592],{"type":30,"value":553},{"type":20,"tag":21,"props":594,"children":595},{},[596],{"type":30,"value":597},"And we should be good to go.",{"type":20,"tag":58,"props":599,"children":601},{"id":600},"setup-supervisord",[602],{"type":30,"value":603},"Setup Supervisord",{"type":20,"tag":21,"props":605,"children":606},{},[607,609,614],{"type":30,"value":608},"Okay, we're getting closer - now we're going to get supervisor to not only start our programs when it runs, but allow our regular web user to start and stop the programs we're setting up with",{"type":20,"tag":86,"props":610,"children":612},{"className":611},[],[613],{"type":30,"value":279},{"type":30,"value":615},".",{"type":20,"tag":21,"props":617,"children":618},{},[619],{"type":30,"value":620},"Supervisord is an important part of the puzzle, as it will keep our server interface and workers up and running. If workers fail or die - which is certainly a possibility - our interface will simply sit and hang, waiting for workers to hand it something to do. Inversely, nothing going in or out of the workers is going to get back to your users without the interface, so it's important we have something monitoring both of them.",{"type":20,"tag":21,"props":622,"children":623},{},[624],{"type":30,"value":625},"We'll need to open up the supervisord.conf file, or add some new files which will be imported into said conf file - on Ubuntu, for example, we can locate our new conf files at /etc/supervisor/conf.d. On FreeBSD, we might just open up the conf file itself - be careful, the install instruction tell us about /etc/supervisord.conf, but their may also be another conf file at /usr/local/etc/ that overrides it.",{"type":20,"tag":21,"props":627,"children":628},{},[629],{"type":30,"value":630},"Either way, we're going to be adding two new program entries - one for the server workers (which handle the requests in the background) and one for the server interface (which consumes the requests and responses from clients and workers alike).",{"type":20,"tag":79,"props":632,"children":634},{"className":81,"code":633,"language":83,"meta":8,"style":8},"[program:server_workers]\ncommand=/home/web/venv/bin/python /home/web/www/manage.py runworker\ndirectory=/home/web/www/\nuser=web\nautostart=true\nautorestart=true\nredirect_stderr=true\nstopasgroup=true\n",[635],{"type":20,"tag":86,"props":636,"children":637},{"__ignoreMap":8},[638,646,673,690,707,724,740,756],{"type":20,"tag":90,"props":639,"children":640},{"class":92,"line":93},[641],{"type":20,"tag":90,"props":642,"children":643},{"style":117},[644],{"type":30,"value":645},"[program:server_workers]\n",{"type":20,"tag":90,"props":647,"children":648},{"class":92,"line":103},[649,654,658,663,668],{"type":20,"tag":90,"props":650,"children":651},{"style":117},[652],{"type":30,"value":653},"command",{"type":20,"tag":90,"props":655,"children":656},{"style":123},[657],{"type":30,"value":126},{"type":20,"tag":90,"props":659,"children":660},{"style":129},[661],{"type":30,"value":662},"/home/web/venv/bin/python",{"type":20,"tag":90,"props":664,"children":665},{"style":135},[666],{"type":30,"value":667}," /home/web/www/manage.py",{"type":20,"tag":90,"props":669,"children":670},{"style":129},[671],{"type":30,"value":672}," runworker\n",{"type":20,"tag":90,"props":674,"children":675},{"class":92,"line":113},[676,681,685],{"type":20,"tag":90,"props":677,"children":678},{"style":117},[679],{"type":30,"value":680},"directory",{"type":20,"tag":90,"props":682,"children":683},{"style":123},[684],{"type":30,"value":126},{"type":20,"tag":90,"props":686,"children":687},{"style":129},[688],{"type":30,"value":689},"/home/web/www/\n",{"type":20,"tag":90,"props":691,"children":692},{"class":92,"line":152},[693,698,702],{"type":20,"tag":90,"props":694,"children":695},{"style":117},[696],{"type":30,"value":697},"user",{"type":20,"tag":90,"props":699,"children":700},{"style":123},[701],{"type":30,"value":126},{"type":20,"tag":90,"props":703,"children":704},{"style":129},[705],{"type":30,"value":706},"web\n",{"type":20,"tag":90,"props":708,"children":709},{"class":92,"line":160},[710,715,719],{"type":20,"tag":90,"props":711,"children":712},{"style":117},[713],{"type":30,"value":714},"autostart",{"type":20,"tag":90,"props":716,"children":717},{"style":123},[718],{"type":30,"value":126},{"type":20,"tag":90,"props":720,"children":721},{"style":129},[722],{"type":30,"value":723},"true\n",{"type":20,"tag":90,"props":725,"children":726},{"class":92,"line":174},[727,732,736],{"type":20,"tag":90,"props":728,"children":729},{"style":117},[730],{"type":30,"value":731},"autorestart",{"type":20,"tag":90,"props":733,"children":734},{"style":123},[735],{"type":30,"value":126},{"type":20,"tag":90,"props":737,"children":738},{"style":129},[739],{"type":30,"value":723},{"type":20,"tag":90,"props":741,"children":742},{"class":92,"line":183},[743,748,752],{"type":20,"tag":90,"props":744,"children":745},{"style":117},[746],{"type":30,"value":747},"redirect_stderr",{"type":20,"tag":90,"props":749,"children":750},{"style":123},[751],{"type":30,"value":126},{"type":20,"tag":90,"props":753,"children":754},{"style":129},[755],{"type":30,"value":723},{"type":20,"tag":90,"props":757,"children":758},{"class":92,"line":191},[759,764,768],{"type":20,"tag":90,"props":760,"children":761},{"style":117},[762],{"type":30,"value":763},"stopasgroup",{"type":20,"tag":90,"props":765,"children":766},{"style":123},[767],{"type":30,"value":126},{"type":20,"tag":90,"props":769,"children":770},{"style":129},[771],{"type":30,"value":723},{"type":20,"tag":79,"props":773,"children":775},{"className":81,"code":774,"language":83,"meta":8,"style":8},"[program:server_interface]\ncommand=/home/web/venv/bin/daphne -b 127.0.0.1 -p 8000 yourapp.asgi:channel_layer\ndirectory=/home/web/www/\nautostart=true\nautorestart=true\nstopasgroup=true\nuser=web\n",[776],{"type":20,"tag":86,"props":777,"children":778},{"__ignoreMap":8},[779,787,828,843,858,873,888],{"type":20,"tag":90,"props":780,"children":781},{"class":92,"line":93},[782],{"type":20,"tag":90,"props":783,"children":784},{"style":117},[785],{"type":30,"value":786},"[program:server_interface]\n",{"type":20,"tag":90,"props":788,"children":789},{"class":92,"line":103},[790,794,798,803,808,813,818,823],{"type":20,"tag":90,"props":791,"children":792},{"style":117},[793],{"type":30,"value":653},{"type":20,"tag":90,"props":795,"children":796},{"style":123},[797],{"type":30,"value":126},{"type":20,"tag":90,"props":799,"children":800},{"style":129},[801],{"type":30,"value":802},"/home/web/venv/bin/daphne",{"type":20,"tag":90,"props":804,"children":805},{"style":135},[806],{"type":30,"value":807}," -b",{"type":20,"tag":90,"props":809,"children":810},{"style":146},[811],{"type":30,"value":812}," 127.0.0.1",{"type":20,"tag":90,"props":814,"children":815},{"style":146},[816],{"type":30,"value":817}," -p",{"type":20,"tag":90,"props":819,"children":820},{"style":146},[821],{"type":30,"value":822}," 8000",{"type":20,"tag":90,"props":824,"children":825},{"style":129},[826],{"type":30,"value":827}," yourapp.asgi:channel_layer\n",{"type":20,"tag":90,"props":829,"children":830},{"class":92,"line":113},[831,835,839],{"type":20,"tag":90,"props":832,"children":833},{"style":117},[834],{"type":30,"value":680},{"type":20,"tag":90,"props":836,"children":837},{"style":123},[838],{"type":30,"value":126},{"type":20,"tag":90,"props":840,"children":841},{"style":129},[842],{"type":30,"value":689},{"type":20,"tag":90,"props":844,"children":845},{"class":92,"line":152},[846,850,854],{"type":20,"tag":90,"props":847,"children":848},{"style":117},[849],{"type":30,"value":714},{"type":20,"tag":90,"props":851,"children":852},{"style":123},[853],{"type":30,"value":126},{"type":20,"tag":90,"props":855,"children":856},{"style":129},[857],{"type":30,"value":723},{"type":20,"tag":90,"props":859,"children":860},{"class":92,"line":160},[861,865,869],{"type":20,"tag":90,"props":862,"children":863},{"style":117},[864],{"type":30,"value":731},{"type":20,"tag":90,"props":866,"children":867},{"style":123},[868],{"type":30,"value":126},{"type":20,"tag":90,"props":870,"children":871},{"style":129},[872],{"type":30,"value":723},{"type":20,"tag":90,"props":874,"children":875},{"class":92,"line":174},[876,880,884],{"type":20,"tag":90,"props":877,"children":878},{"style":117},[879],{"type":30,"value":763},{"type":20,"tag":90,"props":881,"children":882},{"style":123},[883],{"type":30,"value":126},{"type":20,"tag":90,"props":885,"children":886},{"style":129},[887],{"type":30,"value":723},{"type":20,"tag":90,"props":889,"children":890},{"class":92,"line":183},[891,895,899],{"type":20,"tag":90,"props":892,"children":893},{"style":117},[894],{"type":30,"value":697},{"type":20,"tag":90,"props":896,"children":897},{"style":123},[898],{"type":30,"value":126},{"type":20,"tag":90,"props":900,"children":901},{"style":129},[902],{"type":30,"value":706},{"type":20,"tag":21,"props":904,"children":905},{},[906,908,914],{"type":30,"value":907},"And finally, up near the top of the supervisord.conf file, beneath the ",{"type":20,"tag":86,"props":909,"children":911},{"className":910},[],[912],{"type":30,"value":913},"[unix_http_server]",{"type":30,"value":915}," heading, we need to make a few small changes to allow our web user to start and stop these processes.",{"type":20,"tag":79,"props":917,"children":919},{"className":81,"code":918,"language":83,"meta":8,"style":8},"[unix_http_server]\nfile=/var/run/supervisor/supervisor.sock\nchmod=0770\nchown=nobody:web\n",[920],{"type":20,"tag":86,"props":921,"children":922},{"__ignoreMap":8},[923,931,948,965],{"type":20,"tag":90,"props":924,"children":925},{"class":92,"line":93},[926],{"type":20,"tag":90,"props":927,"children":928},{"style":117},[929],{"type":30,"value":930},"[unix_http_server]\n",{"type":20,"tag":90,"props":932,"children":933},{"class":92,"line":103},[934,939,943],{"type":20,"tag":90,"props":935,"children":936},{"style":117},[937],{"type":30,"value":938},"file",{"type":20,"tag":90,"props":940,"children":941},{"style":123},[942],{"type":30,"value":126},{"type":20,"tag":90,"props":944,"children":945},{"style":129},[946],{"type":30,"value":947},"/var/run/supervisor/supervisor.sock\n",{"type":20,"tag":90,"props":949,"children":950},{"class":92,"line":113},[951,956,960],{"type":20,"tag":90,"props":952,"children":953},{"style":117},[954],{"type":30,"value":955},"chmod",{"type":20,"tag":90,"props":957,"children":958},{"style":123},[959],{"type":30,"value":126},{"type":20,"tag":90,"props":961,"children":962},{"style":129},[963],{"type":30,"value":964},"0770\n",{"type":20,"tag":90,"props":966,"children":967},{"class":92,"line":152},[968,973,977],{"type":20,"tag":90,"props":969,"children":970},{"style":117},[971],{"type":30,"value":972},"chown",{"type":20,"tag":90,"props":974,"children":975},{"style":123},[976],{"type":30,"value":126},{"type":20,"tag":90,"props":978,"children":979},{"style":129},[980],{"type":30,"value":981},"nobody:web\n",{"type":20,"tag":21,"props":983,"children":984},{},[985],{"type":30,"value":986},"and restart the supervisord process.",{"type":20,"tag":21,"props":988,"children":989},{},[990,992,998,1000,1006],{"type":30,"value":991},"You can also opt to add your web user to a group like ",{"type":20,"tag":86,"props":993,"children":995},{"className":994},[],[996],{"type":30,"value":997},"wheel",{"type":30,"value":999},", and then alter the chown line to something like ",{"type":20,"tag":86,"props":1001,"children":1003},{"className":1002},[],[1004],{"type":30,"value":1005},"chown=nobody:wheel",{"type":30,"value":1007},". The key here is simply to make the socket available to the appropriate user group so our web user can interact with it.",{"type":20,"tag":58,"props":1009,"children":1011},{"id":1010},"setup-redis",[1012],{"type":30,"value":1013},"Setup Redis",{"type":20,"tag":21,"props":1015,"children":1016},{},[1017],{"type":30,"value":1018},"Getting Redis up and ready is smooth and easy - in fact, at this point you're already done. See how easy that was?",{"type":20,"tag":21,"props":1020,"children":1021},{},[1022,1024,1030,1032,1038],{"type":30,"value":1023},"If you used the requirements.txt in part 1, you already have the needed ",{"type":20,"tag":86,"props":1025,"children":1027},{"className":1026},[],[1028],{"type":30,"value":1029},"asgi_redis",{"type":30,"value":1031}," package installed in your virtual environment, and the defaults that Redis installs with are fine for us. I do encourage you to take a look through the ",{"type":20,"tag":25,"props":1033,"children":1035},{"href":1034},"redis.io/documentation",[1036],{"type":30,"value":1037},"Redis docs",{"type":30,"value":1039},", however, and configure it as you need.",{"type":20,"tag":58,"props":1041,"children":1043},{"id":1042},"django-setup",[1044],{"type":30,"value":1045},"Django Setup",{"type":20,"tag":21,"props":1047,"children":1048},{},[1049,1051,1057],{"type":30,"value":1050},"If we were to check our supervisord status with ",{"type":20,"tag":86,"props":1052,"children":1054},{"className":1053},[],[1055],{"type":30,"value":1056},"supervisorctl status",{"type":30,"value":1058}," right now, we can expect it will be showing a FATAL error for our server_interface program entry. We need to add some new files to get daphne up and running, and while we're in there we'll make the changes necessary to get Django playing nicely with Postgres as our database and Redis as our channel backend.",{"type":20,"tag":21,"props":1060,"children":1061},{},[1062,1064,1071],{"type":30,"value":1063},"For reference, much of the below can also be found in the ",{"type":20,"tag":25,"props":1065,"children":1068},{"href":1066,"rel":1067},"https://channels.readthedocs.io/en/latest/deploying.html#setting-up-a-channel-backend",[38],[1069],{"type":30,"value":1070},"Channels docs",{"type":30,"value":1072},", with the addition of our postgres details.",{"type":20,"tag":21,"props":1074,"children":1075},{},[1076,1078,1084,1086,1092],{"type":30,"value":1077},"Let's start with PostgreSQL. Open up your ",{"type":20,"tag":86,"props":1079,"children":1081},{"className":1080},[],[1082],{"type":30,"value":1083},"settings.py",{"type":30,"value":1085}," file, and alter the ",{"type":20,"tag":86,"props":1087,"children":1089},{"className":1088},[],[1090],{"type":30,"value":1091},"DATABASES",{"type":30,"value":1093}," dict to the following:",{"type":20,"tag":79,"props":1095,"children":1098},{"className":1096,"code":1097,"language":14,"meta":8,"style":8},"language-python shiki shiki-themes github-light github-dark","DATABASES = {\n'default': {\n'ENGINE': 'django.db.backends.postgresql_psycopg2',\n'NAME': 'your_postgres_db',\n'USER': 'web',\n'PASSWORD': 'your_postgres_pass',\n'HOST': 'localhost',\n'PORT': '', # Empty string == default (5432)\n}\n}\n",[1099],{"type":20,"tag":86,"props":1100,"children":1101},{"__ignoreMap":8},[1102,1119,1132,1155,1176,1197,1218,1239,1266,1274],{"type":20,"tag":90,"props":1103,"children":1104},{"class":92,"line":93},[1105,1109,1114],{"type":20,"tag":90,"props":1106,"children":1107},{"style":146},[1108],{"type":30,"value":1091},{"type":20,"tag":90,"props":1110,"children":1111},{"style":123},[1112],{"type":30,"value":1113}," =",{"type":20,"tag":90,"props":1115,"children":1116},{"style":117},[1117],{"type":30,"value":1118}," {\n",{"type":20,"tag":90,"props":1120,"children":1121},{"class":92,"line":103},[1122,1127],{"type":20,"tag":90,"props":1123,"children":1124},{"style":129},[1125],{"type":30,"value":1126},"'default'",{"type":20,"tag":90,"props":1128,"children":1129},{"style":117},[1130],{"type":30,"value":1131},": {\n",{"type":20,"tag":90,"props":1133,"children":1134},{"class":92,"line":113},[1135,1140,1145,1150],{"type":20,"tag":90,"props":1136,"children":1137},{"style":129},[1138],{"type":30,"value":1139},"'ENGINE'",{"type":20,"tag":90,"props":1141,"children":1142},{"style":117},[1143],{"type":30,"value":1144},": ",{"type":20,"tag":90,"props":1146,"children":1147},{"style":129},[1148],{"type":30,"value":1149},"'django.db.backends.postgresql_psycopg2'",{"type":20,"tag":90,"props":1151,"children":1152},{"style":117},[1153],{"type":30,"value":1154},",\n",{"type":20,"tag":90,"props":1156,"children":1157},{"class":92,"line":152},[1158,1163,1167,1172],{"type":20,"tag":90,"props":1159,"children":1160},{"style":129},[1161],{"type":30,"value":1162},"'NAME'",{"type":20,"tag":90,"props":1164,"children":1165},{"style":117},[1166],{"type":30,"value":1144},{"type":20,"tag":90,"props":1168,"children":1169},{"style":129},[1170],{"type":30,"value":1171},"'your_postgres_db'",{"type":20,"tag":90,"props":1173,"children":1174},{"style":117},[1175],{"type":30,"value":1154},{"type":20,"tag":90,"props":1177,"children":1178},{"class":92,"line":160},[1179,1184,1188,1193],{"type":20,"tag":90,"props":1180,"children":1181},{"style":129},[1182],{"type":30,"value":1183},"'USER'",{"type":20,"tag":90,"props":1185,"children":1186},{"style":117},[1187],{"type":30,"value":1144},{"type":20,"tag":90,"props":1189,"children":1190},{"style":129},[1191],{"type":30,"value":1192},"'web'",{"type":20,"tag":90,"props":1194,"children":1195},{"style":117},[1196],{"type":30,"value":1154},{"type":20,"tag":90,"props":1198,"children":1199},{"class":92,"line":174},[1200,1205,1209,1214],{"type":20,"tag":90,"props":1201,"children":1202},{"style":129},[1203],{"type":30,"value":1204},"'PASSWORD'",{"type":20,"tag":90,"props":1206,"children":1207},{"style":117},[1208],{"type":30,"value":1144},{"type":20,"tag":90,"props":1210,"children":1211},{"style":129},[1212],{"type":30,"value":1213},"'your_postgres_pass'",{"type":20,"tag":90,"props":1215,"children":1216},{"style":117},[1217],{"type":30,"value":1154},{"type":20,"tag":90,"props":1219,"children":1220},{"class":92,"line":183},[1221,1226,1230,1235],{"type":20,"tag":90,"props":1222,"children":1223},{"style":129},[1224],{"type":30,"value":1225},"'HOST'",{"type":20,"tag":90,"props":1227,"children":1228},{"style":117},[1229],{"type":30,"value":1144},{"type":20,"tag":90,"props":1231,"children":1232},{"style":129},[1233],{"type":30,"value":1234},"'localhost'",{"type":20,"tag":90,"props":1236,"children":1237},{"style":117},[1238],{"type":30,"value":1154},{"type":20,"tag":90,"props":1240,"children":1241},{"class":92,"line":191},[1242,1247,1251,1256,1261],{"type":20,"tag":90,"props":1243,"children":1244},{"style":129},[1245],{"type":30,"value":1246},"'PORT'",{"type":20,"tag":90,"props":1248,"children":1249},{"style":117},[1250],{"type":30,"value":1144},{"type":20,"tag":90,"props":1252,"children":1253},{"style":129},[1254],{"type":30,"value":1255},"''",{"type":20,"tag":90,"props":1257,"children":1258},{"style":117},[1259],{"type":30,"value":1260},", ",{"type":20,"tag":90,"props":1262,"children":1263},{"style":97},[1264],{"type":30,"value":1265},"# Empty string == default (5432)\n",{"type":20,"tag":90,"props":1267,"children":1268},{"class":92,"line":200},[1269],{"type":20,"tag":90,"props":1270,"children":1271},{"style":117},[1272],{"type":30,"value":1273},"}\n",{"type":20,"tag":90,"props":1275,"children":1276},{"class":92,"line":229},[1277],{"type":20,"tag":90,"props":1278,"children":1279},{"style":117},[1280],{"type":30,"value":1273},{"type":20,"tag":21,"props":1282,"children":1283},{},[1284],{"type":30,"value":1285},"Now, add the following dict beneath that to setup our redis channel layer:",{"type":20,"tag":79,"props":1287,"children":1289},{"className":1096,"code":1288,"language":14,"meta":8,"style":8},"CHANNEL_LAYERS = {\n\"default\": {\n\"BACKEND\": \"asgi_redis.RedisChannelLayer\",\n\"CONFIG\": {\n\"hosts\": [(\"localhost\", 6379)],\n},\n\"ROUTING\": \"yourapp.routing.channel_routing\",\n},\n}\n",[1290],{"type":20,"tag":86,"props":1291,"children":1292},{"__ignoreMap":8},[1293,1309,1321,1342,1354,1386,1394,1415,1422],{"type":20,"tag":90,"props":1294,"children":1295},{"class":92,"line":93},[1296,1301,1305],{"type":20,"tag":90,"props":1297,"children":1298},{"style":146},[1299],{"type":30,"value":1300},"CHANNEL_LAYERS",{"type":20,"tag":90,"props":1302,"children":1303},{"style":123},[1304],{"type":30,"value":1113},{"type":20,"tag":90,"props":1306,"children":1307},{"style":117},[1308],{"type":30,"value":1118},{"type":20,"tag":90,"props":1310,"children":1311},{"class":92,"line":103},[1312,1317],{"type":20,"tag":90,"props":1313,"children":1314},{"style":129},[1315],{"type":30,"value":1316},"\"default\"",{"type":20,"tag":90,"props":1318,"children":1319},{"style":117},[1320],{"type":30,"value":1131},{"type":20,"tag":90,"props":1322,"children":1323},{"class":92,"line":113},[1324,1329,1333,1338],{"type":20,"tag":90,"props":1325,"children":1326},{"style":129},[1327],{"type":30,"value":1328},"\"BACKEND\"",{"type":20,"tag":90,"props":1330,"children":1331},{"style":117},[1332],{"type":30,"value":1144},{"type":20,"tag":90,"props":1334,"children":1335},{"style":129},[1336],{"type":30,"value":1337},"\"asgi_redis.RedisChannelLayer\"",{"type":20,"tag":90,"props":1339,"children":1340},{"style":117},[1341],{"type":30,"value":1154},{"type":20,"tag":90,"props":1343,"children":1344},{"class":92,"line":152},[1345,1350],{"type":20,"tag":90,"props":1346,"children":1347},{"style":129},[1348],{"type":30,"value":1349},"\"CONFIG\"",{"type":20,"tag":90,"props":1351,"children":1352},{"style":117},[1353],{"type":30,"value":1131},{"type":20,"tag":90,"props":1355,"children":1356},{"class":92,"line":160},[1357,1362,1367,1372,1376,1381],{"type":20,"tag":90,"props":1358,"children":1359},{"style":129},[1360],{"type":30,"value":1361},"\"hosts\"",{"type":20,"tag":90,"props":1363,"children":1364},{"style":117},[1365],{"type":30,"value":1366},": [(",{"type":20,"tag":90,"props":1368,"children":1369},{"style":129},[1370],{"type":30,"value":1371},"\"localhost\"",{"type":20,"tag":90,"props":1373,"children":1374},{"style":117},[1375],{"type":30,"value":1260},{"type":20,"tag":90,"props":1377,"children":1378},{"style":146},[1379],{"type":30,"value":1380},"6379",{"type":20,"tag":90,"props":1382,"children":1383},{"style":117},[1384],{"type":30,"value":1385},")],\n",{"type":20,"tag":90,"props":1387,"children":1388},{"class":92,"line":174},[1389],{"type":20,"tag":90,"props":1390,"children":1391},{"style":117},[1392],{"type":30,"value":1393},"},\n",{"type":20,"tag":90,"props":1395,"children":1396},{"class":92,"line":183},[1397,1402,1406,1411],{"type":20,"tag":90,"props":1398,"children":1399},{"style":129},[1400],{"type":30,"value":1401},"\"ROUTING\"",{"type":20,"tag":90,"props":1403,"children":1404},{"style":117},[1405],{"type":30,"value":1144},{"type":20,"tag":90,"props":1407,"children":1408},{"style":129},[1409],{"type":30,"value":1410},"\"yourapp.routing.channel_routing\"",{"type":20,"tag":90,"props":1412,"children":1413},{"style":117},[1414],{"type":30,"value":1154},{"type":20,"tag":90,"props":1416,"children":1417},{"class":92,"line":191},[1418],{"type":20,"tag":90,"props":1419,"children":1420},{"style":117},[1421],{"type":30,"value":1393},{"type":20,"tag":90,"props":1423,"children":1424},{"class":92,"line":200},[1425],{"type":20,"tag":90,"props":1426,"children":1427},{"style":117},[1428],{"type":30,"value":1273},{"type":20,"tag":21,"props":1430,"children":1431},{},[1432],{"type":30,"value":1433},"By default, channels uses process memory as it's communication channel, which is fine for simple development cases, but obviously can't be shared between processes and is unsuitable for production.",{"type":20,"tag":21,"props":1435,"children":1436},{},[1437,1439,1445,1447,1453],{"type":30,"value":1438},"Notice the \"ROUTING\" component of the above config? That's a reference to the ",{"type":20,"tag":86,"props":1440,"children":1442},{"className":1441},[],[1443],{"type":30,"value":1444},"routing.py",{"type":30,"value":1446}," file we're going to slap into the application directory - it should live next to your ",{"type":20,"tag":86,"props":1448,"children":1450},{"className":1449},[],[1451],{"type":30,"value":1452},"urls.py",{"type":30,"value":1454}," file.",{"type":20,"tag":21,"props":1456,"children":1457},{},[1458],{"type":30,"value":1459},"Here's an example:",{"type":20,"tag":79,"props":1461,"children":1463},{"className":1096,"code":1462,"language":14,"meta":8,"style":8},"from channels.routing import route\nfrom channels.routing import include\n\nfrom yourapp import consumers\n\nhttp_routing = [\nroute('http.request', consumers.index)\n]\n\nstream_routing = [\n\n]\n\nchannel_routing = [\ninclude(stream_routing)\n]\n",[1464],{"type":20,"tag":86,"props":1465,"children":1466},{"__ignoreMap":8},[1467,1490,1510,1517,1538,1545,1562,1580,1588,1595,1611,1618,1625,1632,1648,1656],{"type":20,"tag":90,"props":1468,"children":1469},{"class":92,"line":93},[1470,1475,1480,1485],{"type":20,"tag":90,"props":1471,"children":1472},{"style":123},[1473],{"type":30,"value":1474},"from",{"type":20,"tag":90,"props":1476,"children":1477},{"style":117},[1478],{"type":30,"value":1479}," channels.routing ",{"type":20,"tag":90,"props":1481,"children":1482},{"style":123},[1483],{"type":30,"value":1484},"import",{"type":20,"tag":90,"props":1486,"children":1487},{"style":117},[1488],{"type":30,"value":1489}," route\n",{"type":20,"tag":90,"props":1491,"children":1492},{"class":92,"line":103},[1493,1497,1501,1505],{"type":20,"tag":90,"props":1494,"children":1495},{"style":123},[1496],{"type":30,"value":1474},{"type":20,"tag":90,"props":1498,"children":1499},{"style":117},[1500],{"type":30,"value":1479},{"type":20,"tag":90,"props":1502,"children":1503},{"style":123},[1504],{"type":30,"value":1484},{"type":20,"tag":90,"props":1506,"children":1507},{"style":117},[1508],{"type":30,"value":1509}," include\n",{"type":20,"tag":90,"props":1511,"children":1512},{"class":92,"line":113},[1513],{"type":20,"tag":90,"props":1514,"children":1515},{"emptyLinePlaceholder":107},[1516],{"type":30,"value":110},{"type":20,"tag":90,"props":1518,"children":1519},{"class":92,"line":152},[1520,1524,1529,1533],{"type":20,"tag":90,"props":1521,"children":1522},{"style":123},[1523],{"type":30,"value":1474},{"type":20,"tag":90,"props":1525,"children":1526},{"style":117},[1527],{"type":30,"value":1528}," yourapp ",{"type":20,"tag":90,"props":1530,"children":1531},{"style":123},[1532],{"type":30,"value":1484},{"type":20,"tag":90,"props":1534,"children":1535},{"style":117},[1536],{"type":30,"value":1537}," consumers\n",{"type":20,"tag":90,"props":1539,"children":1540},{"class":92,"line":160},[1541],{"type":20,"tag":90,"props":1542,"children":1543},{"emptyLinePlaceholder":107},[1544],{"type":30,"value":110},{"type":20,"tag":90,"props":1546,"children":1547},{"class":92,"line":174},[1548,1553,1557],{"type":20,"tag":90,"props":1549,"children":1550},{"style":117},[1551],{"type":30,"value":1552},"http_routing ",{"type":20,"tag":90,"props":1554,"children":1555},{"style":123},[1556],{"type":30,"value":126},{"type":20,"tag":90,"props":1558,"children":1559},{"style":117},[1560],{"type":30,"value":1561}," [\n",{"type":20,"tag":90,"props":1563,"children":1564},{"class":92,"line":183},[1565,1570,1575],{"type":20,"tag":90,"props":1566,"children":1567},{"style":117},[1568],{"type":30,"value":1569},"route(",{"type":20,"tag":90,"props":1571,"children":1572},{"style":129},[1573],{"type":30,"value":1574},"'http.request'",{"type":20,"tag":90,"props":1576,"children":1577},{"style":117},[1578],{"type":30,"value":1579},", consumers.index)\n",{"type":20,"tag":90,"props":1581,"children":1582},{"class":92,"line":191},[1583],{"type":20,"tag":90,"props":1584,"children":1585},{"style":117},[1586],{"type":30,"value":1587},"]\n",{"type":20,"tag":90,"props":1589,"children":1590},{"class":92,"line":200},[1591],{"type":20,"tag":90,"props":1592,"children":1593},{"emptyLinePlaceholder":107},[1594],{"type":30,"value":110},{"type":20,"tag":90,"props":1596,"children":1597},{"class":92,"line":229},[1598,1603,1607],{"type":20,"tag":90,"props":1599,"children":1600},{"style":117},[1601],{"type":30,"value":1602},"stream_routing ",{"type":20,"tag":90,"props":1604,"children":1605},{"style":123},[1606],{"type":30,"value":126},{"type":20,"tag":90,"props":1608,"children":1609},{"style":117},[1610],{"type":30,"value":1561},{"type":20,"tag":90,"props":1612,"children":1613},{"class":92,"line":247},[1614],{"type":20,"tag":90,"props":1615,"children":1616},{"emptyLinePlaceholder":107},[1617],{"type":30,"value":110},{"type":20,"tag":90,"props":1619,"children":1620},{"class":92,"line":255},[1621],{"type":20,"tag":90,"props":1622,"children":1623},{"style":117},[1624],{"type":30,"value":1587},{"type":20,"tag":90,"props":1626,"children":1627},{"class":92,"line":264},[1628],{"type":20,"tag":90,"props":1629,"children":1630},{"emptyLinePlaceholder":107},[1631],{"type":30,"value":110},{"type":20,"tag":90,"props":1633,"children":1634},{"class":92,"line":273},[1635,1640,1644],{"type":20,"tag":90,"props":1636,"children":1637},{"style":117},[1638],{"type":30,"value":1639},"channel_routing ",{"type":20,"tag":90,"props":1641,"children":1642},{"style":123},[1643],{"type":30,"value":126},{"type":20,"tag":90,"props":1645,"children":1646},{"style":117},[1647],{"type":30,"value":1561},{"type":20,"tag":90,"props":1649,"children":1650},{"class":92,"line":292},[1651],{"type":20,"tag":90,"props":1652,"children":1653},{"style":117},[1654],{"type":30,"value":1655},"include(stream_routing)\n",{"type":20,"tag":90,"props":1657,"children":1659},{"class":92,"line":1658},16,[1660],{"type":20,"tag":90,"props":1661,"children":1662},{"style":117},[1663],{"type":30,"value":1587},{"type":20,"tag":21,"props":1665,"children":1666},{},[1667,1669,1674,1676,1682],{"type":30,"value":1668},"We'll be fleshing this file out in Part 3, so stay tuned. In the meantime, you can also add urls as normal to ",{"type":20,"tag":86,"props":1670,"children":1672},{"className":1671},[],[1673],{"type":30,"value":1452},{"type":30,"value":1675},", referencing standard views, either in a ",{"type":20,"tag":86,"props":1677,"children":1679},{"className":1678},[],[1680],{"type":30,"value":1681},"views.py",{"type":30,"value":1683}," file, or in a directory - this is all exactly the same as it is in standard Django, without any need for changes to accommodate the new ASGI server.",{"type":20,"tag":21,"props":1685,"children":1686},{},[1687,1689,1694,1696,1702],{"type":30,"value":1688},"Next to the ",{"type":20,"tag":86,"props":1690,"children":1692},{"className":1691},[],[1693],{"type":30,"value":1681},{"type":30,"value":1695}," file in your application, add a new file named ",{"type":20,"tag":86,"props":1697,"children":1699},{"className":1698},[],[1700],{"type":30,"value":1701},"consumers.py",{"type":30,"value":1703},". These consumers will be the callables handling the routing we'll be setting up in routing.py - these are what will enable something like websocket requests and replies, rather than being tied into the standard Django view structure.",{"type":20,"tag":21,"props":1705,"children":1706},{},[1707,1709,1716],{"type":30,"value":1708},"For now, we'll put in a simple example of handling an http request, straight from the ",{"type":20,"tag":25,"props":1710,"children":1713},{"href":1711,"rel":1712},"https://channels.readthedocs.io/en/latest/getting-started.html#first-consumers",[38],[1714],{"type":30,"value":1715},"channels docs",{"type":30,"value":1717},":",{"type":20,"tag":79,"props":1719,"children":1721},{"className":1096,"code":1720,"language":14,"meta":8,"style":8},"from django.http import HttpResponse\nfrom channels.handler import AsgiHandler\n\ndef http_consumer(message):\n# Make standard HTTP response - access ASGI path attribute directly\nresponse = HttpResponse(\"Hello world! You asked for %s\" % message.content['path'])\n# Encode that response into message format (ASGI)\nfor chunk in AsgiHandler.encode_response(response):\nmessage.reply_channel.send(chunk)\n",[1722],{"type":20,"tag":86,"props":1723,"children":1724},{"__ignoreMap":8},[1725,1746,1767,1774,1792,1800,1852,1860,1883],{"type":20,"tag":90,"props":1726,"children":1727},{"class":92,"line":93},[1728,1732,1737,1741],{"type":20,"tag":90,"props":1729,"children":1730},{"style":123},[1731],{"type":30,"value":1474},{"type":20,"tag":90,"props":1733,"children":1734},{"style":117},[1735],{"type":30,"value":1736}," django.http ",{"type":20,"tag":90,"props":1738,"children":1739},{"style":123},[1740],{"type":30,"value":1484},{"type":20,"tag":90,"props":1742,"children":1743},{"style":117},[1744],{"type":30,"value":1745}," HttpResponse\n",{"type":20,"tag":90,"props":1747,"children":1748},{"class":92,"line":103},[1749,1753,1758,1762],{"type":20,"tag":90,"props":1750,"children":1751},{"style":123},[1752],{"type":30,"value":1474},{"type":20,"tag":90,"props":1754,"children":1755},{"style":117},[1756],{"type":30,"value":1757}," channels.handler ",{"type":20,"tag":90,"props":1759,"children":1760},{"style":123},[1761],{"type":30,"value":1484},{"type":20,"tag":90,"props":1763,"children":1764},{"style":117},[1765],{"type":30,"value":1766}," AsgiHandler\n",{"type":20,"tag":90,"props":1768,"children":1769},{"class":92,"line":113},[1770],{"type":20,"tag":90,"props":1771,"children":1772},{"emptyLinePlaceholder":107},[1773],{"type":30,"value":110},{"type":20,"tag":90,"props":1775,"children":1776},{"class":92,"line":152},[1777,1782,1787],{"type":20,"tag":90,"props":1778,"children":1779},{"style":123},[1780],{"type":30,"value":1781},"def",{"type":20,"tag":90,"props":1783,"children":1784},{"style":135},[1785],{"type":30,"value":1786}," http_consumer",{"type":20,"tag":90,"props":1788,"children":1789},{"style":117},[1790],{"type":30,"value":1791},"(message):\n",{"type":20,"tag":90,"props":1793,"children":1794},{"class":92,"line":160},[1795],{"type":20,"tag":90,"props":1796,"children":1797},{"style":97},[1798],{"type":30,"value":1799},"# Make standard HTTP response - access ASGI path attribute directly\n",{"type":20,"tag":90,"props":1801,"children":1802},{"class":92,"line":174},[1803,1808,1812,1817,1822,1827,1832,1837,1842,1847],{"type":20,"tag":90,"props":1804,"children":1805},{"style":117},[1806],{"type":30,"value":1807},"response ",{"type":20,"tag":90,"props":1809,"children":1810},{"style":123},[1811],{"type":30,"value":126},{"type":20,"tag":90,"props":1813,"children":1814},{"style":117},[1815],{"type":30,"value":1816}," HttpResponse(",{"type":20,"tag":90,"props":1818,"children":1819},{"style":129},[1820],{"type":30,"value":1821},"\"Hello world! You asked for ",{"type":20,"tag":90,"props":1823,"children":1824},{"style":146},[1825],{"type":30,"value":1826},"%s",{"type":20,"tag":90,"props":1828,"children":1829},{"style":129},[1830],{"type":30,"value":1831},"\"",{"type":20,"tag":90,"props":1833,"children":1834},{"style":123},[1835],{"type":30,"value":1836}," %",{"type":20,"tag":90,"props":1838,"children":1839},{"style":117},[1840],{"type":30,"value":1841}," message.content[",{"type":20,"tag":90,"props":1843,"children":1844},{"style":129},[1845],{"type":30,"value":1846},"'path'",{"type":20,"tag":90,"props":1848,"children":1849},{"style":117},[1850],{"type":30,"value":1851},"])\n",{"type":20,"tag":90,"props":1853,"children":1854},{"class":92,"line":183},[1855],{"type":20,"tag":90,"props":1856,"children":1857},{"style":97},[1858],{"type":30,"value":1859},"# Encode that response into message format (ASGI)\n",{"type":20,"tag":90,"props":1861,"children":1862},{"class":92,"line":191},[1863,1868,1873,1878],{"type":20,"tag":90,"props":1864,"children":1865},{"style":123},[1866],{"type":30,"value":1867},"for",{"type":20,"tag":90,"props":1869,"children":1870},{"style":117},[1871],{"type":30,"value":1872}," chunk ",{"type":20,"tag":90,"props":1874,"children":1875},{"style":123},[1876],{"type":30,"value":1877},"in",{"type":20,"tag":90,"props":1879,"children":1880},{"style":117},[1881],{"type":30,"value":1882}," AsgiHandler.encode_response(response):\n",{"type":20,"tag":90,"props":1884,"children":1885},{"class":92,"line":200},[1886],{"type":20,"tag":90,"props":1887,"children":1888},{"style":117},[1889],{"type":30,"value":1890},"message.reply_channel.send(chunk)\n",{"type":20,"tag":21,"props":1892,"children":1893},{},[1894,1896,1902,1904,1910],{"type":30,"value":1895},"Finally, we need to create an ",{"type":20,"tag":86,"props":1897,"children":1899},{"className":1898},[],[1900],{"type":30,"value":1901},"asgi.py",{"type":30,"value":1903}," file - this should sit right next to the ",{"type":20,"tag":86,"props":1905,"children":1907},{"className":1906},[],[1908],{"type":30,"value":1909},"wsgi.py",{"type":30,"value":1911}," file that was automatically created for you by Django.",{"type":20,"tag":21,"props":1913,"children":1914},{},[1915],{"type":30,"value":1916},"It's pretty simple:",{"type":20,"tag":79,"props":1918,"children":1920},{"className":1096,"code":1919,"language":14,"meta":8,"style":8},"import os\nfrom channels.asgi import get_channel_layer\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"yourapp.settings\")\n\nchannel_layer = get_channel_layer()\n",[1921],{"type":20,"tag":86,"props":1922,"children":1923},{"__ignoreMap":8},[1924,1936,1957,1964,1991,1998],{"type":20,"tag":90,"props":1925,"children":1926},{"class":92,"line":93},[1927,1931],{"type":20,"tag":90,"props":1928,"children":1929},{"style":123},[1930],{"type":30,"value":1484},{"type":20,"tag":90,"props":1932,"children":1933},{"style":117},[1934],{"type":30,"value":1935}," os\n",{"type":20,"tag":90,"props":1937,"children":1938},{"class":92,"line":103},[1939,1943,1948,1952],{"type":20,"tag":90,"props":1940,"children":1941},{"style":123},[1942],{"type":30,"value":1474},{"type":20,"tag":90,"props":1944,"children":1945},{"style":117},[1946],{"type":30,"value":1947}," channels.asgi ",{"type":20,"tag":90,"props":1949,"children":1950},{"style":123},[1951],{"type":30,"value":1484},{"type":20,"tag":90,"props":1953,"children":1954},{"style":117},[1955],{"type":30,"value":1956}," get_channel_layer\n",{"type":20,"tag":90,"props":1958,"children":1959},{"class":92,"line":113},[1960],{"type":20,"tag":90,"props":1961,"children":1962},{"emptyLinePlaceholder":107},[1963],{"type":30,"value":110},{"type":20,"tag":90,"props":1965,"children":1966},{"class":92,"line":152},[1967,1972,1977,1981,1986],{"type":20,"tag":90,"props":1968,"children":1969},{"style":117},[1970],{"type":30,"value":1971},"os.environ.setdefault(",{"type":20,"tag":90,"props":1973,"children":1974},{"style":129},[1975],{"type":30,"value":1976},"\"DJANGO_SETTINGS_MODULE\"",{"type":20,"tag":90,"props":1978,"children":1979},{"style":117},[1980],{"type":30,"value":1260},{"type":20,"tag":90,"props":1982,"children":1983},{"style":129},[1984],{"type":30,"value":1985},"\"yourapp.settings\"",{"type":20,"tag":90,"props":1987,"children":1988},{"style":117},[1989],{"type":30,"value":1990},")\n",{"type":20,"tag":90,"props":1992,"children":1993},{"class":92,"line":160},[1994],{"type":20,"tag":90,"props":1995,"children":1996},{"emptyLinePlaceholder":107},[1997],{"type":30,"value":110},{"type":20,"tag":90,"props":1999,"children":2000},{"class":92,"line":174},[2001,2006,2010],{"type":20,"tag":90,"props":2002,"children":2003},{"style":117},[2004],{"type":30,"value":2005},"channel_layer ",{"type":20,"tag":90,"props":2007,"children":2008},{"style":123},[2009],{"type":30,"value":126},{"type":20,"tag":90,"props":2011,"children":2012},{"style":117},[2013],{"type":30,"value":2014}," get_channel_layer()\n",{"type":20,"tag":21,"props":2016,"children":2017},{},[2018,2020,2026],{"type":30,"value":2019},"This is the file we're referencing in the supervisord config when we wrote ",{"type":20,"tag":86,"props":2021,"children":2023},{"className":2022},[],[2024],{"type":30,"value":2025},"command=/home/web/venv/bin/daphne -b 127.0.0.1 -p 8000 yourapp.asgi:channel_layer",{"type":30,"value":2027},", so now that it's in place, we have all the pieces in place.",{"type":20,"tag":21,"props":2029,"children":2030},{},[2031,2033,2039,2041,2046],{"type":30,"value":2032},"Restart the supervisord service (",{"type":20,"tag":86,"props":2034,"children":2036},{"className":2035},[],[2037],{"type":30,"value":2038},"service supervisord restart",{"type":30,"value":2040},"), and in a few seconds you should be able to check status (",{"type":20,"tag":86,"props":2042,"children":2044},{"className":2043},[],[2045],{"type":30,"value":1056},{"type":30,"value":2047},") and see both of our program entries up and running!",{"type":20,"tag":21,"props":2049,"children":2050},{},[2051],{"type":30,"value":2052},"Which is great! Give yourself a pat on the back. However, we have one step left. Right now, our interace server is bound to port 8000, which is fine for development, but we need to serve up requests on port 80 in production. Now, we could bind to port 80 instead, but that will require running Daphne with root permissions. Instead, let's borrow the common approach with WSGI servers, and setup a reverse proxy with Nginx.",{"type":20,"tag":58,"props":2054,"children":2056},{"id":2055},"last-step-nginx-setup",[2057],{"type":30,"value":2058},"Last Step - Nginx Setup",{"type":20,"tag":21,"props":2060,"children":2061},{},[2062,2064,2069],{"type":30,"value":2063},"Now, it doesn't ",{"type":20,"tag":45,"props":2065,"children":2066},{},[2067],{"type":30,"value":2068},"have",{"type":30,"value":2070}," to be Nginx - Apache could handle this duty, as could a number of others.",{"type":20,"tag":21,"props":2072,"children":2073},{},[2074],{"type":30,"value":2075},"In the meantime, however, Nginx it is, so let's take a look at the nicely straightforward setup.",{"type":20,"tag":21,"props":2077,"children":2078},{},[2079,2081,2087,2089,2095],{"type":30,"value":2080},"Head to ",{"type":20,"tag":86,"props":2082,"children":2084},{"className":2083},[],[2085],{"type":30,"value":2086},"/etc/nginx/sites-available/",{"type":30,"value":2088}," and create a new, appropriately named file (e.g. ",{"type":20,"tag":86,"props":2090,"children":2092},{"className":2091},[],[2093],{"type":30,"value":2094},"yourapp",{"type":30,"value":2096},"), and edit it to include the following:",{"type":20,"tag":79,"props":2098,"children":2100},{"className":1096,"code":2099,"language":14,"meta":8,"style":8},"# Enable upgrading of connection (and websocket proxying) depending on the\n# presence of the upgrade field in the client request header\nmap \\$http_upgrade \\$connection_upgrade {\ndefault upgrade;\n'' close;\n}\n\n# Create an upstream alias to where we've set daphne to bind to\nupstream yourapp {\nserver 127.0.0.1:8000;\n}\n\nserver {\n\nlisten 80;\n# If you have a domain name, this is where to add it\nserver_name localhost;\n\nlocation / {\n# Pass request to the upstream alias\nproxy_pass http://yourapp;\n\n# Require http version 1.1 to allow for upgrade requests\nproxy_http_version 1.1;\n\n# We want proxy_buffering off for proxying to websockets.\nproxy_buffering off;\n\n# http://en.wikipedia.org/wiki/X-Forwarded-For\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\n# enable this if you use HTTPS:\n# proxy_set_header X-Forwarded-Proto https;\n\n# pass the Host: header from the client for the sake of redirects\nproxy_set_header Host $http_host;\n\n# We've set the Host header, so we don't need Nginx to muddle\n# about with redirects\nproxy_redirect off;\n\n# Depending on the request value, set the Upgrade and\n# connection headers\nproxy_set_header Upgrade $http_upgrade;\n\nproxy_set_header Connection $connection_upgrade;\n}\n}\n",[2101],{"type":20,"tag":86,"props":2102,"children":2103},{"__ignoreMap":8},[2104,2112,2120,2139,2152,2168,2175,2182,2190,2198,2225,2232,2239,2247,2254,2271,2279,2288,2296,2314,2323,2342,2350,2359,2377,2385,2394,2403,2411,2420,2458,2466,2475,2484,2492,2501,2519,2527,2536,2545,2554,2562,2571,2580,2598,2606,2624,2632],{"type":20,"tag":90,"props":2105,"children":2106},{"class":92,"line":93},[2107],{"type":20,"tag":90,"props":2108,"children":2109},{"style":97},[2110],{"type":30,"value":2111},"# Enable upgrading of connection (and websocket proxying) depending on the\n",{"type":20,"tag":90,"props":2113,"children":2114},{"class":92,"line":103},[2115],{"type":20,"tag":90,"props":2116,"children":2117},{"style":97},[2118],{"type":30,"value":2119},"# presence of the upgrade field in the client request header\n",{"type":20,"tag":90,"props":2121,"children":2122},{"class":92,"line":113},[2123,2128,2133],{"type":20,"tag":90,"props":2124,"children":2125},{"style":146},[2126],{"type":30,"value":2127},"map",{"type":20,"tag":90,"props":2129,"children":2130},{"style":117},[2131],{"type":30,"value":2132}," \\",{"type":20,"tag":90,"props":2134,"children":2136},{"style":2135},"--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic",[2137],{"type":30,"value":2138},"$http_upgrade \\$connection_upgrade {\n",{"type":20,"tag":90,"props":2140,"children":2141},{"class":92,"line":152},[2142,2147],{"type":20,"tag":90,"props":2143,"children":2144},{"style":117},[2145],{"type":30,"value":2146},"default upgrade",{"type":20,"tag":90,"props":2148,"children":2149},{"style":2135},[2150],{"type":30,"value":2151},";\n",{"type":20,"tag":90,"props":2153,"children":2154},{"class":92,"line":160},[2155,2159,2164],{"type":20,"tag":90,"props":2156,"children":2157},{"style":129},[2158],{"type":30,"value":1255},{"type":20,"tag":90,"props":2160,"children":2161},{"style":117},[2162],{"type":30,"value":2163}," close",{"type":20,"tag":90,"props":2165,"children":2166},{"style":2135},[2167],{"type":30,"value":2151},{"type":20,"tag":90,"props":2169,"children":2170},{"class":92,"line":174},[2171],{"type":20,"tag":90,"props":2172,"children":2173},{"style":117},[2174],{"type":30,"value":1273},{"type":20,"tag":90,"props":2176,"children":2177},{"class":92,"line":183},[2178],{"type":20,"tag":90,"props":2179,"children":2180},{"emptyLinePlaceholder":107},[2181],{"type":30,"value":110},{"type":20,"tag":90,"props":2183,"children":2184},{"class":92,"line":191},[2185],{"type":20,"tag":90,"props":2186,"children":2187},{"style":97},[2188],{"type":30,"value":2189},"# Create an upstream alias to where we've set daphne to bind to\n",{"type":20,"tag":90,"props":2191,"children":2192},{"class":92,"line":200},[2193],{"type":20,"tag":90,"props":2194,"children":2195},{"style":117},[2196],{"type":30,"value":2197},"upstream yourapp {\n",{"type":20,"tag":90,"props":2199,"children":2200},{"class":92,"line":229},[2201,2206,2211,2216,2221],{"type":20,"tag":90,"props":2202,"children":2203},{"style":117},[2204],{"type":30,"value":2205},"server ",{"type":20,"tag":90,"props":2207,"children":2208},{"style":146},[2209],{"type":30,"value":2210},"127.0",{"type":20,"tag":90,"props":2212,"children":2213},{"style":117},[2214],{"type":30,"value":2215},".0.1:",{"type":20,"tag":90,"props":2217,"children":2218},{"style":146},[2219],{"type":30,"value":2220},"8000",{"type":20,"tag":90,"props":2222,"children":2223},{"style":117},[2224],{"type":30,"value":2151},{"type":20,"tag":90,"props":2226,"children":2227},{"class":92,"line":247},[2228],{"type":20,"tag":90,"props":2229,"children":2230},{"style":117},[2231],{"type":30,"value":1273},{"type":20,"tag":90,"props":2233,"children":2234},{"class":92,"line":255},[2235],{"type":20,"tag":90,"props":2236,"children":2237},{"emptyLinePlaceholder":107},[2238],{"type":30,"value":110},{"type":20,"tag":90,"props":2240,"children":2241},{"class":92,"line":264},[2242],{"type":20,"tag":90,"props":2243,"children":2244},{"style":117},[2245],{"type":30,"value":2246},"server {\n",{"type":20,"tag":90,"props":2248,"children":2249},{"class":92,"line":273},[2250],{"type":20,"tag":90,"props":2251,"children":2252},{"emptyLinePlaceholder":107},[2253],{"type":30,"value":110},{"type":20,"tag":90,"props":2255,"children":2256},{"class":92,"line":292},[2257,2262,2267],{"type":20,"tag":90,"props":2258,"children":2259},{"style":117},[2260],{"type":30,"value":2261},"listen ",{"type":20,"tag":90,"props":2263,"children":2264},{"style":146},[2265],{"type":30,"value":2266},"80",{"type":20,"tag":90,"props":2268,"children":2269},{"style":117},[2270],{"type":30,"value":2151},{"type":20,"tag":90,"props":2272,"children":2273},{"class":92,"line":1658},[2274],{"type":20,"tag":90,"props":2275,"children":2276},{"style":97},[2277],{"type":30,"value":2278},"# If you have a domain name, this is where to add it\n",{"type":20,"tag":90,"props":2280,"children":2282},{"class":92,"line":2281},17,[2283],{"type":20,"tag":90,"props":2284,"children":2285},{"style":117},[2286],{"type":30,"value":2287},"server_name localhost;\n",{"type":20,"tag":90,"props":2289,"children":2291},{"class":92,"line":2290},18,[2292],{"type":20,"tag":90,"props":2293,"children":2294},{"emptyLinePlaceholder":107},[2295],{"type":30,"value":110},{"type":20,"tag":90,"props":2297,"children":2299},{"class":92,"line":2298},19,[2300,2305,2310],{"type":20,"tag":90,"props":2301,"children":2302},{"style":117},[2303],{"type":30,"value":2304},"location ",{"type":20,"tag":90,"props":2306,"children":2307},{"style":123},[2308],{"type":30,"value":2309},"/",{"type":20,"tag":90,"props":2311,"children":2312},{"style":117},[2313],{"type":30,"value":1118},{"type":20,"tag":90,"props":2315,"children":2317},{"class":92,"line":2316},20,[2318],{"type":20,"tag":90,"props":2319,"children":2320},{"style":97},[2321],{"type":30,"value":2322},"# Pass request to the upstream alias\n",{"type":20,"tag":90,"props":2324,"children":2326},{"class":92,"line":2325},21,[2327,2332,2337],{"type":20,"tag":90,"props":2328,"children":2329},{"style":117},[2330],{"type":30,"value":2331},"proxy_pass http:",{"type":20,"tag":90,"props":2333,"children":2334},{"style":123},[2335],{"type":30,"value":2336},"//",{"type":20,"tag":90,"props":2338,"children":2339},{"style":117},[2340],{"type":30,"value":2341},"yourapp;\n",{"type":20,"tag":90,"props":2343,"children":2345},{"class":92,"line":2344},22,[2346],{"type":20,"tag":90,"props":2347,"children":2348},{"emptyLinePlaceholder":107},[2349],{"type":30,"value":110},{"type":20,"tag":90,"props":2351,"children":2353},{"class":92,"line":2352},23,[2354],{"type":20,"tag":90,"props":2355,"children":2356},{"style":97},[2357],{"type":30,"value":2358},"# Require http version 1.1 to allow for upgrade requests\n",{"type":20,"tag":90,"props":2360,"children":2362},{"class":92,"line":2361},24,[2363,2368,2373],{"type":20,"tag":90,"props":2364,"children":2365},{"style":117},[2366],{"type":30,"value":2367},"proxy_http_version ",{"type":20,"tag":90,"props":2369,"children":2370},{"style":146},[2371],{"type":30,"value":2372},"1.1",{"type":20,"tag":90,"props":2374,"children":2375},{"style":117},[2376],{"type":30,"value":2151},{"type":20,"tag":90,"props":2378,"children":2380},{"class":92,"line":2379},25,[2381],{"type":20,"tag":90,"props":2382,"children":2383},{"emptyLinePlaceholder":107},[2384],{"type":30,"value":110},{"type":20,"tag":90,"props":2386,"children":2388},{"class":92,"line":2387},26,[2389],{"type":20,"tag":90,"props":2390,"children":2391},{"style":97},[2392],{"type":30,"value":2393},"# We want proxy_buffering off for proxying to websockets.\n",{"type":20,"tag":90,"props":2395,"children":2397},{"class":92,"line":2396},27,[2398],{"type":20,"tag":90,"props":2399,"children":2400},{"style":117},[2401],{"type":30,"value":2402},"proxy_buffering off;\n",{"type":20,"tag":90,"props":2404,"children":2406},{"class":92,"line":2405},28,[2407],{"type":20,"tag":90,"props":2408,"children":2409},{"emptyLinePlaceholder":107},[2410],{"type":30,"value":110},{"type":20,"tag":90,"props":2412,"children":2414},{"class":92,"line":2413},29,[2415],{"type":20,"tag":90,"props":2416,"children":2417},{"style":97},[2418],{"type":30,"value":2419},"# http://en.wikipedia.org/wiki/X-Forwarded-For\n",{"type":20,"tag":90,"props":2421,"children":2423},{"class":92,"line":2422},30,[2424,2429,2434,2439,2443,2448,2453],{"type":20,"tag":90,"props":2425,"children":2426},{"style":117},[2427],{"type":30,"value":2428},"proxy_set_header X",{"type":20,"tag":90,"props":2430,"children":2431},{"style":123},[2432],{"type":30,"value":2433},"-",{"type":20,"tag":90,"props":2435,"children":2436},{"style":117},[2437],{"type":30,"value":2438},"Forwarded",{"type":20,"tag":90,"props":2440,"children":2441},{"style":123},[2442],{"type":30,"value":2433},{"type":20,"tag":90,"props":2444,"children":2445},{"style":117},[2446],{"type":30,"value":2447},"For ",{"type":20,"tag":90,"props":2449,"children":2450},{"style":2135},[2451],{"type":30,"value":2452},"$",{"type":20,"tag":90,"props":2454,"children":2455},{"style":117},[2456],{"type":30,"value":2457},"proxy_add_x_forwarded_for;\n",{"type":20,"tag":90,"props":2459,"children":2461},{"class":92,"line":2460},31,[2462],{"type":20,"tag":90,"props":2463,"children":2464},{"emptyLinePlaceholder":107},[2465],{"type":30,"value":110},{"type":20,"tag":90,"props":2467,"children":2469},{"class":92,"line":2468},32,[2470],{"type":20,"tag":90,"props":2471,"children":2472},{"style":97},[2473],{"type":30,"value":2474},"# enable this if you use HTTPS:\n",{"type":20,"tag":90,"props":2476,"children":2478},{"class":92,"line":2477},33,[2479],{"type":20,"tag":90,"props":2480,"children":2481},{"style":97},[2482],{"type":30,"value":2483},"# proxy_set_header X-Forwarded-Proto https;\n",{"type":20,"tag":90,"props":2485,"children":2487},{"class":92,"line":2486},34,[2488],{"type":20,"tag":90,"props":2489,"children":2490},{"emptyLinePlaceholder":107},[2491],{"type":30,"value":110},{"type":20,"tag":90,"props":2493,"children":2495},{"class":92,"line":2494},35,[2496],{"type":20,"tag":90,"props":2497,"children":2498},{"style":97},[2499],{"type":30,"value":2500},"# pass the Host: header from the client for the sake of redirects\n",{"type":20,"tag":90,"props":2502,"children":2504},{"class":92,"line":2503},36,[2505,2510,2514],{"type":20,"tag":90,"props":2506,"children":2507},{"style":117},[2508],{"type":30,"value":2509},"proxy_set_header Host ",{"type":20,"tag":90,"props":2511,"children":2512},{"style":2135},[2513],{"type":30,"value":2452},{"type":20,"tag":90,"props":2515,"children":2516},{"style":117},[2517],{"type":30,"value":2518},"http_host;\n",{"type":20,"tag":90,"props":2520,"children":2522},{"class":92,"line":2521},37,[2523],{"type":20,"tag":90,"props":2524,"children":2525},{"emptyLinePlaceholder":107},[2526],{"type":30,"value":110},{"type":20,"tag":90,"props":2528,"children":2530},{"class":92,"line":2529},38,[2531],{"type":20,"tag":90,"props":2532,"children":2533},{"style":97},[2534],{"type":30,"value":2535},"# We've set the Host header, so we don't need Nginx to muddle\n",{"type":20,"tag":90,"props":2537,"children":2539},{"class":92,"line":2538},39,[2540],{"type":20,"tag":90,"props":2541,"children":2542},{"style":97},[2543],{"type":30,"value":2544},"# about with redirects\n",{"type":20,"tag":90,"props":2546,"children":2548},{"class":92,"line":2547},40,[2549],{"type":20,"tag":90,"props":2550,"children":2551},{"style":117},[2552],{"type":30,"value":2553},"proxy_redirect off;\n",{"type":20,"tag":90,"props":2555,"children":2557},{"class":92,"line":2556},41,[2558],{"type":20,"tag":90,"props":2559,"children":2560},{"emptyLinePlaceholder":107},[2561],{"type":30,"value":110},{"type":20,"tag":90,"props":2563,"children":2565},{"class":92,"line":2564},42,[2566],{"type":20,"tag":90,"props":2567,"children":2568},{"style":97},[2569],{"type":30,"value":2570},"# Depending on the request value, set the Upgrade and\n",{"type":20,"tag":90,"props":2572,"children":2574},{"class":92,"line":2573},43,[2575],{"type":20,"tag":90,"props":2576,"children":2577},{"style":97},[2578],{"type":30,"value":2579},"# connection headers\n",{"type":20,"tag":90,"props":2581,"children":2583},{"class":92,"line":2582},44,[2584,2589,2593],{"type":20,"tag":90,"props":2585,"children":2586},{"style":117},[2587],{"type":30,"value":2588},"proxy_set_header Upgrade ",{"type":20,"tag":90,"props":2590,"children":2591},{"style":2135},[2592],{"type":30,"value":2452},{"type":20,"tag":90,"props":2594,"children":2595},{"style":117},[2596],{"type":30,"value":2597},"http_upgrade;\n",{"type":20,"tag":90,"props":2599,"children":2601},{"class":92,"line":2600},45,[2602],{"type":20,"tag":90,"props":2603,"children":2604},{"emptyLinePlaceholder":107},[2605],{"type":30,"value":110},{"type":20,"tag":90,"props":2607,"children":2609},{"class":92,"line":2608},46,[2610,2615,2619],{"type":20,"tag":90,"props":2611,"children":2612},{"style":117},[2613],{"type":30,"value":2614},"proxy_set_header Connection ",{"type":20,"tag":90,"props":2616,"children":2617},{"style":2135},[2618],{"type":30,"value":2452},{"type":20,"tag":90,"props":2620,"children":2621},{"style":117},[2622],{"type":30,"value":2623},"connection_upgrade;\n",{"type":20,"tag":90,"props":2625,"children":2627},{"class":92,"line":2626},47,[2628],{"type":20,"tag":90,"props":2629,"children":2630},{"style":117},[2631],{"type":30,"value":1273},{"type":20,"tag":90,"props":2633,"children":2635},{"class":92,"line":2634},48,[2636],{"type":20,"tag":90,"props":2637,"children":2638},{"style":117},[2639],{"type":30,"value":1273},{"type":20,"tag":2641,"props":2642,"children":2644},"h5",{"id":2643},"freebsd-note",[2645],{"type":30,"value":2646},"FreeBSD note:",{"type":20,"tag":21,"props":2648,"children":2649},{},[2650],{"type":30,"value":2651},"Chances are good that your Nginx conf may be in a directory like /usr/local/etc/nginx - you'll either need to alter it to support imports, or simply edit the file to include the above directives.",{"type":20,"tag":21,"props":2653,"children":2654},{},[2655,2657,2663,2665,2671],{"type":30,"value":2656},"Now, check your config for sanity with ",{"type":20,"tag":86,"props":2658,"children":2660},{"className":2659},[],[2661],{"type":30,"value":2662},"nginx -t",{"type":30,"value":2664}," and, if all is well, restart the nginx service ",{"type":20,"tag":86,"props":2666,"children":2668},{"className":2667},[],[2669],{"type":30,"value":2670},"service nginx restart",{"type":30,"value":615},{"type":20,"tag":21,"props":2673,"children":2674},{},[2675],{"type":30,"value":2676},"Now, push your changes to the server, and navigate to it in your browser. If is all well, you should see the simple message from the http.request consumer you set up. What is this feeling. Is this... joy?",{"type":20,"tag":2678,"props":2679,"children":2681},"h2",{"id":2680},"next-time",[2682],{"type":30,"value":2683},"Next Time",{"type":20,"tag":21,"props":2685,"children":2686},{},[2687,2689,2694],{"type":30,"value":2688},"Well, now, all set up with a stack that wouldn't make a dev-op cry, not bad! It... doesn't really ",{"type":20,"tag":45,"props":2690,"children":2691},{},[2692],{"type":30,"value":2693},"do",{"type":30,"value":2695}," anything yet, though, does it? Next time, we'll be looking at getting some simple websocket communication up and running.",{"type":20,"tag":21,"props":2697,"children":2698},{},[2699,2701,2706],{"type":30,"value":2700},"Not a chat server, though. Everyone does a chat server. Instead, let's try something a little more ambitious - how about real time media from an ",{"type":20,"tag":45,"props":2702,"children":2703},{},[2704],{"type":30,"value":2705},"rtsp stream",{"type":30,"value":2707},", straight into the browser?",{"type":20,"tag":21,"props":2709,"children":2710},{},[2711,2713,2719],{"type":30,"value":2712},"If you're running into any issues with the above, I suggest that a quick question to the good folks at ",{"type":20,"tag":25,"props":2714,"children":2716},{"href":2715},"stackoverflow.com",[2717],{"type":30,"value":2718},"Stack Overflow",{"type":30,"value":2720}," will likely avail you best; and as always, if you notice any mistakes in the article, or just have something to say, the comment section awaits.",{"type":20,"tag":2722,"props":2723,"children":2724},"style",{},[2725],{"type":30,"value":2726},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":8,"searchDepth":113,"depth":113,"links":2728},[2729,2730,2731,2732,2733,2734,2735],{"id":60,"depth":113,"text":63},{"id":500,"depth":113,"text":503},{"id":600,"depth":113,"text":603},{"id":1010,"depth":113,"text":1013},{"id":1042,"depth":113,"text":1045},{"id":2055,"depth":113,"text":2058},{"id":2680,"depth":103,"text":2683},"markdown","content:ckeefer:2016-4:djangochannels2.md","content","ckeefer/2016-4/djangochannels2.md","ckeefer/2016-4/djangochannels2","md",{"user":2743,"name":2744},"ckeefer","Christopher Keefer",{"_path":2746,"_dir":2747,"_draft":7,"_partial":7,"_locale":8,"title":2748,"description":2749,"publishDate":2750,"tags":2751,"excerpt":2749,"body":2752,"_type":2736,"_id":4412,"_source":2738,"_file":4413,"_stem":4414,"_extension":2741,"author":4415},"/ckeefer/2016-3/djangochannels1","2016-3","Django Channels: From the Ground Up - Part 1","You stare mournfully into the mass of code you've inherited. At some point, it's clear, the requirements called for the server to push information to the client, because there's an unholy mix of Server-Side Events, long-polling, hidden iframes and even a Java applet in there, all supporting some level of long-term connectivity with the server. It's almost fascinating in its barely functional hideousness, and you would be inclined to leave well enough alone... except for the new feature specifications you've been assigned, which require the client to be able to send data back to the server in response to the received events, in as close to real-time as you can get.","2016-06-13",[13,14,15],{"type":17,"children":2753,"toc":4399},[2754,2775,2789,2795,2842,2847,2852,2866,2879,2892,2897,2904,2910,2924,2929,2935,2949,2954,2959,2999,3004,3022,3027,3032,3038,3043,3048,3139,3144,3183,3188,3212,3234,3239,3245,3250,3255,3281,3292,3297,3345,3351,3364,3369,3564,3569,3613,3617,3661,3667,3680,3708,3722,3727,3732,3743,3749,3763,3768,3807,3812,3853,3866,3870,4103,4107,4312,4332,4353,4365,4371,4383,4395],{"type":20,"tag":21,"props":2755,"children":2756},{},[2757,2759,2766,2768,2773],{"type":30,"value":2758},"You stare mournfully into the mass of code you've inherited. At some point, it's clear, the requirements called for the server to push information to the client, because there's an unholy mix of ",{"type":20,"tag":25,"props":2760,"children":2763},{"href":2761,"rel":2762},"https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events",[38],[2764],{"type":30,"value":2765},"Server-Side Events",{"type":30,"value":2767},", long-polling, hidden iframes and even a Java applet in there, all supporting some level of long-term connectivity with the server. It's almost fascinating in its barely functional hideousness, and you would be inclined to leave well enough alone... except for the ",{"type":20,"tag":45,"props":2769,"children":2770},{},[2771],{"type":30,"value":2772},"new",{"type":30,"value":2774}," feature specifications you've been assigned, which require the client to be able to send data back to the server in response to the received events, in as close to real-time as you can get.",{"type":20,"tag":21,"props":2776,"children":2777},{},[2778,2780,2787],{"type":30,"value":2779},"It's time for a major overhaul. Only ",{"type":20,"tag":25,"props":2781,"children":2784},{"href":2782,"rel":2783},"https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API",[38],[2785],{"type":30,"value":2786},"Websockets",{"type":30,"value":2788}," can save us now. And, as it so happens, one of your favourite frameworks just added support for real-time, bi-directional communication...",{"type":20,"tag":2678,"props":2790,"children":2792},{"id":2791},"adding-more-batteries",[2793],{"type":30,"value":2794},"Adding More Batteries",{"type":20,"tag":21,"props":2796,"children":2797},{},[2798,2800,2807,2809,2814,2816,2823,2825,2832,2834,2841],{"type":30,"value":2799},"If you've been paying attention to the ",{"type":20,"tag":25,"props":2801,"children":2804},{"href":2802,"rel":2803},"https://www.djangoproject.com/",[38],[2805],{"type":30,"value":2806},"Django",{"type":30,"value":2808}," project, you've probably heard about ",{"type":20,"tag":25,"props":2810,"children":2812},{"href":36,"rel":2811},[38],[2813],{"type":30,"value":41},{"type":30,"value":2815},". A new server gateway interface (",{"type":20,"tag":25,"props":2817,"children":2820},{"href":2818,"rel":2819},"https://channels.readthedocs.io/en/latest/asgi.html",[38],[2821],{"type":30,"value":2822},"ASGI",{"type":30,"value":2824},"), a new server (",{"type":20,"tag":25,"props":2826,"children":2829},{"href":2827,"rel":2828},"https://github.com/andrewgodwin/daphne",[38],[2830],{"type":30,"value":2831},"Daphne",{"type":30,"value":2833},") and, as a result, new functionality - including support for Websockets and (at some near-future point) ",{"type":20,"tag":25,"props":2835,"children":2838},{"href":2836,"rel":2837},"https://en.wikipedia.org/wiki/HTTP/2",[38],[2839],{"type":30,"value":2840},"HTTP2",{"type":30,"value":615},{"type":20,"tag":21,"props":2843,"children":2844},{},[2845],{"type":30,"value":2846},"Support for websockets isn't new - Node.js (and thus, Express, Meteor, Sails, etc.) had them pretty much out of the box, and its event-based model is well suited to them. Even on the Python side of things, if you needed websockets, you could have them - Gevent, Tornado/Cyclone and Twisted had your back, amongst others. In fact, the preferred server for Django Channels, Daphne, is based on Twisted.",{"type":20,"tag":21,"props":2848,"children":2849},{},[2850],{"type":30,"value":2851},"So, the big news here isn't OMG Websockets, but rather Websockets + Django. Pyramid and Flask fans may scoff, but Django's batteries-included approach echoes that of Python itself, and enables some solid work that tends to be easier to maintain than, for instance, the special snowflakes that a large Flask project can end up as (your mileage may vary).",{"type":20,"tag":21,"props":2853,"children":2854},{},[2855,2857,2864],{"type":30,"value":2856},"So, if you're sold on Django, there's good reason to be excited about Channels. Although its inclusion in Django core has been ",{"type":20,"tag":25,"props":2858,"children":2861},{"href":2859,"rel":2860},"https://groups.google.com/d/topic/django-developers/QRd4v7OErT8/discussion",[38],[2862],{"type":30,"value":2863},"deferred",{"type":30,"value":2865}," for now, chances are good that it will see integration with the Django core project at some near-future point, making now a good time to get up to speed.",{"type":20,"tag":21,"props":2867,"children":2868},{},[2869,2871,2877],{"type":30,"value":2870},"For this short series of articles, we'll be looking at doing just that. While the ",{"type":20,"tag":25,"props":2872,"children":2874},{"href":36,"rel":2873},[38],[2875],{"type":30,"value":2876},"Django Channels documentation",{"type":30,"value":2878}," lives up to the high standard set by the core Django documentation, it doesn't spend much time describing what a production-ready setup might look like, or how to achieve it. Additionally, like most tutorials for websockets, it focuses on a simple echo or chat server. We're going to go a step beyond, and take a look at what we need to setup real-time streaming video in the browser.",{"type":20,"tag":21,"props":2880,"children":2881},{},[2882,2884,2890],{"type":30,"value":2883},"For the first two articles, though, we'll focus on how to get our shiny new Django Channels installation up and running. We're going to cover a lot of ground, so we won't be able to focus too closely on the details. If you run into trouble, a quick search might do it for you - if not, I suggest you bring your question to the good people at ",{"type":20,"tag":25,"props":2885,"children":2888},{"href":2886,"rel":2887},"https://stackoverflow.com",[38],[2889],{"type":30,"value":2718},{"type":30,"value":2891},"; and if you note any mistakes in the article, or just have something to say, the comment section below awaits you.",{"type":20,"tag":21,"props":2893,"children":2894},{},[2895],{"type":30,"value":2896},"Let's get started, shall we?",{"type":20,"tag":2898,"props":2899,"children":2901},"h4",{"id":2900},"penguins-or-daemons",[2902],{"type":30,"value":2903},"Penguins or Daemons?",{"type":20,"tag":2641,"props":2905,"children":2907},{"id":2906},"its-true-penguins-are-cuter-and-ive-never-had-to-kill-9-a-penguin",[2908],{"type":30,"value":2909},"It's true, penguins are cuter, and I've never had to kill -9 a penguin.",{"type":20,"tag":21,"props":2911,"children":2912},{},[2913,2915,2922],{"type":30,"value":2914},"One small additional wrinkle to the following documentation is that we're going to add some details for this same setup with ",{"type":20,"tag":25,"props":2916,"children":2919},{"href":2917,"rel":2918},"https://www.freebsd.org/",[38],[2920],{"type":30,"value":2921},"FreeBSD",{"type":30,"value":2923},". I've had some recent projects that have caused me to dip my toes into the BSD pool, and I noticed there's a relative lack of documentation for this sort of thing there, so we're going to help rectify that a little.",{"type":20,"tag":21,"props":2925,"children":2926},{},[2927],{"type":30,"value":2928},"Don't worry if you're planning to use a Linux flavour - in most cases, the instructions are either identical, or the differences will be called out.",{"type":20,"tag":2678,"props":2930,"children":2932},{"id":2931},"from-the-ground-up",[2933],{"type":30,"value":2934},"From the Ground Up",{"type":20,"tag":21,"props":2936,"children":2937},{},[2938,2940,2947],{"type":30,"value":2939},"Assumption: You have a relatively modern unix-like operating system. Windows folks, as ever in server-land, I'm afraid you're on your own (maybe now's a good time to look into ",{"type":20,"tag":25,"props":2941,"children":2944},{"href":2942,"rel":2943},"https://msdn.microsoft.com/en-us/commandline/wsl/about",[38],[2945],{"type":30,"value":2946},"Ubuntu on Windows",{"type":30,"value":2948},"?).",{"type":20,"tag":21,"props":2950,"children":2951},{},[2952],{"type":30,"value":2953},"We're going to be re-treading some ground that is likely very familiar for some of you, so bear with me - we're going to start up from scratch here.",{"type":20,"tag":21,"props":2955,"children":2956},{},[2957],{"type":30,"value":2958},"Now, let's discuss our stack. We're going to go with a set of software that should look familiar to anyone who's set up a basic, fairly production-worthy server with Django:",{"type":20,"tag":2960,"props":2961,"children":2962},"ul",{},[2963,2969,2974,2979,2984,2989,2994],{"type":20,"tag":2964,"props":2965,"children":2966},"li",{},[2967],{"type":30,"value":2968},"Python (2.7+ or 3.4+);",{"type":20,"tag":2964,"props":2970,"children":2971},{},[2972],{"type":30,"value":2973},"Virtualenv;",{"type":20,"tag":2964,"props":2975,"children":2976},{},[2977],{"type":30,"value":2978},"Pip;",{"type":20,"tag":2964,"props":2980,"children":2981},{},[2982],{"type":30,"value":2983},"Nginx;",{"type":20,"tag":2964,"props":2985,"children":2986},{},[2987],{"type":30,"value":2988},"Postgresql;",{"type":20,"tag":2964,"props":2990,"children":2991},{},[2992],{"type":30,"value":2993},"Supervisord;",{"type":20,"tag":2964,"props":2995,"children":2996},{},[2997],{"type":30,"value":2998},"Django (1.8+).",{"type":20,"tag":21,"props":3000,"children":3001},{},[3002],{"type":30,"value":3003},"And adding some new elements to support Channels:",{"type":20,"tag":2960,"props":3005,"children":3006},{},[3007,3012,3017],{"type":20,"tag":2964,"props":3008,"children":3009},{},[3010],{"type":30,"value":3011},"Redis;",{"type":20,"tag":2964,"props":3013,"children":3014},{},[3015],{"type":30,"value":3016},"Daphne;",{"type":20,"tag":2964,"props":3018,"children":3019},{},[3020],{"type":30,"value":3021},"channels.",{"type":20,"tag":21,"props":3023,"children":3024},{},[3025],{"type":30,"value":3026},"Let's go through the setup step-by-step, and discuss the how and, in some cases, the why of our software stack.",{"type":20,"tag":21,"props":3028,"children":3029},{},[3030],{"type":30,"value":3031},"For this first part, we're going to go get us far enough to run Django using our shiny new ASGI server, via the usual development invocation; and in part 2, we'll be getting our stack somewhere approaching production ready.",{"type":20,"tag":58,"props":3033,"children":3035},{"id":3034},"package-installation",[3036],{"type":30,"value":3037},"Package Installation",{"type":20,"tag":21,"props":3039,"children":3040},{},[3041],{"type":30,"value":3042},"This step is nice and straightforward. Ask your friendly neighbourhood package manager for more details.",{"type":20,"tag":21,"props":3044,"children":3045},{},[3046],{"type":30,"value":3047},"Debian/Ubuntu one-liner:",{"type":20,"tag":79,"props":3049,"children":3053},{"className":3050,"code":3051,"language":3052,"meta":8,"style":8},"language-shell shiki shiki-themes github-light github-dark","sudo apt-get -y -q install python python-dev python-pip python-virtualenv libpq-dev postgresql postgresql-contrib nginx supervisor python-software-properties redis-server\n","shell",[3054],{"type":20,"tag":86,"props":3055,"children":3056},{"__ignoreMap":8},[3057],{"type":20,"tag":90,"props":3058,"children":3059},{"class":92,"line":93},[3060,3065,3070,3075,3080,3084,3089,3094,3099,3104,3109,3114,3119,3124,3129,3134],{"type":20,"tag":90,"props":3061,"children":3062},{"style":135},[3063],{"type":30,"value":3064},"sudo",{"type":20,"tag":90,"props":3066,"children":3067},{"style":129},[3068],{"type":30,"value":3069}," apt-get",{"type":20,"tag":90,"props":3071,"children":3072},{"style":146},[3073],{"type":30,"value":3074}," -y",{"type":20,"tag":90,"props":3076,"children":3077},{"style":146},[3078],{"type":30,"value":3079}," -q",{"type":20,"tag":90,"props":3081,"children":3082},{"style":129},[3083],{"type":30,"value":211},{"type":20,"tag":90,"props":3085,"children":3086},{"style":129},[3087],{"type":30,"value":3088}," python",{"type":20,"tag":90,"props":3090,"children":3091},{"style":129},[3092],{"type":30,"value":3093}," python-dev",{"type":20,"tag":90,"props":3095,"children":3096},{"style":129},[3097],{"type":30,"value":3098}," python-pip",{"type":20,"tag":90,"props":3100,"children":3101},{"style":129},[3102],{"type":30,"value":3103}," python-virtualenv",{"type":20,"tag":90,"props":3105,"children":3106},{"style":129},[3107],{"type":30,"value":3108}," libpq-dev",{"type":20,"tag":90,"props":3110,"children":3111},{"style":129},[3112],{"type":30,"value":3113}," postgresql",{"type":20,"tag":90,"props":3115,"children":3116},{"style":129},[3117],{"type":30,"value":3118}," postgresql-contrib",{"type":20,"tag":90,"props":3120,"children":3121},{"style":129},[3122],{"type":30,"value":3123}," nginx",{"type":20,"tag":90,"props":3125,"children":3126},{"style":129},[3127],{"type":30,"value":3128}," supervisor",{"type":20,"tag":90,"props":3130,"children":3131},{"style":129},[3132],{"type":30,"value":3133}," python-software-properties",{"type":20,"tag":90,"props":3135,"children":3136},{"style":129},[3137],{"type":30,"value":3138}," redis-server\n",{"type":20,"tag":21,"props":3140,"children":3141},{},[3142],{"type":30,"value":3143},"FreeBSD example:",{"type":20,"tag":79,"props":3145,"children":3147},{"className":3050,"code":3146,"language":3052,"meta":8,"style":8},"cd /usr/ports/databases/postgresql95-server/ && make install clean\n",[3148],{"type":20,"tag":86,"props":3149,"children":3150},{"__ignoreMap":8},[3151],{"type":20,"tag":90,"props":3152,"children":3153},{"class":92,"line":93},[3154,3159,3164,3169,3174,3178],{"type":20,"tag":90,"props":3155,"children":3156},{"style":146},[3157],{"type":30,"value":3158},"cd",{"type":20,"tag":90,"props":3160,"children":3161},{"style":129},[3162],{"type":30,"value":3163}," /usr/ports/databases/postgresql95-server/",{"type":20,"tag":90,"props":3165,"children":3166},{"style":117},[3167],{"type":30,"value":3168}," && ",{"type":20,"tag":90,"props":3170,"children":3171},{"style":135},[3172],{"type":30,"value":3173},"make",{"type":20,"tag":90,"props":3175,"children":3176},{"style":129},[3177],{"type":30,"value":211},{"type":20,"tag":90,"props":3179,"children":3180},{"style":129},[3181],{"type":30,"value":3182}," clean\n",{"type":20,"tag":21,"props":3184,"children":3185},{},[3186],{"type":30,"value":3187},"OR",{"type":20,"tag":79,"props":3189,"children":3191},{"className":3050,"code":3190,"language":3052,"meta":8,"style":8},"pkg install postgresql95-server\n",[3192],{"type":20,"tag":86,"props":3193,"children":3194},{"__ignoreMap":8},[3195],{"type":20,"tag":90,"props":3196,"children":3197},{"class":92,"line":93},[3198,3203,3207],{"type":20,"tag":90,"props":3199,"children":3200},{"style":135},[3201],{"type":30,"value":3202},"pkg",{"type":20,"tag":90,"props":3204,"children":3205},{"style":129},[3206],{"type":30,"value":211},{"type":20,"tag":90,"props":3208,"children":3209},{"style":129},[3210],{"type":30,"value":3211}," postgresql95-server\n",{"type":20,"tag":21,"props":3213,"children":3214},{},[3215,3217,3223,3225,3232],{"type":30,"value":3216},"and repeat for python27 (e.g. ",{"type":20,"tag":86,"props":3218,"children":3220},{"className":3219},[],[3221],{"type":30,"value":3222},"pkg install python27",{"type":30,"value":3224},"), nginx, supervisord, etc. I suggest searching ",{"type":20,"tag":25,"props":3226,"children":3229},{"href":3227,"rel":3228},"https://www.freshports.org/",[38],[3230],{"type":30,"value":3231},"FreshPorts",{"type":30,"value":3233}," for the specific package names.",{"type":20,"tag":21,"props":3235,"children":3236},{},[3237],{"type":30,"value":3238},"If you're on FreeBSD, you'll also want to add the appropriate enable commands to rc.conf to allow these applications to start with the server.",{"type":20,"tag":58,"props":3240,"children":3242},{"id":3241},"user-virtualenv-setup",[3243],{"type":30,"value":3244},"User & VirtualEnv setup",{"type":20,"tag":21,"props":3246,"children":3247},{},[3248],{"type":30,"value":3249},"Now that we have our system packages installed, let's set up our python virtual environment in preparation for getting our python packages into place.",{"type":20,"tag":21,"props":3251,"children":3252},{},[3253],{"type":30,"value":3254},"First, we'll create a new, low-priviledged user who we want to run our server software - running web-facing processes as root can be a security faux pas.",{"type":20,"tag":21,"props":3256,"children":3257},{},[3258,3264,3266,3271,3273,3279],{"type":20,"tag":86,"props":3259,"children":3261},{"className":3260},[],[3262],{"type":30,"value":3263},"sudo adduser web",{"type":30,"value":3265}," (If using FreeBSD, drop the ",{"type":20,"tag":86,"props":3267,"children":3269},{"className":3268},[],[3270],{"type":30,"value":3064},{"type":30,"value":3272}," and execute this (and other commands requiring sudo) as root by ",{"type":20,"tag":86,"props":3274,"children":3276},{"className":3275},[],[3277],{"type":30,"value":3278},"su",{"type":30,"value":3280},"ing into root account, or else install sudo package).",{"type":20,"tag":21,"props":3282,"children":3283},{},[3284,3286],{"type":30,"value":3285},"Let's su in as this user... ",{"type":20,"tag":86,"props":3287,"children":3289},{"className":3288},[],[3290],{"type":30,"value":3291},"su web",{"type":20,"tag":21,"props":3293,"children":3294},{},[3295],{"type":30,"value":3296},"We're now going to drop our virtualenv directory (and, in a moment, our deploy directory) into this users home dir - we don't have to do it this way, of course, but this avoids some bothersome chmod'ing and chown'ing we'd have to do otherwise.",{"type":20,"tag":79,"props":3298,"children":3300},{"className":81,"code":3299,"language":83,"meta":8,"style":8},"mkdir -p /home/web/venv/\n\nvirtualenv --no-site-packages /home/web/venv/\n",[3301],{"type":20,"tag":86,"props":3302,"children":3303},{"__ignoreMap":8},[3304,3321,3328],{"type":20,"tag":90,"props":3305,"children":3306},{"class":92,"line":93},[3307,3312,3316],{"type":20,"tag":90,"props":3308,"children":3309},{"style":135},[3310],{"type":30,"value":3311},"mkdir",{"type":20,"tag":90,"props":3313,"children":3314},{"style":146},[3315],{"type":30,"value":817},{"type":20,"tag":90,"props":3317,"children":3318},{"style":129},[3319],{"type":30,"value":3320}," /home/web/venv/\n",{"type":20,"tag":90,"props":3322,"children":3323},{"class":92,"line":103},[3324],{"type":20,"tag":90,"props":3325,"children":3326},{"emptyLinePlaceholder":107},[3327],{"type":30,"value":110},{"type":20,"tag":90,"props":3329,"children":3330},{"class":92,"line":113},[3331,3336,3341],{"type":20,"tag":90,"props":3332,"children":3333},{"style":135},[3334],{"type":30,"value":3335},"virtualenv",{"type":20,"tag":90,"props":3337,"children":3338},{"style":146},[3339],{"type":30,"value":3340}," --no-site-packages",{"type":20,"tag":90,"props":3342,"children":3343},{"style":129},[3344],{"type":30,"value":3320},{"type":20,"tag":58,"props":3346,"children":3348},{"id":3347},"python-package-installation",[3349],{"type":30,"value":3350},"Python Package Installation",{"type":20,"tag":21,"props":3352,"children":3353},{},[3354,3356,3363],{"type":30,"value":3355},"Now that we have our virtualenv in place, we can install our python packages via pip. If we follow the git deploy setup, below, these can also be automatically installed/upgraded for us by processing a ",{"type":20,"tag":25,"props":3357,"children":3360},{"href":3358,"rel":3359},"https://pip.readthedocs.io/en/1.1/requirements.html",[38],[3361],{"type":30,"value":3362},"requirements.txt file",{"type":30,"value":615},{"type":20,"tag":21,"props":3365,"children":3366},{},[3367],{"type":30,"value":3368},"Let's make a requirements.txt file that looks like the following:",{"type":20,"tag":79,"props":3370,"children":3372},{"className":3050,"code":3371,"language":3052,"meta":8,"style":8},"asgi-redis==0.12.0\nasgiref==0.13.0\nautobahn==0.14.1\nchannels==0.14.0\ndaphne==0.12.1\nDjango>=1.9,=2.6,\u003C2.7\nredis==2.10.5\nsix==1.10.0\nTwisted==16.2.0\ntxaio==2.5.1\nzope.interface==4.1.3\n",[3373],{"type":20,"tag":86,"props":3374,"children":3375},{"__ignoreMap":8},[3376,3393,3410,3427,3444,3461,3483,3500,3517,3534,3551],{"type":20,"tag":90,"props":3377,"children":3378},{"class":92,"line":93},[3379,3384,3388],{"type":20,"tag":90,"props":3380,"children":3381},{"style":117},[3382],{"type":30,"value":3383},"asgi-redis",{"type":20,"tag":90,"props":3385,"children":3386},{"style":123},[3387],{"type":30,"value":126},{"type":20,"tag":90,"props":3389,"children":3390},{"style":129},[3391],{"type":30,"value":3392},"=0.12.0\n",{"type":20,"tag":90,"props":3394,"children":3395},{"class":92,"line":103},[3396,3401,3405],{"type":20,"tag":90,"props":3397,"children":3398},{"style":117},[3399],{"type":30,"value":3400},"asgiref",{"type":20,"tag":90,"props":3402,"children":3403},{"style":123},[3404],{"type":30,"value":126},{"type":20,"tag":90,"props":3406,"children":3407},{"style":129},[3408],{"type":30,"value":3409},"=0.13.0\n",{"type":20,"tag":90,"props":3411,"children":3412},{"class":92,"line":113},[3413,3418,3422],{"type":20,"tag":90,"props":3414,"children":3415},{"style":117},[3416],{"type":30,"value":3417},"autobahn",{"type":20,"tag":90,"props":3419,"children":3420},{"style":123},[3421],{"type":30,"value":126},{"type":20,"tag":90,"props":3423,"children":3424},{"style":129},[3425],{"type":30,"value":3426},"=0.14.1\n",{"type":20,"tag":90,"props":3428,"children":3429},{"class":92,"line":152},[3430,3435,3439],{"type":20,"tag":90,"props":3431,"children":3432},{"style":117},[3433],{"type":30,"value":3434},"channels",{"type":20,"tag":90,"props":3436,"children":3437},{"style":123},[3438],{"type":30,"value":126},{"type":20,"tag":90,"props":3440,"children":3441},{"style":129},[3442],{"type":30,"value":3443},"=0.14.0\n",{"type":20,"tag":90,"props":3445,"children":3446},{"class":92,"line":160},[3447,3452,3456],{"type":20,"tag":90,"props":3448,"children":3449},{"style":117},[3450],{"type":30,"value":3451},"daphne",{"type":20,"tag":90,"props":3453,"children":3454},{"style":123},[3455],{"type":30,"value":126},{"type":20,"tag":90,"props":3457,"children":3458},{"style":129},[3459],{"type":30,"value":3460},"=0.12.1\n",{"type":20,"tag":90,"props":3462,"children":3463},{"class":92,"line":174},[3464,3468,3473,3478],{"type":20,"tag":90,"props":3465,"children":3466},{"style":135},[3467],{"type":30,"value":2806},{"type":20,"tag":90,"props":3469,"children":3470},{"style":117},[3471],{"type":30,"value":3472},">",{"type":20,"tag":90,"props":3474,"children":3475},{"style":129},[3476],{"type":30,"value":3477},"=1.9,=2.6,",{"type":20,"tag":90,"props":3479,"children":3480},{"style":117},[3481],{"type":30,"value":3482},"\u003C2.7\n",{"type":20,"tag":90,"props":3484,"children":3485},{"class":92,"line":183},[3486,3491,3495],{"type":20,"tag":90,"props":3487,"children":3488},{"style":117},[3489],{"type":30,"value":3490},"redis",{"type":20,"tag":90,"props":3492,"children":3493},{"style":123},[3494],{"type":30,"value":126},{"type":20,"tag":90,"props":3496,"children":3497},{"style":129},[3498],{"type":30,"value":3499},"=2.10.5\n",{"type":20,"tag":90,"props":3501,"children":3502},{"class":92,"line":191},[3503,3508,3512],{"type":20,"tag":90,"props":3504,"children":3505},{"style":117},[3506],{"type":30,"value":3507},"six",{"type":20,"tag":90,"props":3509,"children":3510},{"style":123},[3511],{"type":30,"value":126},{"type":20,"tag":90,"props":3513,"children":3514},{"style":129},[3515],{"type":30,"value":3516},"=1.10.0\n",{"type":20,"tag":90,"props":3518,"children":3519},{"class":92,"line":200},[3520,3525,3529],{"type":20,"tag":90,"props":3521,"children":3522},{"style":117},[3523],{"type":30,"value":3524},"Twisted",{"type":20,"tag":90,"props":3526,"children":3527},{"style":123},[3528],{"type":30,"value":126},{"type":20,"tag":90,"props":3530,"children":3531},{"style":129},[3532],{"type":30,"value":3533},"=16.2.0\n",{"type":20,"tag":90,"props":3535,"children":3536},{"class":92,"line":229},[3537,3542,3546],{"type":20,"tag":90,"props":3538,"children":3539},{"style":117},[3540],{"type":30,"value":3541},"txaio",{"type":20,"tag":90,"props":3543,"children":3544},{"style":123},[3545],{"type":30,"value":126},{"type":20,"tag":90,"props":3547,"children":3548},{"style":129},[3549],{"type":30,"value":3550},"=2.5.1\n",{"type":20,"tag":90,"props":3552,"children":3553},{"class":92,"line":247},[3554,3559],{"type":20,"tag":90,"props":3555,"children":3556},{"style":135},[3557],{"type":30,"value":3558},"zope.interface",{"type":20,"tag":90,"props":3560,"children":3561},{"style":129},[3562],{"type":30,"value":3563},"==4.1.3\n",{"type":20,"tag":21,"props":3565,"children":3566},{},[3567],{"type":30,"value":3568},"Now, we can activate the virtual environment and install these requirements with pip like so:",{"type":20,"tag":79,"props":3570,"children":3572},{"className":3050,"code":3571,"language":3052,"meta":8,"style":8},"source /home/web/venv/bin/activate\npip install -r requirements.txt\ndeactivate\n",[3573],{"type":20,"tag":86,"props":3574,"children":3575},{"__ignoreMap":8},[3576,3587,3606],{"type":20,"tag":90,"props":3577,"children":3578},{"class":92,"line":93},[3579,3583],{"type":20,"tag":90,"props":3580,"children":3581},{"style":146},[3582],{"type":30,"value":166},{"type":20,"tag":90,"props":3584,"children":3585},{"style":129},[3586],{"type":30,"value":171},{"type":20,"tag":90,"props":3588,"children":3589},{"class":92,"line":103},[3590,3594,3598,3602],{"type":20,"tag":90,"props":3591,"children":3592},{"style":135},[3593],{"type":30,"value":206},{"type":20,"tag":90,"props":3595,"children":3596},{"style":129},[3597],{"type":30,"value":211},{"type":20,"tag":90,"props":3599,"children":3600},{"style":146},[3601],{"type":30,"value":221},{"type":20,"tag":90,"props":3603,"children":3604},{"style":129},[3605],{"type":30,"value":226},{"type":20,"tag":90,"props":3607,"children":3608},{"class":92,"line":113},[3609],{"type":20,"tag":90,"props":3610,"children":3611},{"style":135},[3612],{"type":30,"value":270},{"type":20,"tag":21,"props":3614,"children":3615},{},[3616],{"type":30,"value":314},{"type":20,"tag":79,"props":3618,"children":3620},{"className":3050,"code":3619,"language":3052,"meta":8,"style":8},"source /home/web/venv/bin/activate.csh\npip install -r requirements.txt\ndeactivate\n",[3621],{"type":20,"tag":86,"props":3622,"children":3623},{"__ignoreMap":8},[3624,3635,3654],{"type":20,"tag":90,"props":3625,"children":3626},{"class":92,"line":93},[3627,3631],{"type":20,"tag":90,"props":3628,"children":3629},{"style":146},[3630],{"type":30,"value":166},{"type":20,"tag":90,"props":3632,"children":3633},{"style":129},[3634],{"type":30,"value":373},{"type":20,"tag":90,"props":3636,"children":3637},{"class":92,"line":103},[3638,3642,3646,3650],{"type":20,"tag":90,"props":3639,"children":3640},{"style":135},[3641],{"type":30,"value":206},{"type":20,"tag":90,"props":3643,"children":3644},{"style":129},[3645],{"type":30,"value":211},{"type":20,"tag":90,"props":3647,"children":3648},{"style":146},[3649],{"type":30,"value":221},{"type":20,"tag":90,"props":3651,"children":3652},{"style":129},[3653],{"type":30,"value":226},{"type":20,"tag":90,"props":3655,"children":3656},{"class":92,"line":113},[3657],{"type":20,"tag":90,"props":3658,"children":3659},{"style":135},[3660],{"type":30,"value":270},{"type":20,"tag":58,"props":3662,"children":3664},{"id":3663},"django-project-setup",[3665],{"type":30,"value":3666},"Django Project Setup",{"type":20,"tag":21,"props":3668,"children":3669},{},[3670,3672,3679],{"type":30,"value":3671},"Now, we're going to get a bare minimal Django project structure in place. Thankfully, Django has some built-in ability to generate it's own boilerplate, which we'll take advantage of. For this, I refer you to the ",{"type":20,"tag":25,"props":3673,"children":3676},{"href":3674,"rel":3675},"https://docs.djangoproject.com/en/1.9/intro/tutorial01/#creating-a-project",[38],[3677],{"type":30,"value":3678},"official Django docs",{"type":30,"value":615},{"type":20,"tag":21,"props":3681,"children":3682},{},[3683,3685,3690,3692,3698,3700,3706],{"type":30,"value":3684},"For our purposes, the only file of interest is ",{"type":20,"tag":86,"props":3686,"children":3688},{"className":3687},[],[3689],{"type":30,"value":1083},{"type":30,"value":3691}," in your app directory. Open that up in your favourite editor, and find the ",{"type":20,"tag":86,"props":3693,"children":3695},{"className":3694},[],[3696],{"type":30,"value":3697},"INSTALLED_APPS",{"type":30,"value":3699}," tuple. Installing channels into Django is as simple as adding ",{"type":20,"tag":86,"props":3701,"children":3703},{"className":3702},[],[3704],{"type":30,"value":3705},"'channels'",{"type":30,"value":3707}," to the end of the tuple.",{"type":20,"tag":21,"props":3709,"children":3710},{},[3711,3713,3720],{"type":30,"value":3712},"You may also need/want to add your 'app_name' to this tuple, especially if you need static file discovery. You can take a look at the ",{"type":20,"tag":25,"props":3714,"children":3717},{"href":3715,"rel":3716},"https://channels.readthedocs.io/en/latest/installation.html",[38],[3718],{"type":30,"value":3719},"Channels Installation",{"type":30,"value":3721}," documentation for a little more detail here, but it's nicely straightforward.",{"type":20,"tag":21,"props":3723,"children":3724},{},[3725],{"type":30,"value":3726},"You should also copy that requirements.txt file we made earlier into the root of your app directory. If nothing else, it serves as a reference as to what packages you're using.",{"type":20,"tag":2641,"props":3728,"children":3729},{"id":2643},[3730],{"type":30,"value":3731},"FreeBSD Note:",{"type":20,"tag":21,"props":3733,"children":3734},{},[3735,3737],{"type":30,"value":3736},"At this point we'll be relying on SQLite to provide our database solution - in many distributions, this is built-in to Python, but on FreeBSD we'll also need to install the py-sqlite3 package: ",{"type":20,"tag":86,"props":3738,"children":3740},{"className":3739},[],[3741],{"type":30,"value":3742},"pkg install py27-sqlite3",{"type":20,"tag":58,"props":3744,"children":3746},{"id":3745},"deploy-setup-optional",[3747],{"type":30,"value":3748},"Deploy Setup [Optional]",{"type":20,"tag":21,"props":3750,"children":3751},{},[3752,3754,3761],{"type":30,"value":3753},"This step is purely optional, but I like it as an easy way to ",{"type":20,"tag":25,"props":3755,"children":3758},{"href":3756,"rel":3757},"https://artandlogic.com/2013/12/deploying-websites-with-git/",[38],[3759],{"type":30,"value":3760},"deploy via git push",{"type":30,"value":3762},". That link has more info, so we'll just sketch out the implementation here:",{"type":20,"tag":21,"props":3764,"children":3765},{},[3766],{"type":30,"value":3767},"Make the necessary directories:",{"type":20,"tag":79,"props":3769,"children":3771},{"className":3050,"code":3770,"language":3052,"meta":8,"style":8},"mkdir -p /home/web/www.git/\nmkdir -p /home/web/www/\n",[3772],{"type":20,"tag":86,"props":3773,"children":3774},{"__ignoreMap":8},[3775,3791],{"type":20,"tag":90,"props":3776,"children":3777},{"class":92,"line":93},[3778,3782,3786],{"type":20,"tag":90,"props":3779,"children":3780},{"style":135},[3781],{"type":30,"value":3311},{"type":20,"tag":90,"props":3783,"children":3784},{"style":146},[3785],{"type":30,"value":817},{"type":20,"tag":90,"props":3787,"children":3788},{"style":129},[3789],{"type":30,"value":3790}," /home/web/www.git/\n",{"type":20,"tag":90,"props":3792,"children":3793},{"class":92,"line":103},[3794,3798,3802],{"type":20,"tag":90,"props":3795,"children":3796},{"style":135},[3797],{"type":30,"value":3311},{"type":20,"tag":90,"props":3799,"children":3800},{"style":146},[3801],{"type":30,"value":817},{"type":20,"tag":90,"props":3803,"children":3804},{"style":129},[3805],{"type":30,"value":3806}," /home/web/www/\n",{"type":20,"tag":21,"props":3808,"children":3809},{},[3810],{"type":30,"value":3811},"Setup a bare git repository:",{"type":20,"tag":79,"props":3813,"children":3815},{"className":3050,"code":3814,"language":3052,"meta":8,"style":8},"cd /home/web/www.git/\ngit config core.sharedRepository group\n",[3816],{"type":20,"tag":86,"props":3817,"children":3818},{"__ignoreMap":8},[3819,3830],{"type":20,"tag":90,"props":3820,"children":3821},{"class":92,"line":93},[3822,3826],{"type":20,"tag":90,"props":3823,"children":3824},{"style":146},[3825],{"type":30,"value":3158},{"type":20,"tag":90,"props":3827,"children":3828},{"style":129},[3829],{"type":30,"value":3790},{"type":20,"tag":90,"props":3831,"children":3832},{"class":92,"line":103},[3833,3838,3843,3848],{"type":20,"tag":90,"props":3834,"children":3835},{"style":135},[3836],{"type":30,"value":3837},"git",{"type":20,"tag":90,"props":3839,"children":3840},{"style":129},[3841],{"type":30,"value":3842}," config",{"type":20,"tag":90,"props":3844,"children":3845},{"style":129},[3846],{"type":30,"value":3847}," core.sharedRepository",{"type":20,"tag":90,"props":3849,"children":3850},{"style":129},[3851],{"type":30,"value":3852}," group\n",{"type":20,"tag":21,"props":3854,"children":3855},{},[3856,3858,3864],{"type":30,"value":3857},"And create a post-receive hook that will ",{"type":20,"tag":86,"props":3859,"children":3861},{"className":3860},[],[3862],{"type":30,"value":3863},"install/update",{"type":30,"value":3865}," our packages, run migrations for us, and kill and restart the development server:",{"type":20,"tag":21,"props":3867,"children":3868},{},[3869],{"type":30,"value":77},{"type":20,"tag":79,"props":3871,"children":3873},{"className":81,"code":3872,"language":83,"meta":8,"style":8},"#!/bin/bash\n\nGIT_WORK_TREE=/home/web/www/ git checkout -f\n\nsource /home/web/venv/bin/activate\npushd /home/web/www/\n\n# Install python libs via pip and perform database migrations\npip install --upgrade -r requirements.txt\npython manage.py migrate\n\nkill ps aux | grep runserver | grep -v grep | awk '{print $2}'\npython manage.py runserver\n\npopd\ndeactivate\n",[3874],{"type":20,"tag":86,"props":3875,"children":3876},{"__ignoreMap":8},[3877,3884,3891,3918,3925,3936,3943,3950,3957,3980,3995,4002,4066,4082,4089,4096],{"type":20,"tag":90,"props":3878,"children":3879},{"class":92,"line":93},[3880],{"type":20,"tag":90,"props":3881,"children":3882},{"style":97},[3883],{"type":30,"value":100},{"type":20,"tag":90,"props":3885,"children":3886},{"class":92,"line":103},[3887],{"type":20,"tag":90,"props":3888,"children":3889},{"emptyLinePlaceholder":107},[3890],{"type":30,"value":110},{"type":20,"tag":90,"props":3892,"children":3893},{"class":92,"line":113},[3894,3898,3902,3906,3910,3914],{"type":20,"tag":90,"props":3895,"children":3896},{"style":117},[3897],{"type":30,"value":120},{"type":20,"tag":90,"props":3899,"children":3900},{"style":123},[3901],{"type":30,"value":126},{"type":20,"tag":90,"props":3903,"children":3904},{"style":129},[3905],{"type":30,"value":132},{"type":20,"tag":90,"props":3907,"children":3908},{"style":135},[3909],{"type":30,"value":138},{"type":20,"tag":90,"props":3911,"children":3912},{"style":129},[3913],{"type":30,"value":143},{"type":20,"tag":90,"props":3915,"children":3916},{"style":146},[3917],{"type":30,"value":149},{"type":20,"tag":90,"props":3919,"children":3920},{"class":92,"line":152},[3921],{"type":20,"tag":90,"props":3922,"children":3923},{"emptyLinePlaceholder":107},[3924],{"type":30,"value":110},{"type":20,"tag":90,"props":3926,"children":3927},{"class":92,"line":160},[3928,3932],{"type":20,"tag":90,"props":3929,"children":3930},{"style":146},[3931],{"type":30,"value":166},{"type":20,"tag":90,"props":3933,"children":3934},{"style":129},[3935],{"type":30,"value":171},{"type":20,"tag":90,"props":3937,"children":3938},{"class":92,"line":174},[3939],{"type":20,"tag":90,"props":3940,"children":3941},{"style":117},[3942],{"type":30,"value":180},{"type":20,"tag":90,"props":3944,"children":3945},{"class":92,"line":183},[3946],{"type":20,"tag":90,"props":3947,"children":3948},{"emptyLinePlaceholder":107},[3949],{"type":30,"value":110},{"type":20,"tag":90,"props":3951,"children":3952},{"class":92,"line":191},[3953],{"type":20,"tag":90,"props":3954,"children":3955},{"style":97},[3956],{"type":30,"value":197},{"type":20,"tag":90,"props":3958,"children":3959},{"class":92,"line":200},[3960,3964,3968,3972,3976],{"type":20,"tag":90,"props":3961,"children":3962},{"style":135},[3963],{"type":30,"value":206},{"type":20,"tag":90,"props":3965,"children":3966},{"style":129},[3967],{"type":30,"value":211},{"type":20,"tag":90,"props":3969,"children":3970},{"style":146},[3971],{"type":30,"value":216},{"type":20,"tag":90,"props":3973,"children":3974},{"style":146},[3975],{"type":30,"value":221},{"type":20,"tag":90,"props":3977,"children":3978},{"style":129},[3979],{"type":30,"value":226},{"type":20,"tag":90,"props":3981,"children":3982},{"class":92,"line":229},[3983,3987,3991],{"type":20,"tag":90,"props":3984,"children":3985},{"style":135},[3986],{"type":30,"value":14},{"type":20,"tag":90,"props":3988,"children":3989},{"style":129},[3990],{"type":30,"value":239},{"type":20,"tag":90,"props":3992,"children":3993},{"style":129},[3994],{"type":30,"value":244},{"type":20,"tag":90,"props":3996,"children":3997},{"class":92,"line":247},[3998],{"type":20,"tag":90,"props":3999,"children":4000},{"emptyLinePlaceholder":107},[4001],{"type":30,"value":110},{"type":20,"tag":90,"props":4003,"children":4004},{"class":92,"line":255},[4005,4010,4015,4020,4025,4030,4035,4039,4043,4048,4052,4056,4061],{"type":20,"tag":90,"props":4006,"children":4007},{"style":146},[4008],{"type":30,"value":4009},"kill",{"type":20,"tag":90,"props":4011,"children":4012},{"style":129},[4013],{"type":30,"value":4014}," ps",{"type":20,"tag":90,"props":4016,"children":4017},{"style":129},[4018],{"type":30,"value":4019}," aux",{"type":20,"tag":90,"props":4021,"children":4022},{"style":123},[4023],{"type":30,"value":4024}," |",{"type":20,"tag":90,"props":4026,"children":4027},{"style":135},[4028],{"type":30,"value":4029}," grep",{"type":20,"tag":90,"props":4031,"children":4032},{"style":129},[4033],{"type":30,"value":4034}," runserver",{"type":20,"tag":90,"props":4036,"children":4037},{"style":123},[4038],{"type":30,"value":4024},{"type":20,"tag":90,"props":4040,"children":4041},{"style":135},[4042],{"type":30,"value":4029},{"type":20,"tag":90,"props":4044,"children":4045},{"style":146},[4046],{"type":30,"value":4047}," -v",{"type":20,"tag":90,"props":4049,"children":4050},{"style":129},[4051],{"type":30,"value":4029},{"type":20,"tag":90,"props":4053,"children":4054},{"style":123},[4055],{"type":30,"value":4024},{"type":20,"tag":90,"props":4057,"children":4058},{"style":135},[4059],{"type":30,"value":4060}," awk",{"type":20,"tag":90,"props":4062,"children":4063},{"style":129},[4064],{"type":30,"value":4065}," '{print $2}'\n",{"type":20,"tag":90,"props":4067,"children":4068},{"class":92,"line":264},[4069,4073,4077],{"type":20,"tag":90,"props":4070,"children":4071},{"style":135},[4072],{"type":30,"value":14},{"type":20,"tag":90,"props":4074,"children":4075},{"style":129},[4076],{"type":30,"value":239},{"type":20,"tag":90,"props":4078,"children":4079},{"style":129},[4080],{"type":30,"value":4081}," runserver\n",{"type":20,"tag":90,"props":4083,"children":4084},{"class":92,"line":273},[4085],{"type":20,"tag":90,"props":4086,"children":4087},{"emptyLinePlaceholder":107},[4088],{"type":30,"value":110},{"type":20,"tag":90,"props":4090,"children":4091},{"class":92,"line":292},[4092],{"type":20,"tag":90,"props":4093,"children":4094},{"style":117},[4095],{"type":30,"value":261},{"type":20,"tag":90,"props":4097,"children":4098},{"class":92,"line":1658},[4099],{"type":20,"tag":90,"props":4100,"children":4101},{"style":135},[4102],{"type":30,"value":270},{"type":20,"tag":21,"props":4104,"children":4105},{},[4106],{"type":30,"value":314},{"type":20,"tag":79,"props":4108,"children":4110},{"className":81,"code":4109,"language":83,"meta":8,"style":8},"#!/bin/csh\n\nenv GIT_WORK_TREE=/home/web/www/ git checkout -f\nsource /home/web/venv/bin/activate.csh\npushd /home/web/www/\n\npip install --upgrade -r requirements.txt\npython manage.py migrate\n\nkill ps aux | grep runserver | grep -v grep | awk '{print $2}'\npython manage.py runserver\n\npopd\ndeactivate\n",[4111],{"type":20,"tag":86,"props":4112,"children":4113},{"__ignoreMap":8},[4114,4121,4128,4151,4162,4169,4176,4199,4214,4221,4276,4291,4298,4305],{"type":20,"tag":90,"props":4115,"children":4116},{"class":92,"line":93},[4117],{"type":20,"tag":90,"props":4118,"children":4119},{"style":97},[4120],{"type":30,"value":329},{"type":20,"tag":90,"props":4122,"children":4123},{"class":92,"line":103},[4124],{"type":20,"tag":90,"props":4125,"children":4126},{"emptyLinePlaceholder":107},[4127],{"type":30,"value":110},{"type":20,"tag":90,"props":4129,"children":4130},{"class":92,"line":113},[4131,4135,4139,4143,4147],{"type":20,"tag":90,"props":4132,"children":4133},{"style":135},[4134],{"type":30,"value":344},{"type":20,"tag":90,"props":4136,"children":4137},{"style":129},[4138],{"type":30,"value":349},{"type":20,"tag":90,"props":4140,"children":4141},{"style":129},[4142],{"type":30,"value":138},{"type":20,"tag":90,"props":4144,"children":4145},{"style":129},[4146],{"type":30,"value":143},{"type":20,"tag":90,"props":4148,"children":4149},{"style":146},[4150],{"type":30,"value":149},{"type":20,"tag":90,"props":4152,"children":4153},{"class":92,"line":152},[4154,4158],{"type":20,"tag":90,"props":4155,"children":4156},{"style":146},[4157],{"type":30,"value":166},{"type":20,"tag":90,"props":4159,"children":4160},{"style":129},[4161],{"type":30,"value":373},{"type":20,"tag":90,"props":4163,"children":4164},{"class":92,"line":160},[4165],{"type":20,"tag":90,"props":4166,"children":4167},{"style":117},[4168],{"type":30,"value":180},{"type":20,"tag":90,"props":4170,"children":4171},{"class":92,"line":174},[4172],{"type":20,"tag":90,"props":4173,"children":4174},{"emptyLinePlaceholder":107},[4175],{"type":30,"value":110},{"type":20,"tag":90,"props":4177,"children":4178},{"class":92,"line":183},[4179,4183,4187,4191,4195],{"type":20,"tag":90,"props":4180,"children":4181},{"style":135},[4182],{"type":30,"value":206},{"type":20,"tag":90,"props":4184,"children":4185},{"style":129},[4186],{"type":30,"value":211},{"type":20,"tag":90,"props":4188,"children":4189},{"style":146},[4190],{"type":30,"value":216},{"type":20,"tag":90,"props":4192,"children":4193},{"style":146},[4194],{"type":30,"value":221},{"type":20,"tag":90,"props":4196,"children":4197},{"style":129},[4198],{"type":30,"value":226},{"type":20,"tag":90,"props":4200,"children":4201},{"class":92,"line":191},[4202,4206,4210],{"type":20,"tag":90,"props":4203,"children":4204},{"style":135},[4205],{"type":30,"value":14},{"type":20,"tag":90,"props":4207,"children":4208},{"style":129},[4209],{"type":30,"value":239},{"type":20,"tag":90,"props":4211,"children":4212},{"style":129},[4213],{"type":30,"value":244},{"type":20,"tag":90,"props":4215,"children":4216},{"class":92,"line":200},[4217],{"type":20,"tag":90,"props":4218,"children":4219},{"emptyLinePlaceholder":107},[4220],{"type":30,"value":110},{"type":20,"tag":90,"props":4222,"children":4223},{"class":92,"line":229},[4224,4228,4232,4236,4240,4244,4248,4252,4256,4260,4264,4268,4272],{"type":20,"tag":90,"props":4225,"children":4226},{"style":146},[4227],{"type":30,"value":4009},{"type":20,"tag":90,"props":4229,"children":4230},{"style":129},[4231],{"type":30,"value":4014},{"type":20,"tag":90,"props":4233,"children":4234},{"style":129},[4235],{"type":30,"value":4019},{"type":20,"tag":90,"props":4237,"children":4238},{"style":123},[4239],{"type":30,"value":4024},{"type":20,"tag":90,"props":4241,"children":4242},{"style":135},[4243],{"type":30,"value":4029},{"type":20,"tag":90,"props":4245,"children":4246},{"style":129},[4247],{"type":30,"value":4034},{"type":20,"tag":90,"props":4249,"children":4250},{"style":123},[4251],{"type":30,"value":4024},{"type":20,"tag":90,"props":4253,"children":4254},{"style":135},[4255],{"type":30,"value":4029},{"type":20,"tag":90,"props":4257,"children":4258},{"style":146},[4259],{"type":30,"value":4047},{"type":20,"tag":90,"props":4261,"children":4262},{"style":129},[4263],{"type":30,"value":4029},{"type":20,"tag":90,"props":4265,"children":4266},{"style":123},[4267],{"type":30,"value":4024},{"type":20,"tag":90,"props":4269,"children":4270},{"style":135},[4271],{"type":30,"value":4060},{"type":20,"tag":90,"props":4273,"children":4274},{"style":129},[4275],{"type":30,"value":4065},{"type":20,"tag":90,"props":4277,"children":4278},{"class":92,"line":247},[4279,4283,4287],{"type":20,"tag":90,"props":4280,"children":4281},{"style":135},[4282],{"type":30,"value":14},{"type":20,"tag":90,"props":4284,"children":4285},{"style":129},[4286],{"type":30,"value":239},{"type":20,"tag":90,"props":4288,"children":4289},{"style":129},[4290],{"type":30,"value":4081},{"type":20,"tag":90,"props":4292,"children":4293},{"class":92,"line":255},[4294],{"type":20,"tag":90,"props":4295,"children":4296},{"emptyLinePlaceholder":107},[4297],{"type":30,"value":110},{"type":20,"tag":90,"props":4299,"children":4300},{"class":92,"line":264},[4301],{"type":20,"tag":90,"props":4302,"children":4303},{"style":117},[4304],{"type":30,"value":261},{"type":20,"tag":90,"props":4306,"children":4307},{"class":92,"line":273},[4308],{"type":20,"tag":90,"props":4309,"children":4310},{"style":135},[4311],{"type":30,"value":270},{"type":20,"tag":21,"props":4313,"children":4314},{},[4315,4317,4323,4325,4331],{"type":30,"value":4316},"Save this file as ",{"type":20,"tag":86,"props":4318,"children":4320},{"className":4319},[],[4321],{"type":30,"value":4322},"post-receive",{"type":30,"value":4324},", and then make it executable: ",{"type":20,"tag":86,"props":4326,"children":4328},{"className":4327},[],[4329],{"type":30,"value":4330},"chmod +x post-receive",{"type":30,"value":615},{"type":20,"tag":21,"props":4333,"children":4334},{},[4335,4337,4343,4345,4351],{"type":30,"value":4336},"Now, ",{"type":20,"tag":86,"props":4338,"children":4340},{"className":4339},[],[4341],{"type":30,"value":4342},"git init",{"type":30,"value":4344}," in your local directory, and add a new remote with ",{"type":20,"tag":86,"props":4346,"children":4348},{"className":4347},[],[4349],{"type":30,"value":4350},"git remote add your.server.addr.octets/home/web/www.git",{"type":30,"value":4352},". When pushing, do so as your web user, or you may run into permissions issues.",{"type":20,"tag":21,"props":4354,"children":4355},{},[4356,4358,4364],{"type":30,"value":4357},"As noted before, ",{"type":20,"tag":25,"props":4359,"children":4361},{"href":3756,"rel":4360},[38],[4362],{"type":30,"value":4363},"more details on this can be found in this article",{"type":30,"value":615},{"type":20,"tag":2678,"props":4366,"children":4368},{"id":4367},"are-we-there-yet",[4369],{"type":30,"value":4370},"Are we there yet?",{"type":20,"tag":21,"props":4372,"children":4373},{},[4374,4376,4381],{"type":30,"value":4375},"Hah, no, but we are done for today. We're now at a point where you could push your code into your server, and use django's runserver command to run the development server. With the ",{"type":20,"tag":86,"props":4377,"children":4379},{"className":4378},[],[4380],{"type":30,"value":3434},{"type":30,"value":4382}," app installed, this well-known invocation will not start up the old wsgi server, but a shiny new ASGI server instead, with workers and interface living inside the same process as separate threads.",{"type":20,"tag":21,"props":4384,"children":4385},{},[4386,4393],{"type":20,"tag":25,"props":4387,"children":4390},{"href":4388,"rel":4389},"https://artandlogic.com/2016/06/django-channels-ground-part-2/",[38],[4391],{"type":30,"value":4392},"Next time",{"type":30,"value":4394},", we'll go the rest of the way - getting your server something resembling production ready, with postgresql setup, supervisord managing our server workers and interface, and we'll start figuring out what we need to actually use this setup for something cool.",{"type":20,"tag":2722,"props":4396,"children":4397},{},[4398],{"type":30,"value":2726},{"title":8,"searchDepth":113,"depth":113,"links":4400},[4401,4404,4411],{"id":2791,"depth":103,"text":2794,"children":4402},[4403],{"id":2900,"depth":152,"text":2903},{"id":2931,"depth":103,"text":2934,"children":4405},[4406,4407,4408,4409,4410],{"id":3034,"depth":113,"text":3037},{"id":3241,"depth":113,"text":3244},{"id":3347,"depth":113,"text":3350},{"id":3663,"depth":113,"text":3666},{"id":3745,"depth":113,"text":3748},{"id":4367,"depth":103,"text":4370},"content:ckeefer:2016-3:djangoChannels1.md","ckeefer/2016-3/djangoChannels1.md","ckeefer/2016-3/djangoChannels1",{"user":2743,"name":2744},{"_path":4417,"_dir":4418,"_draft":7,"_partial":7,"_locale":8,"title":4419,"description":4420,"publishDate":4421,"tags":4422,"image":4425,"excerpt":4420,"body":4426,"_type":2736,"_id":10428,"_source":2738,"_file":10429,"_stem":10430,"_extension":2741,"author":10431},"/ckeefer/2014-6/backbonesocketsync","2014-6","Websockets for Backbone","Backbone's had some of its thunder stolen lately by trendier frameworks like Meteor and Angular; for good reason, in most cases, as without the prosthetic functionality offered by the likes of Marionette, Backbone's view handling (amongst a few other lacks and warts) is really just 'roughed in'.","2014-06-25",[4423,15,4424],"js","backbone","/ckeefer/2014-6/img/WebsocketsPlusBackbone.png",{"type":17,"children":4427,"toc":10426},[4428,4442,4447,4452,4465,4496,4501,6321,6326,6507,6512,6625,6644,6649,6701,7047,7067,7264,7269,7487,7515,7527,7540,7593,7607,7704,7709,7928,7933,8190,8202,8207,8212,10417,10422],{"type":20,"tag":21,"props":4429,"children":4430},{},[4431,4433,4440],{"type":30,"value":4432},"Backbone's had some of its thunder stolen lately by trendier frameworks like Meteor and Angular; for good reason, in most cases, as without the prosthetic functionality offered by the likes of ",{"type":20,"tag":25,"props":4434,"children":4437},{"href":4435,"rel":4436},"http://marionettejs.com",[38],[4438],{"type":30,"value":4439},"Marionette",{"type":30,"value":4441},", Backbone's view handling (amongst a few other lacks and warts) is really just 'roughed in'.",{"type":20,"tag":21,"props":4443,"children":4444},{},[4445],{"type":30,"value":4446},"But the fact that a framework like marionette can be built on top of Backbone is a testament to Backbone's flexibility - after all, as the name suggests, Backbone is really just the 'skeleton' of your app, and it's willing to be fit into place however you need it to be.",{"type":20,"tag":21,"props":4448,"children":4449},{},[4450],{"type":30,"value":4451},"For instance: Backbone's default persistance method is via jQuery's ajax - make a request to the server using one of the standard HTTP methods to persists changes to models in a collection to the server-side db. Works great, but maybe you need something faster/better/stronger/etc.",{"type":20,"tag":21,"props":4453,"children":4454},{},[4455,4457,4464],{"type":30,"value":4456},"Like, say, ",{"type":20,"tag":25,"props":4458,"children":4461},{"href":4459,"rel":4460},"https://developer.mozilla.org/en/docs/WebSockets",[38],[4462],{"type":30,"value":4463},"WebSockets",{"type":30,"value":615},{"type":20,"tag":21,"props":4466,"children":4467},{},[4468,4470,4477,4479,4485,4487,4494],{"type":30,"value":4469},"Let's replace Backbone's standard method of persistance via ajax with WebSockets! To do this, we'll take advantage of the excellent ",{"type":20,"tag":25,"props":4471,"children":4474},{"href":4472,"rel":4473},"http://socket.io",[38],[4475],{"type":30,"value":4476},"socket.io",{"type":30,"value":4478}," client library (and, of course, you'll need the appropriate server-side library for your chosen language - via ",{"type":20,"tag":86,"props":4480,"children":4482},{"className":4481},[],[4483],{"type":30,"value":4484},"npm install socket.io",{"type":30,"value":4486}," if you're using Node.js, a package like ",{"type":20,"tag":25,"props":4488,"children":4491},{"href":4489,"rel":4490},"https://github.com/abourget/gevent-socketio",[38],[4492],{"type":30,"value":4493},"Gevent Socket.io",{"type":30,"value":4495}," if you're using Python, etc.).",{"type":20,"tag":21,"props":4497,"children":4498},{},[4499],{"type":30,"value":4500},"Let's take a look at the code, and then break it down:",{"type":20,"tag":79,"props":4502,"children":4506},{"className":4503,"code":4504,"language":4505,"meta":8,"style":8},"language-javascript shiki shiki-themes github-light github-dark","/**\n * Copyright (c) Christopher Keefer. All Rights Reserved.\n *\n * Overrides the default transport for Backbone syncing to use websockets via socket.io.\n */\n(function(Backbone, $, _, io){\n    var urlError = function(){\n        throw new Error('A \"url\" property or function must be specified.');\n    },\n        eventEmit = io.EventEmitter.prototype.emit,\n        ajaxSync = Backbone.sync;\n\n    /**\n     * Preserve the standard, jquery ajax based persistance method as ajaxSync.\n     */\n    Backbone.ajaxSync = function(method, model, options){\n        return ajaxSync.call(this, method, model, options);\n    };\n\n    /**\n     * Replace the standard sync function with our new, websocket/socket.io based solution.\n     */\n    Backbone.sync = function(method, model, options){\n        var opts = _.extend({}, options),\n            defer = $.Deferred(),\n            promise = defer.promise(),\n            namespace,\n            socket;\n\n        opts.url = (opts.url) ? _.result(opts, 'url') : (model.url) ? _.result(model, 'url') : void 0;\n        // If no url property has been specified, throw an error, as per the standard Backbone sync\n        if (!opts.url) urlError();\n        // Transform the url into a namespace\n        namespace = Backbone.Model.prototype.namespace.call(this, opts.url);\n        // Determine what data we're sending, and ensure id is present if we're performing a PATCH call\n        if (!opts.data && model) opts.data = opts.attrs || model.toJSON(options) || {};\n        if ((opts.data.id === null || opts.data.id === void 0) && opts.patch === true && model){\n            opts.data.id = model.id;\n        }\n        // Determine which websocket to use - set in options or on model\n        socket = opts.socket || model.socket;\n        // Add a listener for our namespaced method, and resolve or reject our deferred based on the response\n        socket.once(namespace+method, function(res){\n            var success = (res && res.success); // Expects server json response to contain a boolean 'success' field\n            if (success)\n            {\n                if (_.isFunction(options.success)) options.success(res);\n                defer.resolve(res);\n                return;\n            }\n            if (_.isFunction(options.error)) options.error(res);\n            defer.reject(res);\n        });\n\n        // Emit our namespaced method and the model+opts data\n        socket.emit(namespace+method, opts.data);\n\n        // Trigger the request event on the model, as per backbone spec\n        model.trigger('request', model, promise, opts);\n        // Return the promise for us to use as per usual (hanging .done blocks off, add to a .when, etc.)\n        return promise;\n    };\n\n    /**\n     * Break url apart to create namespace - every '/' save any pre/post-fixing the url will become a ':' indicating\n     * namespace - so a collection that maps to /api/posts will now have its events on the namespace\n     * api:posts: (ie. api:posts:create, api:posts:delete, etc.), and a model that maps to /api/posts/21\n     * will have events on api:posts:21: (ie. api:posts:21:update, api:posts:21:patch, etc.)\n     * @param {string=} url\n     */\n    Backbone.Model.prototype.namespace = function(url){\n        url = url || this.url();\n        return _.trim(url, '/').replace('/', ':') + \":\";\n    };\n\n    /**\n     * Override EventEmitter.emit and SocketNamespace reference for socket.io to add a catch all case for the\n     * wildcard ('*') character. Now, socket.on('*') will catch any event, with the name of the caught event\n     * passed to the handler as the first argument.\n    */\n    io.EventEmitter.prototype.emit = function(name){\n        var args = Array.prototype.slice.call(arguments, 1);\n\n        eventEmit.apply(this, ['*', name].concat(args));\n        eventEmit.apply(this, [name].concat(args));\n    };\n    io.SocketNamespace.prototype.$emit = io.EventEmitter.prototype.emit;\n})(Backbone, jQuery, _, io);\n","javascript",[4507],{"type":20,"tag":86,"props":4508,"children":4509},{"__ignoreMap":8},[4510,4518,4526,4534,4542,4550,4604,4631,4663,4671,4698,4715,4722,4730,4738,4746,4798,4830,4838,4845,4852,4860,4867,4915,4947,4974,5000,5008,5016,5023,5121,5129,5162,5170,5213,5221,5289,5365,5382,5390,5398,5424,5432,5477,5513,5526,5534,5567,5584,5597,5606,5636,5654,5663,5671,5680,5706,5714,5723,5751,5760,5773,5781,5789,5797,5806,5815,5824,5833,5857,5865,5908,5947,6018,6026,6034,6042,6051,6060,6069,6078,6120,6181,6189,6236,6269,6277,6312],{"type":20,"tag":90,"props":4511,"children":4512},{"class":92,"line":93},[4513],{"type":20,"tag":90,"props":4514,"children":4515},{"style":97},[4516],{"type":30,"value":4517},"/**\n",{"type":20,"tag":90,"props":4519,"children":4520},{"class":92,"line":103},[4521],{"type":20,"tag":90,"props":4522,"children":4523},{"style":97},[4524],{"type":30,"value":4525}," * Copyright (c) Christopher Keefer. All Rights Reserved.\n",{"type":20,"tag":90,"props":4527,"children":4528},{"class":92,"line":113},[4529],{"type":20,"tag":90,"props":4530,"children":4531},{"style":97},[4532],{"type":30,"value":4533}," *\n",{"type":20,"tag":90,"props":4535,"children":4536},{"class":92,"line":152},[4537],{"type":20,"tag":90,"props":4538,"children":4539},{"style":97},[4540],{"type":30,"value":4541}," * Overrides the default transport for Backbone syncing to use websockets via socket.io.\n",{"type":20,"tag":90,"props":4543,"children":4544},{"class":92,"line":160},[4545],{"type":20,"tag":90,"props":4546,"children":4547},{"style":97},[4548],{"type":30,"value":4549}," */\n",{"type":20,"tag":90,"props":4551,"children":4552},{"class":92,"line":174},[4553,4558,4563,4567,4573,4577,4581,4585,4590,4594,4599],{"type":20,"tag":90,"props":4554,"children":4555},{"style":117},[4556],{"type":30,"value":4557},"(",{"type":20,"tag":90,"props":4559,"children":4560},{"style":123},[4561],{"type":30,"value":4562},"function",{"type":20,"tag":90,"props":4564,"children":4565},{"style":117},[4566],{"type":30,"value":4557},{"type":20,"tag":90,"props":4568,"children":4570},{"style":4569},"--shiki-default:#E36209;--shiki-dark:#FFAB70",[4571],{"type":30,"value":4572},"Backbone",{"type":20,"tag":90,"props":4574,"children":4575},{"style":117},[4576],{"type":30,"value":1260},{"type":20,"tag":90,"props":4578,"children":4579},{"style":4569},[4580],{"type":30,"value":2452},{"type":20,"tag":90,"props":4582,"children":4583},{"style":117},[4584],{"type":30,"value":1260},{"type":20,"tag":90,"props":4586,"children":4587},{"style":4569},[4588],{"type":30,"value":4589},"_",{"type":20,"tag":90,"props":4591,"children":4592},{"style":117},[4593],{"type":30,"value":1260},{"type":20,"tag":90,"props":4595,"children":4596},{"style":4569},[4597],{"type":30,"value":4598},"io",{"type":20,"tag":90,"props":4600,"children":4601},{"style":117},[4602],{"type":30,"value":4603},"){\n",{"type":20,"tag":90,"props":4605,"children":4606},{"class":92,"line":183},[4607,4612,4617,4621,4626],{"type":20,"tag":90,"props":4608,"children":4609},{"style":123},[4610],{"type":30,"value":4611},"    var",{"type":20,"tag":90,"props":4613,"children":4614},{"style":135},[4615],{"type":30,"value":4616}," urlError",{"type":20,"tag":90,"props":4618,"children":4619},{"style":123},[4620],{"type":30,"value":1113},{"type":20,"tag":90,"props":4622,"children":4623},{"style":123},[4624],{"type":30,"value":4625}," function",{"type":20,"tag":90,"props":4627,"children":4628},{"style":117},[4629],{"type":30,"value":4630},"(){\n",{"type":20,"tag":90,"props":4632,"children":4633},{"class":92,"line":191},[4634,4639,4644,4649,4653,4658],{"type":20,"tag":90,"props":4635,"children":4636},{"style":123},[4637],{"type":30,"value":4638},"        throw",{"type":20,"tag":90,"props":4640,"children":4641},{"style":123},[4642],{"type":30,"value":4643}," new",{"type":20,"tag":90,"props":4645,"children":4646},{"style":135},[4647],{"type":30,"value":4648}," Error",{"type":20,"tag":90,"props":4650,"children":4651},{"style":117},[4652],{"type":30,"value":4557},{"type":20,"tag":90,"props":4654,"children":4655},{"style":129},[4656],{"type":30,"value":4657},"'A \"url\" property or function must be specified.'",{"type":20,"tag":90,"props":4659,"children":4660},{"style":117},[4661],{"type":30,"value":4662},");\n",{"type":20,"tag":90,"props":4664,"children":4665},{"class":92,"line":200},[4666],{"type":20,"tag":90,"props":4667,"children":4668},{"style":117},[4669],{"type":30,"value":4670},"    },\n",{"type":20,"tag":90,"props":4672,"children":4673},{"class":92,"line":229},[4674,4679,4683,4688,4693],{"type":20,"tag":90,"props":4675,"children":4676},{"style":117},[4677],{"type":30,"value":4678},"        eventEmit ",{"type":20,"tag":90,"props":4680,"children":4681},{"style":123},[4682],{"type":30,"value":126},{"type":20,"tag":90,"props":4684,"children":4685},{"style":117},[4686],{"type":30,"value":4687}," io.EventEmitter.",{"type":20,"tag":90,"props":4689,"children":4690},{"style":146},[4691],{"type":30,"value":4692},"prototype",{"type":20,"tag":90,"props":4694,"children":4695},{"style":117},[4696],{"type":30,"value":4697},".emit,\n",{"type":20,"tag":90,"props":4699,"children":4700},{"class":92,"line":247},[4701,4706,4710],{"type":20,"tag":90,"props":4702,"children":4703},{"style":117},[4704],{"type":30,"value":4705},"        ajaxSync ",{"type":20,"tag":90,"props":4707,"children":4708},{"style":123},[4709],{"type":30,"value":126},{"type":20,"tag":90,"props":4711,"children":4712},{"style":117},[4713],{"type":30,"value":4714}," Backbone.sync;\n",{"type":20,"tag":90,"props":4716,"children":4717},{"class":92,"line":255},[4718],{"type":20,"tag":90,"props":4719,"children":4720},{"emptyLinePlaceholder":107},[4721],{"type":30,"value":110},{"type":20,"tag":90,"props":4723,"children":4724},{"class":92,"line":264},[4725],{"type":20,"tag":90,"props":4726,"children":4727},{"style":97},[4728],{"type":30,"value":4729},"    /**\n",{"type":20,"tag":90,"props":4731,"children":4732},{"class":92,"line":273},[4733],{"type":20,"tag":90,"props":4734,"children":4735},{"style":97},[4736],{"type":30,"value":4737},"     * Preserve the standard, jquery ajax based persistance method as ajaxSync.\n",{"type":20,"tag":90,"props":4739,"children":4740},{"class":92,"line":292},[4741],{"type":20,"tag":90,"props":4742,"children":4743},{"style":97},[4744],{"type":30,"value":4745},"     */\n",{"type":20,"tag":90,"props":4747,"children":4748},{"class":92,"line":1658},[4749,4754,4759,4763,4767,4771,4776,4780,4785,4789,4794],{"type":20,"tag":90,"props":4750,"children":4751},{"style":117},[4752],{"type":30,"value":4753},"    Backbone.",{"type":20,"tag":90,"props":4755,"children":4756},{"style":135},[4757],{"type":30,"value":4758},"ajaxSync",{"type":20,"tag":90,"props":4760,"children":4761},{"style":123},[4762],{"type":30,"value":1113},{"type":20,"tag":90,"props":4764,"children":4765},{"style":123},[4766],{"type":30,"value":4625},{"type":20,"tag":90,"props":4768,"children":4769},{"style":117},[4770],{"type":30,"value":4557},{"type":20,"tag":90,"props":4772,"children":4773},{"style":4569},[4774],{"type":30,"value":4775},"method",{"type":20,"tag":90,"props":4777,"children":4778},{"style":117},[4779],{"type":30,"value":1260},{"type":20,"tag":90,"props":4781,"children":4782},{"style":4569},[4783],{"type":30,"value":4784},"model",{"type":20,"tag":90,"props":4786,"children":4787},{"style":117},[4788],{"type":30,"value":1260},{"type":20,"tag":90,"props":4790,"children":4791},{"style":4569},[4792],{"type":30,"value":4793},"options",{"type":20,"tag":90,"props":4795,"children":4796},{"style":117},[4797],{"type":30,"value":4603},{"type":20,"tag":90,"props":4799,"children":4800},{"class":92,"line":2281},[4801,4806,4811,4816,4820,4825],{"type":20,"tag":90,"props":4802,"children":4803},{"style":123},[4804],{"type":30,"value":4805},"        return",{"type":20,"tag":90,"props":4807,"children":4808},{"style":117},[4809],{"type":30,"value":4810}," ajaxSync.",{"type":20,"tag":90,"props":4812,"children":4813},{"style":135},[4814],{"type":30,"value":4815},"call",{"type":20,"tag":90,"props":4817,"children":4818},{"style":117},[4819],{"type":30,"value":4557},{"type":20,"tag":90,"props":4821,"children":4822},{"style":146},[4823],{"type":30,"value":4824},"this",{"type":20,"tag":90,"props":4826,"children":4827},{"style":117},[4828],{"type":30,"value":4829},", method, model, options);\n",{"type":20,"tag":90,"props":4831,"children":4832},{"class":92,"line":2290},[4833],{"type":20,"tag":90,"props":4834,"children":4835},{"style":117},[4836],{"type":30,"value":4837},"    };\n",{"type":20,"tag":90,"props":4839,"children":4840},{"class":92,"line":2298},[4841],{"type":20,"tag":90,"props":4842,"children":4843},{"emptyLinePlaceholder":107},[4844],{"type":30,"value":110},{"type":20,"tag":90,"props":4846,"children":4847},{"class":92,"line":2316},[4848],{"type":20,"tag":90,"props":4849,"children":4850},{"style":97},[4851],{"type":30,"value":4729},{"type":20,"tag":90,"props":4853,"children":4854},{"class":92,"line":2325},[4855],{"type":20,"tag":90,"props":4856,"children":4857},{"style":97},[4858],{"type":30,"value":4859},"     * Replace the standard sync function with our new, websocket/socket.io based solution.\n",{"type":20,"tag":90,"props":4861,"children":4862},{"class":92,"line":2344},[4863],{"type":20,"tag":90,"props":4864,"children":4865},{"style":97},[4866],{"type":30,"value":4745},{"type":20,"tag":90,"props":4868,"children":4869},{"class":92,"line":2352},[4870,4874,4879,4883,4887,4891,4895,4899,4903,4907,4911],{"type":20,"tag":90,"props":4871,"children":4872},{"style":117},[4873],{"type":30,"value":4753},{"type":20,"tag":90,"props":4875,"children":4876},{"style":135},[4877],{"type":30,"value":4878},"sync",{"type":20,"tag":90,"props":4880,"children":4881},{"style":123},[4882],{"type":30,"value":1113},{"type":20,"tag":90,"props":4884,"children":4885},{"style":123},[4886],{"type":30,"value":4625},{"type":20,"tag":90,"props":4888,"children":4889},{"style":117},[4890],{"type":30,"value":4557},{"type":20,"tag":90,"props":4892,"children":4893},{"style":4569},[4894],{"type":30,"value":4775},{"type":20,"tag":90,"props":4896,"children":4897},{"style":117},[4898],{"type":30,"value":1260},{"type":20,"tag":90,"props":4900,"children":4901},{"style":4569},[4902],{"type":30,"value":4784},{"type":20,"tag":90,"props":4904,"children":4905},{"style":117},[4906],{"type":30,"value":1260},{"type":20,"tag":90,"props":4908,"children":4909},{"style":4569},[4910],{"type":30,"value":4793},{"type":20,"tag":90,"props":4912,"children":4913},{"style":117},[4914],{"type":30,"value":4603},{"type":20,"tag":90,"props":4916,"children":4917},{"class":92,"line":2361},[4918,4923,4928,4932,4937,4942],{"type":20,"tag":90,"props":4919,"children":4920},{"style":123},[4921],{"type":30,"value":4922},"        var",{"type":20,"tag":90,"props":4924,"children":4925},{"style":117},[4926],{"type":30,"value":4927}," opts ",{"type":20,"tag":90,"props":4929,"children":4930},{"style":123},[4931],{"type":30,"value":126},{"type":20,"tag":90,"props":4933,"children":4934},{"style":117},[4935],{"type":30,"value":4936}," _.",{"type":20,"tag":90,"props":4938,"children":4939},{"style":135},[4940],{"type":30,"value":4941},"extend",{"type":20,"tag":90,"props":4943,"children":4944},{"style":117},[4945],{"type":30,"value":4946},"({}, options),\n",{"type":20,"tag":90,"props":4948,"children":4949},{"class":92,"line":2379},[4950,4955,4959,4964,4969],{"type":20,"tag":90,"props":4951,"children":4952},{"style":117},[4953],{"type":30,"value":4954},"            defer ",{"type":20,"tag":90,"props":4956,"children":4957},{"style":123},[4958],{"type":30,"value":126},{"type":20,"tag":90,"props":4960,"children":4961},{"style":117},[4962],{"type":30,"value":4963}," $.",{"type":20,"tag":90,"props":4965,"children":4966},{"style":135},[4967],{"type":30,"value":4968},"Deferred",{"type":20,"tag":90,"props":4970,"children":4971},{"style":117},[4972],{"type":30,"value":4973},"(),\n",{"type":20,"tag":90,"props":4975,"children":4976},{"class":92,"line":2387},[4977,4982,4986,4991,4996],{"type":20,"tag":90,"props":4978,"children":4979},{"style":117},[4980],{"type":30,"value":4981},"            promise ",{"type":20,"tag":90,"props":4983,"children":4984},{"style":123},[4985],{"type":30,"value":126},{"type":20,"tag":90,"props":4987,"children":4988},{"style":117},[4989],{"type":30,"value":4990}," defer.",{"type":20,"tag":90,"props":4992,"children":4993},{"style":135},[4994],{"type":30,"value":4995},"promise",{"type":20,"tag":90,"props":4997,"children":4998},{"style":117},[4999],{"type":30,"value":4973},{"type":20,"tag":90,"props":5001,"children":5002},{"class":92,"line":2396},[5003],{"type":20,"tag":90,"props":5004,"children":5005},{"style":117},[5006],{"type":30,"value":5007},"            namespace,\n",{"type":20,"tag":90,"props":5009,"children":5010},{"class":92,"line":2405},[5011],{"type":20,"tag":90,"props":5012,"children":5013},{"style":117},[5014],{"type":30,"value":5015},"            socket;\n",{"type":20,"tag":90,"props":5017,"children":5018},{"class":92,"line":2413},[5019],{"type":20,"tag":90,"props":5020,"children":5021},{"emptyLinePlaceholder":107},[5022],{"type":30,"value":110},{"type":20,"tag":90,"props":5024,"children":5025},{"class":92,"line":2422},[5026,5031,5035,5040,5045,5049,5054,5059,5064,5069,5073,5078,5082,5086,5090,5095,5099,5103,5107,5112,5117],{"type":20,"tag":90,"props":5027,"children":5028},{"style":117},[5029],{"type":30,"value":5030},"        opts.url ",{"type":20,"tag":90,"props":5032,"children":5033},{"style":123},[5034],{"type":30,"value":126},{"type":20,"tag":90,"props":5036,"children":5037},{"style":117},[5038],{"type":30,"value":5039}," (opts.url) ",{"type":20,"tag":90,"props":5041,"children":5042},{"style":123},[5043],{"type":30,"value":5044},"?",{"type":20,"tag":90,"props":5046,"children":5047},{"style":117},[5048],{"type":30,"value":4936},{"type":20,"tag":90,"props":5050,"children":5051},{"style":135},[5052],{"type":30,"value":5053},"result",{"type":20,"tag":90,"props":5055,"children":5056},{"style":117},[5057],{"type":30,"value":5058},"(opts, ",{"type":20,"tag":90,"props":5060,"children":5061},{"style":129},[5062],{"type":30,"value":5063},"'url'",{"type":20,"tag":90,"props":5065,"children":5066},{"style":117},[5067],{"type":30,"value":5068},") ",{"type":20,"tag":90,"props":5070,"children":5071},{"style":123},[5072],{"type":30,"value":1717},{"type":20,"tag":90,"props":5074,"children":5075},{"style":117},[5076],{"type":30,"value":5077}," (model.url) ",{"type":20,"tag":90,"props":5079,"children":5080},{"style":123},[5081],{"type":30,"value":5044},{"type":20,"tag":90,"props":5083,"children":5084},{"style":117},[5085],{"type":30,"value":4936},{"type":20,"tag":90,"props":5087,"children":5088},{"style":135},[5089],{"type":30,"value":5053},{"type":20,"tag":90,"props":5091,"children":5092},{"style":117},[5093],{"type":30,"value":5094},"(model, ",{"type":20,"tag":90,"props":5096,"children":5097},{"style":129},[5098],{"type":30,"value":5063},{"type":20,"tag":90,"props":5100,"children":5101},{"style":117},[5102],{"type":30,"value":5068},{"type":20,"tag":90,"props":5104,"children":5105},{"style":123},[5106],{"type":30,"value":1717},{"type":20,"tag":90,"props":5108,"children":5109},{"style":123},[5110],{"type":30,"value":5111}," void",{"type":20,"tag":90,"props":5113,"children":5114},{"style":146},[5115],{"type":30,"value":5116}," 0",{"type":20,"tag":90,"props":5118,"children":5119},{"style":117},[5120],{"type":30,"value":2151},{"type":20,"tag":90,"props":5122,"children":5123},{"class":92,"line":2460},[5124],{"type":20,"tag":90,"props":5125,"children":5126},{"style":97},[5127],{"type":30,"value":5128},"        // If no url property has been specified, throw an error, as per the standard Backbone sync\n",{"type":20,"tag":90,"props":5130,"children":5131},{"class":92,"line":2468},[5132,5137,5142,5147,5152,5157],{"type":20,"tag":90,"props":5133,"children":5134},{"style":123},[5135],{"type":30,"value":5136},"        if",{"type":20,"tag":90,"props":5138,"children":5139},{"style":117},[5140],{"type":30,"value":5141}," (",{"type":20,"tag":90,"props":5143,"children":5144},{"style":123},[5145],{"type":30,"value":5146},"!",{"type":20,"tag":90,"props":5148,"children":5149},{"style":117},[5150],{"type":30,"value":5151},"opts.url) ",{"type":20,"tag":90,"props":5153,"children":5154},{"style":135},[5155],{"type":30,"value":5156},"urlError",{"type":20,"tag":90,"props":5158,"children":5159},{"style":117},[5160],{"type":30,"value":5161},"();\n",{"type":20,"tag":90,"props":5163,"children":5164},{"class":92,"line":2477},[5165],{"type":20,"tag":90,"props":5166,"children":5167},{"style":97},[5168],{"type":30,"value":5169},"        // Transform the url into a namespace\n",{"type":20,"tag":90,"props":5171,"children":5172},{"class":92,"line":2486},[5173,5178,5182,5187,5191,5196,5200,5204,5208],{"type":20,"tag":90,"props":5174,"children":5175},{"style":117},[5176],{"type":30,"value":5177},"        namespace ",{"type":20,"tag":90,"props":5179,"children":5180},{"style":123},[5181],{"type":30,"value":126},{"type":20,"tag":90,"props":5183,"children":5184},{"style":117},[5185],{"type":30,"value":5186}," Backbone.Model.",{"type":20,"tag":90,"props":5188,"children":5189},{"style":146},[5190],{"type":30,"value":4692},{"type":20,"tag":90,"props":5192,"children":5193},{"style":117},[5194],{"type":30,"value":5195},".namespace.",{"type":20,"tag":90,"props":5197,"children":5198},{"style":135},[5199],{"type":30,"value":4815},{"type":20,"tag":90,"props":5201,"children":5202},{"style":117},[5203],{"type":30,"value":4557},{"type":20,"tag":90,"props":5205,"children":5206},{"style":146},[5207],{"type":30,"value":4824},{"type":20,"tag":90,"props":5209,"children":5210},{"style":117},[5211],{"type":30,"value":5212},", opts.url);\n",{"type":20,"tag":90,"props":5214,"children":5215},{"class":92,"line":2494},[5216],{"type":20,"tag":90,"props":5217,"children":5218},{"style":97},[5219],{"type":30,"value":5220},"        // Determine what data we're sending, and ensure id is present if we're performing a PATCH call\n",{"type":20,"tag":90,"props":5222,"children":5223},{"class":92,"line":2503},[5224,5228,5232,5236,5241,5246,5251,5255,5260,5265,5270,5275,5280,5284],{"type":20,"tag":90,"props":5225,"children":5226},{"style":123},[5227],{"type":30,"value":5136},{"type":20,"tag":90,"props":5229,"children":5230},{"style":117},[5231],{"type":30,"value":5141},{"type":20,"tag":90,"props":5233,"children":5234},{"style":123},[5235],{"type":30,"value":5146},{"type":20,"tag":90,"props":5237,"children":5238},{"style":117},[5239],{"type":30,"value":5240},"opts.data ",{"type":20,"tag":90,"props":5242,"children":5243},{"style":123},[5244],{"type":30,"value":5245},"&&",{"type":20,"tag":90,"props":5247,"children":5248},{"style":117},[5249],{"type":30,"value":5250}," model) opts.data ",{"type":20,"tag":90,"props":5252,"children":5253},{"style":123},[5254],{"type":30,"value":126},{"type":20,"tag":90,"props":5256,"children":5257},{"style":117},[5258],{"type":30,"value":5259}," opts.attrs ",{"type":20,"tag":90,"props":5261,"children":5262},{"style":123},[5263],{"type":30,"value":5264},"||",{"type":20,"tag":90,"props":5266,"children":5267},{"style":117},[5268],{"type":30,"value":5269}," model.",{"type":20,"tag":90,"props":5271,"children":5272},{"style":135},[5273],{"type":30,"value":5274},"toJSON",{"type":20,"tag":90,"props":5276,"children":5277},{"style":117},[5278],{"type":30,"value":5279},"(options) ",{"type":20,"tag":90,"props":5281,"children":5282},{"style":123},[5283],{"type":30,"value":5264},{"type":20,"tag":90,"props":5285,"children":5286},{"style":117},[5287],{"type":30,"value":5288}," {};\n",{"type":20,"tag":90,"props":5290,"children":5291},{"class":92,"line":2521},[5292,5296,5301,5306,5311,5316,5321,5325,5329,5333,5337,5341,5346,5350,5355,5360],{"type":20,"tag":90,"props":5293,"children":5294},{"style":123},[5295],{"type":30,"value":5136},{"type":20,"tag":90,"props":5297,"children":5298},{"style":117},[5299],{"type":30,"value":5300}," ((opts.data.id ",{"type":20,"tag":90,"props":5302,"children":5303},{"style":123},[5304],{"type":30,"value":5305},"===",{"type":20,"tag":90,"props":5307,"children":5308},{"style":146},[5309],{"type":30,"value":5310}," null",{"type":20,"tag":90,"props":5312,"children":5313},{"style":123},[5314],{"type":30,"value":5315}," ||",{"type":20,"tag":90,"props":5317,"children":5318},{"style":117},[5319],{"type":30,"value":5320}," opts.data.id ",{"type":20,"tag":90,"props":5322,"children":5323},{"style":123},[5324],{"type":30,"value":5305},{"type":20,"tag":90,"props":5326,"children":5327},{"style":123},[5328],{"type":30,"value":5111},{"type":20,"tag":90,"props":5330,"children":5331},{"style":146},[5332],{"type":30,"value":5116},{"type":20,"tag":90,"props":5334,"children":5335},{"style":117},[5336],{"type":30,"value":5068},{"type":20,"tag":90,"props":5338,"children":5339},{"style":123},[5340],{"type":30,"value":5245},{"type":20,"tag":90,"props":5342,"children":5343},{"style":117},[5344],{"type":30,"value":5345}," opts.patch ",{"type":20,"tag":90,"props":5347,"children":5348},{"style":123},[5349],{"type":30,"value":5305},{"type":20,"tag":90,"props":5351,"children":5352},{"style":146},[5353],{"type":30,"value":5354}," true",{"type":20,"tag":90,"props":5356,"children":5357},{"style":123},[5358],{"type":30,"value":5359}," &&",{"type":20,"tag":90,"props":5361,"children":5362},{"style":117},[5363],{"type":30,"value":5364}," model){\n",{"type":20,"tag":90,"props":5366,"children":5367},{"class":92,"line":2529},[5368,5373,5377],{"type":20,"tag":90,"props":5369,"children":5370},{"style":117},[5371],{"type":30,"value":5372},"            opts.data.id ",{"type":20,"tag":90,"props":5374,"children":5375},{"style":123},[5376],{"type":30,"value":126},{"type":20,"tag":90,"props":5378,"children":5379},{"style":117},[5380],{"type":30,"value":5381}," model.id;\n",{"type":20,"tag":90,"props":5383,"children":5384},{"class":92,"line":2538},[5385],{"type":20,"tag":90,"props":5386,"children":5387},{"style":117},[5388],{"type":30,"value":5389},"        }\n",{"type":20,"tag":90,"props":5391,"children":5392},{"class":92,"line":2547},[5393],{"type":20,"tag":90,"props":5394,"children":5395},{"style":97},[5396],{"type":30,"value":5397},"        // Determine which websocket to use - set in options or on model\n",{"type":20,"tag":90,"props":5399,"children":5400},{"class":92,"line":2556},[5401,5406,5410,5415,5419],{"type":20,"tag":90,"props":5402,"children":5403},{"style":117},[5404],{"type":30,"value":5405},"        socket ",{"type":20,"tag":90,"props":5407,"children":5408},{"style":123},[5409],{"type":30,"value":126},{"type":20,"tag":90,"props":5411,"children":5412},{"style":117},[5413],{"type":30,"value":5414}," opts.socket ",{"type":20,"tag":90,"props":5416,"children":5417},{"style":123},[5418],{"type":30,"value":5264},{"type":20,"tag":90,"props":5420,"children":5421},{"style":117},[5422],{"type":30,"value":5423}," model.socket;\n",{"type":20,"tag":90,"props":5425,"children":5426},{"class":92,"line":2564},[5427],{"type":20,"tag":90,"props":5428,"children":5429},{"style":97},[5430],{"type":30,"value":5431},"        // Add a listener for our namespaced method, and resolve or reject our deferred based on the response\n",{"type":20,"tag":90,"props":5433,"children":5434},{"class":92,"line":2573},[5435,5440,5445,5450,5455,5460,5464,5468,5473],{"type":20,"tag":90,"props":5436,"children":5437},{"style":117},[5438],{"type":30,"value":5439},"        socket.",{"type":20,"tag":90,"props":5441,"children":5442},{"style":135},[5443],{"type":30,"value":5444},"once",{"type":20,"tag":90,"props":5446,"children":5447},{"style":117},[5448],{"type":30,"value":5449},"(namespace",{"type":20,"tag":90,"props":5451,"children":5452},{"style":123},[5453],{"type":30,"value":5454},"+",{"type":20,"tag":90,"props":5456,"children":5457},{"style":117},[5458],{"type":30,"value":5459},"method, ",{"type":20,"tag":90,"props":5461,"children":5462},{"style":123},[5463],{"type":30,"value":4562},{"type":20,"tag":90,"props":5465,"children":5466},{"style":117},[5467],{"type":30,"value":4557},{"type":20,"tag":90,"props":5469,"children":5470},{"style":4569},[5471],{"type":30,"value":5472},"res",{"type":20,"tag":90,"props":5474,"children":5475},{"style":117},[5476],{"type":30,"value":4603},{"type":20,"tag":90,"props":5478,"children":5479},{"class":92,"line":2582},[5480,5485,5490,5494,5499,5503,5508],{"type":20,"tag":90,"props":5481,"children":5482},{"style":123},[5483],{"type":30,"value":5484},"            var",{"type":20,"tag":90,"props":5486,"children":5487},{"style":117},[5488],{"type":30,"value":5489}," success ",{"type":20,"tag":90,"props":5491,"children":5492},{"style":123},[5493],{"type":30,"value":126},{"type":20,"tag":90,"props":5495,"children":5496},{"style":117},[5497],{"type":30,"value":5498}," (res ",{"type":20,"tag":90,"props":5500,"children":5501},{"style":123},[5502],{"type":30,"value":5245},{"type":20,"tag":90,"props":5504,"children":5505},{"style":117},[5506],{"type":30,"value":5507}," res.success); ",{"type":20,"tag":90,"props":5509,"children":5510},{"style":97},[5511],{"type":30,"value":5512},"// Expects server json response to contain a boolean 'success' field\n",{"type":20,"tag":90,"props":5514,"children":5515},{"class":92,"line":2600},[5516,5521],{"type":20,"tag":90,"props":5517,"children":5518},{"style":123},[5519],{"type":30,"value":5520},"            if",{"type":20,"tag":90,"props":5522,"children":5523},{"style":117},[5524],{"type":30,"value":5525}," (success)\n",{"type":20,"tag":90,"props":5527,"children":5528},{"class":92,"line":2608},[5529],{"type":20,"tag":90,"props":5530,"children":5531},{"style":117},[5532],{"type":30,"value":5533},"            {\n",{"type":20,"tag":90,"props":5535,"children":5536},{"class":92,"line":2626},[5537,5542,5547,5552,5557,5562],{"type":20,"tag":90,"props":5538,"children":5539},{"style":123},[5540],{"type":30,"value":5541},"                if",{"type":20,"tag":90,"props":5543,"children":5544},{"style":117},[5545],{"type":30,"value":5546}," (_.",{"type":20,"tag":90,"props":5548,"children":5549},{"style":135},[5550],{"type":30,"value":5551},"isFunction",{"type":20,"tag":90,"props":5553,"children":5554},{"style":117},[5555],{"type":30,"value":5556},"(options.success)) options.",{"type":20,"tag":90,"props":5558,"children":5559},{"style":135},[5560],{"type":30,"value":5561},"success",{"type":20,"tag":90,"props":5563,"children":5564},{"style":117},[5565],{"type":30,"value":5566},"(res);\n",{"type":20,"tag":90,"props":5568,"children":5569},{"class":92,"line":2634},[5570,5575,5580],{"type":20,"tag":90,"props":5571,"children":5572},{"style":117},[5573],{"type":30,"value":5574},"                defer.",{"type":20,"tag":90,"props":5576,"children":5577},{"style":135},[5578],{"type":30,"value":5579},"resolve",{"type":20,"tag":90,"props":5581,"children":5582},{"style":117},[5583],{"type":30,"value":5566},{"type":20,"tag":90,"props":5585,"children":5587},{"class":92,"line":5586},49,[5588,5593],{"type":20,"tag":90,"props":5589,"children":5590},{"style":123},[5591],{"type":30,"value":5592},"                return",{"type":20,"tag":90,"props":5594,"children":5595},{"style":117},[5596],{"type":30,"value":2151},{"type":20,"tag":90,"props":5598,"children":5600},{"class":92,"line":5599},50,[5601],{"type":20,"tag":90,"props":5602,"children":5603},{"style":117},[5604],{"type":30,"value":5605},"            }\n",{"type":20,"tag":90,"props":5607,"children":5609},{"class":92,"line":5608},51,[5610,5614,5618,5622,5627,5632],{"type":20,"tag":90,"props":5611,"children":5612},{"style":123},[5613],{"type":30,"value":5520},{"type":20,"tag":90,"props":5615,"children":5616},{"style":117},[5617],{"type":30,"value":5546},{"type":20,"tag":90,"props":5619,"children":5620},{"style":135},[5621],{"type":30,"value":5551},{"type":20,"tag":90,"props":5623,"children":5624},{"style":117},[5625],{"type":30,"value":5626},"(options.error)) options.",{"type":20,"tag":90,"props":5628,"children":5629},{"style":135},[5630],{"type":30,"value":5631},"error",{"type":20,"tag":90,"props":5633,"children":5634},{"style":117},[5635],{"type":30,"value":5566},{"type":20,"tag":90,"props":5637,"children":5639},{"class":92,"line":5638},52,[5640,5645,5650],{"type":20,"tag":90,"props":5641,"children":5642},{"style":117},[5643],{"type":30,"value":5644},"            defer.",{"type":20,"tag":90,"props":5646,"children":5647},{"style":135},[5648],{"type":30,"value":5649},"reject",{"type":20,"tag":90,"props":5651,"children":5652},{"style":117},[5653],{"type":30,"value":5566},{"type":20,"tag":90,"props":5655,"children":5657},{"class":92,"line":5656},53,[5658],{"type":20,"tag":90,"props":5659,"children":5660},{"style":117},[5661],{"type":30,"value":5662},"        });\n",{"type":20,"tag":90,"props":5664,"children":5666},{"class":92,"line":5665},54,[5667],{"type":20,"tag":90,"props":5668,"children":5669},{"emptyLinePlaceholder":107},[5670],{"type":30,"value":110},{"type":20,"tag":90,"props":5672,"children":5674},{"class":92,"line":5673},55,[5675],{"type":20,"tag":90,"props":5676,"children":5677},{"style":97},[5678],{"type":30,"value":5679},"        // Emit our namespaced method and the model+opts data\n",{"type":20,"tag":90,"props":5681,"children":5683},{"class":92,"line":5682},56,[5684,5688,5693,5697,5701],{"type":20,"tag":90,"props":5685,"children":5686},{"style":117},[5687],{"type":30,"value":5439},{"type":20,"tag":90,"props":5689,"children":5690},{"style":135},[5691],{"type":30,"value":5692},"emit",{"type":20,"tag":90,"props":5694,"children":5695},{"style":117},[5696],{"type":30,"value":5449},{"type":20,"tag":90,"props":5698,"children":5699},{"style":123},[5700],{"type":30,"value":5454},{"type":20,"tag":90,"props":5702,"children":5703},{"style":117},[5704],{"type":30,"value":5705},"method, opts.data);\n",{"type":20,"tag":90,"props":5707,"children":5709},{"class":92,"line":5708},57,[5710],{"type":20,"tag":90,"props":5711,"children":5712},{"emptyLinePlaceholder":107},[5713],{"type":30,"value":110},{"type":20,"tag":90,"props":5715,"children":5717},{"class":92,"line":5716},58,[5718],{"type":20,"tag":90,"props":5719,"children":5720},{"style":97},[5721],{"type":30,"value":5722},"        // Trigger the request event on the model, as per backbone spec\n",{"type":20,"tag":90,"props":5724,"children":5726},{"class":92,"line":5725},59,[5727,5732,5737,5741,5746],{"type":20,"tag":90,"props":5728,"children":5729},{"style":117},[5730],{"type":30,"value":5731},"        model.",{"type":20,"tag":90,"props":5733,"children":5734},{"style":135},[5735],{"type":30,"value":5736},"trigger",{"type":20,"tag":90,"props":5738,"children":5739},{"style":117},[5740],{"type":30,"value":4557},{"type":20,"tag":90,"props":5742,"children":5743},{"style":129},[5744],{"type":30,"value":5745},"'request'",{"type":20,"tag":90,"props":5747,"children":5748},{"style":117},[5749],{"type":30,"value":5750},", model, promise, opts);\n",{"type":20,"tag":90,"props":5752,"children":5754},{"class":92,"line":5753},60,[5755],{"type":20,"tag":90,"props":5756,"children":5757},{"style":97},[5758],{"type":30,"value":5759},"        // Return the promise for us to use as per usual (hanging .done blocks off, add to a .when, etc.)\n",{"type":20,"tag":90,"props":5761,"children":5763},{"class":92,"line":5762},61,[5764,5768],{"type":20,"tag":90,"props":5765,"children":5766},{"style":123},[5767],{"type":30,"value":4805},{"type":20,"tag":90,"props":5769,"children":5770},{"style":117},[5771],{"type":30,"value":5772}," promise;\n",{"type":20,"tag":90,"props":5774,"children":5776},{"class":92,"line":5775},62,[5777],{"type":20,"tag":90,"props":5778,"children":5779},{"style":117},[5780],{"type":30,"value":4837},{"type":20,"tag":90,"props":5782,"children":5784},{"class":92,"line":5783},63,[5785],{"type":20,"tag":90,"props":5786,"children":5787},{"emptyLinePlaceholder":107},[5788],{"type":30,"value":110},{"type":20,"tag":90,"props":5790,"children":5792},{"class":92,"line":5791},64,[5793],{"type":20,"tag":90,"props":5794,"children":5795},{"style":97},[5796],{"type":30,"value":4729},{"type":20,"tag":90,"props":5798,"children":5800},{"class":92,"line":5799},65,[5801],{"type":20,"tag":90,"props":5802,"children":5803},{"style":97},[5804],{"type":30,"value":5805},"     * Break url apart to create namespace - every '/' save any pre/post-fixing the url will become a ':' indicating\n",{"type":20,"tag":90,"props":5807,"children":5809},{"class":92,"line":5808},66,[5810],{"type":20,"tag":90,"props":5811,"children":5812},{"style":97},[5813],{"type":30,"value":5814},"     * namespace - so a collection that maps to /api/posts will now have its events on the namespace\n",{"type":20,"tag":90,"props":5816,"children":5818},{"class":92,"line":5817},67,[5819],{"type":20,"tag":90,"props":5820,"children":5821},{"style":97},[5822],{"type":30,"value":5823},"     * api:posts: (ie. api:posts:create, api:posts:delete, etc.), and a model that maps to /api/posts/21\n",{"type":20,"tag":90,"props":5825,"children":5827},{"class":92,"line":5826},68,[5828],{"type":20,"tag":90,"props":5829,"children":5830},{"style":97},[5831],{"type":30,"value":5832},"     * will have events on api:posts:21: (ie. api:posts:21:update, api:posts:21:patch, etc.)\n",{"type":20,"tag":90,"props":5834,"children":5836},{"class":92,"line":5835},69,[5837,5842,5847,5852],{"type":20,"tag":90,"props":5838,"children":5839},{"style":97},[5840],{"type":30,"value":5841},"     * ",{"type":20,"tag":90,"props":5843,"children":5844},{"style":123},[5845],{"type":30,"value":5846},"@param",{"type":20,"tag":90,"props":5848,"children":5849},{"style":135},[5850],{"type":30,"value":5851}," {string=}",{"type":20,"tag":90,"props":5853,"children":5854},{"style":117},[5855],{"type":30,"value":5856}," url\n",{"type":20,"tag":90,"props":5858,"children":5860},{"class":92,"line":5859},70,[5861],{"type":20,"tag":90,"props":5862,"children":5863},{"style":97},[5864],{"type":30,"value":4745},{"type":20,"tag":90,"props":5866,"children":5868},{"class":92,"line":5867},71,[5869,5874,5878,5882,5887,5891,5895,5899,5904],{"type":20,"tag":90,"props":5870,"children":5871},{"style":117},[5872],{"type":30,"value":5873},"    Backbone.Model.",{"type":20,"tag":90,"props":5875,"children":5876},{"style":146},[5877],{"type":30,"value":4692},{"type":20,"tag":90,"props":5879,"children":5880},{"style":117},[5881],{"type":30,"value":615},{"type":20,"tag":90,"props":5883,"children":5884},{"style":135},[5885],{"type":30,"value":5886},"namespace",{"type":20,"tag":90,"props":5888,"children":5889},{"style":123},[5890],{"type":30,"value":1113},{"type":20,"tag":90,"props":5892,"children":5893},{"style":123},[5894],{"type":30,"value":4625},{"type":20,"tag":90,"props":5896,"children":5897},{"style":117},[5898],{"type":30,"value":4557},{"type":20,"tag":90,"props":5900,"children":5901},{"style":4569},[5902],{"type":30,"value":5903},"url",{"type":20,"tag":90,"props":5905,"children":5906},{"style":117},[5907],{"type":30,"value":4603},{"type":20,"tag":90,"props":5909,"children":5911},{"class":92,"line":5910},72,[5912,5917,5921,5926,5930,5935,5939,5943],{"type":20,"tag":90,"props":5913,"children":5914},{"style":117},[5915],{"type":30,"value":5916},"        url ",{"type":20,"tag":90,"props":5918,"children":5919},{"style":123},[5920],{"type":30,"value":126},{"type":20,"tag":90,"props":5922,"children":5923},{"style":117},[5924],{"type":30,"value":5925}," url ",{"type":20,"tag":90,"props":5927,"children":5928},{"style":123},[5929],{"type":30,"value":5264},{"type":20,"tag":90,"props":5931,"children":5932},{"style":146},[5933],{"type":30,"value":5934}," this",{"type":20,"tag":90,"props":5936,"children":5937},{"style":117},[5938],{"type":30,"value":615},{"type":20,"tag":90,"props":5940,"children":5941},{"style":135},[5942],{"type":30,"value":5903},{"type":20,"tag":90,"props":5944,"children":5945},{"style":117},[5946],{"type":30,"value":5161},{"type":20,"tag":90,"props":5948,"children":5950},{"class":92,"line":5949},73,[5951,5955,5959,5964,5969,5974,5979,5984,5988,5992,5996,6001,6005,6009,6014],{"type":20,"tag":90,"props":5952,"children":5953},{"style":123},[5954],{"type":30,"value":4805},{"type":20,"tag":90,"props":5956,"children":5957},{"style":117},[5958],{"type":30,"value":4936},{"type":20,"tag":90,"props":5960,"children":5961},{"style":135},[5962],{"type":30,"value":5963},"trim",{"type":20,"tag":90,"props":5965,"children":5966},{"style":117},[5967],{"type":30,"value":5968},"(url, ",{"type":20,"tag":90,"props":5970,"children":5971},{"style":129},[5972],{"type":30,"value":5973},"'/'",{"type":20,"tag":90,"props":5975,"children":5976},{"style":117},[5977],{"type":30,"value":5978},").",{"type":20,"tag":90,"props":5980,"children":5981},{"style":135},[5982],{"type":30,"value":5983},"replace",{"type":20,"tag":90,"props":5985,"children":5986},{"style":117},[5987],{"type":30,"value":4557},{"type":20,"tag":90,"props":5989,"children":5990},{"style":129},[5991],{"type":30,"value":5973},{"type":20,"tag":90,"props":5993,"children":5994},{"style":117},[5995],{"type":30,"value":1260},{"type":20,"tag":90,"props":5997,"children":5998},{"style":129},[5999],{"type":30,"value":6000},"':'",{"type":20,"tag":90,"props":6002,"children":6003},{"style":117},[6004],{"type":30,"value":5068},{"type":20,"tag":90,"props":6006,"children":6007},{"style":123},[6008],{"type":30,"value":5454},{"type":20,"tag":90,"props":6010,"children":6011},{"style":129},[6012],{"type":30,"value":6013}," \":\"",{"type":20,"tag":90,"props":6015,"children":6016},{"style":117},[6017],{"type":30,"value":2151},{"type":20,"tag":90,"props":6019,"children":6021},{"class":92,"line":6020},74,[6022],{"type":20,"tag":90,"props":6023,"children":6024},{"style":117},[6025],{"type":30,"value":4837},{"type":20,"tag":90,"props":6027,"children":6029},{"class":92,"line":6028},75,[6030],{"type":20,"tag":90,"props":6031,"children":6032},{"emptyLinePlaceholder":107},[6033],{"type":30,"value":110},{"type":20,"tag":90,"props":6035,"children":6037},{"class":92,"line":6036},76,[6038],{"type":20,"tag":90,"props":6039,"children":6040},{"style":97},[6041],{"type":30,"value":4729},{"type":20,"tag":90,"props":6043,"children":6045},{"class":92,"line":6044},77,[6046],{"type":20,"tag":90,"props":6047,"children":6048},{"style":97},[6049],{"type":30,"value":6050},"     * Override EventEmitter.emit and SocketNamespace reference for socket.io to add a catch all case for the\n",{"type":20,"tag":90,"props":6052,"children":6054},{"class":92,"line":6053},78,[6055],{"type":20,"tag":90,"props":6056,"children":6057},{"style":97},[6058],{"type":30,"value":6059},"     * wildcard ('*') character. Now, socket.on('*') will catch any event, with the name of the caught event\n",{"type":20,"tag":90,"props":6061,"children":6063},{"class":92,"line":6062},79,[6064],{"type":20,"tag":90,"props":6065,"children":6066},{"style":97},[6067],{"type":30,"value":6068},"     * passed to the handler as the first argument.\n",{"type":20,"tag":90,"props":6070,"children":6072},{"class":92,"line":6071},80,[6073],{"type":20,"tag":90,"props":6074,"children":6075},{"style":97},[6076],{"type":30,"value":6077},"    */\n",{"type":20,"tag":90,"props":6079,"children":6081},{"class":92,"line":6080},81,[6082,6087,6091,6095,6099,6103,6107,6111,6116],{"type":20,"tag":90,"props":6083,"children":6084},{"style":117},[6085],{"type":30,"value":6086},"    io.EventEmitter.",{"type":20,"tag":90,"props":6088,"children":6089},{"style":146},[6090],{"type":30,"value":4692},{"type":20,"tag":90,"props":6092,"children":6093},{"style":117},[6094],{"type":30,"value":615},{"type":20,"tag":90,"props":6096,"children":6097},{"style":135},[6098],{"type":30,"value":5692},{"type":20,"tag":90,"props":6100,"children":6101},{"style":123},[6102],{"type":30,"value":1113},{"type":20,"tag":90,"props":6104,"children":6105},{"style":123},[6106],{"type":30,"value":4625},{"type":20,"tag":90,"props":6108,"children":6109},{"style":117},[6110],{"type":30,"value":4557},{"type":20,"tag":90,"props":6112,"children":6113},{"style":4569},[6114],{"type":30,"value":6115},"name",{"type":20,"tag":90,"props":6117,"children":6118},{"style":117},[6119],{"type":30,"value":4603},{"type":20,"tag":90,"props":6121,"children":6123},{"class":92,"line":6122},82,[6124,6128,6133,6137,6142,6146,6150,6155,6159,6163,6168,6172,6177],{"type":20,"tag":90,"props":6125,"children":6126},{"style":123},[6127],{"type":30,"value":4922},{"type":20,"tag":90,"props":6129,"children":6130},{"style":117},[6131],{"type":30,"value":6132}," args ",{"type":20,"tag":90,"props":6134,"children":6135},{"style":123},[6136],{"type":30,"value":126},{"type":20,"tag":90,"props":6138,"children":6139},{"style":146},[6140],{"type":30,"value":6141}," Array",{"type":20,"tag":90,"props":6143,"children":6144},{"style":117},[6145],{"type":30,"value":615},{"type":20,"tag":90,"props":6147,"children":6148},{"style":146},[6149],{"type":30,"value":4692},{"type":20,"tag":90,"props":6151,"children":6152},{"style":117},[6153],{"type":30,"value":6154},".slice.",{"type":20,"tag":90,"props":6156,"children":6157},{"style":135},[6158],{"type":30,"value":4815},{"type":20,"tag":90,"props":6160,"children":6161},{"style":117},[6162],{"type":30,"value":4557},{"type":20,"tag":90,"props":6164,"children":6165},{"style":146},[6166],{"type":30,"value":6167},"arguments",{"type":20,"tag":90,"props":6169,"children":6170},{"style":117},[6171],{"type":30,"value":1260},{"type":20,"tag":90,"props":6173,"children":6174},{"style":146},[6175],{"type":30,"value":6176},"1",{"type":20,"tag":90,"props":6178,"children":6179},{"style":117},[6180],{"type":30,"value":4662},{"type":20,"tag":90,"props":6182,"children":6184},{"class":92,"line":6183},83,[6185],{"type":20,"tag":90,"props":6186,"children":6187},{"emptyLinePlaceholder":107},[6188],{"type":30,"value":110},{"type":20,"tag":90,"props":6190,"children":6192},{"class":92,"line":6191},84,[6193,6198,6203,6207,6211,6216,6221,6226,6231],{"type":20,"tag":90,"props":6194,"children":6195},{"style":117},[6196],{"type":30,"value":6197},"        eventEmit.",{"type":20,"tag":90,"props":6199,"children":6200},{"style":135},[6201],{"type":30,"value":6202},"apply",{"type":20,"tag":90,"props":6204,"children":6205},{"style":117},[6206],{"type":30,"value":4557},{"type":20,"tag":90,"props":6208,"children":6209},{"style":146},[6210],{"type":30,"value":4824},{"type":20,"tag":90,"props":6212,"children":6213},{"style":117},[6214],{"type":30,"value":6215},", [",{"type":20,"tag":90,"props":6217,"children":6218},{"style":129},[6219],{"type":30,"value":6220},"'*'",{"type":20,"tag":90,"props":6222,"children":6223},{"style":117},[6224],{"type":30,"value":6225},", name].",{"type":20,"tag":90,"props":6227,"children":6228},{"style":135},[6229],{"type":30,"value":6230},"concat",{"type":20,"tag":90,"props":6232,"children":6233},{"style":117},[6234],{"type":30,"value":6235},"(args));\n",{"type":20,"tag":90,"props":6237,"children":6239},{"class":92,"line":6238},85,[6240,6244,6248,6252,6256,6261,6265],{"type":20,"tag":90,"props":6241,"children":6242},{"style":117},[6243],{"type":30,"value":6197},{"type":20,"tag":90,"props":6245,"children":6246},{"style":135},[6247],{"type":30,"value":6202},{"type":20,"tag":90,"props":6249,"children":6250},{"style":117},[6251],{"type":30,"value":4557},{"type":20,"tag":90,"props":6253,"children":6254},{"style":146},[6255],{"type":30,"value":4824},{"type":20,"tag":90,"props":6257,"children":6258},{"style":117},[6259],{"type":30,"value":6260},", [name].",{"type":20,"tag":90,"props":6262,"children":6263},{"style":135},[6264],{"type":30,"value":6230},{"type":20,"tag":90,"props":6266,"children":6267},{"style":117},[6268],{"type":30,"value":6235},{"type":20,"tag":90,"props":6270,"children":6272},{"class":92,"line":6271},86,[6273],{"type":20,"tag":90,"props":6274,"children":6275},{"style":117},[6276],{"type":30,"value":4837},{"type":20,"tag":90,"props":6278,"children":6280},{"class":92,"line":6279},87,[6281,6286,6290,6295,6299,6303,6307],{"type":20,"tag":90,"props":6282,"children":6283},{"style":117},[6284],{"type":30,"value":6285},"    io.SocketNamespace.",{"type":20,"tag":90,"props":6287,"children":6288},{"style":146},[6289],{"type":30,"value":4692},{"type":20,"tag":90,"props":6291,"children":6292},{"style":117},[6293],{"type":30,"value":6294},".$emit ",{"type":20,"tag":90,"props":6296,"children":6297},{"style":123},[6298],{"type":30,"value":126},{"type":20,"tag":90,"props":6300,"children":6301},{"style":117},[6302],{"type":30,"value":4687},{"type":20,"tag":90,"props":6304,"children":6305},{"style":146},[6306],{"type":30,"value":4692},{"type":20,"tag":90,"props":6308,"children":6309},{"style":117},[6310],{"type":30,"value":6311},".emit;\n",{"type":20,"tag":90,"props":6313,"children":6315},{"class":92,"line":6314},88,[6316],{"type":20,"tag":90,"props":6317,"children":6318},{"style":117},[6319],{"type":30,"value":6320},"})(Backbone, jQuery, _, io);\n",{"type":20,"tag":21,"props":6322,"children":6323},{},[6324],{"type":30,"value":6325},"So, let's start at the top (and the very bottom).",{"type":20,"tag":79,"props":6327,"children":6329},{"className":4503,"code":6328,"language":4505,"meta":8,"style":8},"(function(Backbone, $, _, io){\n    var urlError = function(){\n        throw new Error('A \"url\" property or function must be specified.');\n    },\n    eventEmit = io.EventEmitter.prototype.emit,\n    ajaxSync = Backbone.sync;\n\n    //... More code ...\n\n    })(Backbone, jQuery, _, io);\n",[6330],{"type":20,"tag":86,"props":6331,"children":6332},{"__ignoreMap":8},[6333,6380,6403,6430,6437,6461,6477,6484,6492,6499],{"type":20,"tag":90,"props":6334,"children":6335},{"class":92,"line":93},[6336,6340,6344,6348,6352,6356,6360,6364,6368,6372,6376],{"type":20,"tag":90,"props":6337,"children":6338},{"style":117},[6339],{"type":30,"value":4557},{"type":20,"tag":90,"props":6341,"children":6342},{"style":123},[6343],{"type":30,"value":4562},{"type":20,"tag":90,"props":6345,"children":6346},{"style":117},[6347],{"type":30,"value":4557},{"type":20,"tag":90,"props":6349,"children":6350},{"style":4569},[6351],{"type":30,"value":4572},{"type":20,"tag":90,"props":6353,"children":6354},{"style":117},[6355],{"type":30,"value":1260},{"type":20,"tag":90,"props":6357,"children":6358},{"style":4569},[6359],{"type":30,"value":2452},{"type":20,"tag":90,"props":6361,"children":6362},{"style":117},[6363],{"type":30,"value":1260},{"type":20,"tag":90,"props":6365,"children":6366},{"style":4569},[6367],{"type":30,"value":4589},{"type":20,"tag":90,"props":6369,"children":6370},{"style":117},[6371],{"type":30,"value":1260},{"type":20,"tag":90,"props":6373,"children":6374},{"style":4569},[6375],{"type":30,"value":4598},{"type":20,"tag":90,"props":6377,"children":6378},{"style":117},[6379],{"type":30,"value":4603},{"type":20,"tag":90,"props":6381,"children":6382},{"class":92,"line":103},[6383,6387,6391,6395,6399],{"type":20,"tag":90,"props":6384,"children":6385},{"style":123},[6386],{"type":30,"value":4611},{"type":20,"tag":90,"props":6388,"children":6389},{"style":135},[6390],{"type":30,"value":4616},{"type":20,"tag":90,"props":6392,"children":6393},{"style":123},[6394],{"type":30,"value":1113},{"type":20,"tag":90,"props":6396,"children":6397},{"style":123},[6398],{"type":30,"value":4625},{"type":20,"tag":90,"props":6400,"children":6401},{"style":117},[6402],{"type":30,"value":4630},{"type":20,"tag":90,"props":6404,"children":6405},{"class":92,"line":113},[6406,6410,6414,6418,6422,6426],{"type":20,"tag":90,"props":6407,"children":6408},{"style":123},[6409],{"type":30,"value":4638},{"type":20,"tag":90,"props":6411,"children":6412},{"style":123},[6413],{"type":30,"value":4643},{"type":20,"tag":90,"props":6415,"children":6416},{"style":135},[6417],{"type":30,"value":4648},{"type":20,"tag":90,"props":6419,"children":6420},{"style":117},[6421],{"type":30,"value":4557},{"type":20,"tag":90,"props":6423,"children":6424},{"style":129},[6425],{"type":30,"value":4657},{"type":20,"tag":90,"props":6427,"children":6428},{"style":117},[6429],{"type":30,"value":4662},{"type":20,"tag":90,"props":6431,"children":6432},{"class":92,"line":152},[6433],{"type":20,"tag":90,"props":6434,"children":6435},{"style":117},[6436],{"type":30,"value":4670},{"type":20,"tag":90,"props":6438,"children":6439},{"class":92,"line":160},[6440,6445,6449,6453,6457],{"type":20,"tag":90,"props":6441,"children":6442},{"style":117},[6443],{"type":30,"value":6444},"    eventEmit ",{"type":20,"tag":90,"props":6446,"children":6447},{"style":123},[6448],{"type":30,"value":126},{"type":20,"tag":90,"props":6450,"children":6451},{"style":117},[6452],{"type":30,"value":4687},{"type":20,"tag":90,"props":6454,"children":6455},{"style":146},[6456],{"type":30,"value":4692},{"type":20,"tag":90,"props":6458,"children":6459},{"style":117},[6460],{"type":30,"value":4697},{"type":20,"tag":90,"props":6462,"children":6463},{"class":92,"line":174},[6464,6469,6473],{"type":20,"tag":90,"props":6465,"children":6466},{"style":117},[6467],{"type":30,"value":6468},"    ajaxSync ",{"type":20,"tag":90,"props":6470,"children":6471},{"style":123},[6472],{"type":30,"value":126},{"type":20,"tag":90,"props":6474,"children":6475},{"style":117},[6476],{"type":30,"value":4714},{"type":20,"tag":90,"props":6478,"children":6479},{"class":92,"line":183},[6480],{"type":20,"tag":90,"props":6481,"children":6482},{"emptyLinePlaceholder":107},[6483],{"type":30,"value":110},{"type":20,"tag":90,"props":6485,"children":6486},{"class":92,"line":191},[6487],{"type":20,"tag":90,"props":6488,"children":6489},{"style":97},[6490],{"type":30,"value":6491},"    //... More code ...\n",{"type":20,"tag":90,"props":6493,"children":6494},{"class":92,"line":200},[6495],{"type":20,"tag":90,"props":6496,"children":6497},{"emptyLinePlaceholder":107},[6498],{"type":30,"value":110},{"type":20,"tag":90,"props":6500,"children":6501},{"class":92,"line":229},[6502],{"type":20,"tag":90,"props":6503,"children":6504},{"style":117},[6505],{"type":30,"value":6506},"    })(Backbone, jQuery, _, io);\n",{"type":20,"tag":21,"props":6508,"children":6509},{},[6510],{"type":30,"value":6511},"We create a function expression, and feed it the expected globals - a reference to Backbone, jQuery, underscore and socket.io, in that order. At the top, we're reproducing backbone's standard urlError function, and then we're saving a reference to io's emit (more on that in a bit), and to the original, ajax-based sync.",{"type":20,"tag":79,"props":6513,"children":6515},{"className":4503,"code":6514,"language":4505,"meta":8,"style":8},"/**\n * Preserve the standard, jquery ajax based persistance method as ajaxSync.\n */\nBackbone.ajaxSync = function(method, model, options){\n    return ajaxSync.call(this, method, model, options);\n};\n",[6516],{"type":20,"tag":86,"props":6517,"children":6518},{"__ignoreMap":8},[6519,6526,6534,6541,6589,6617],{"type":20,"tag":90,"props":6520,"children":6521},{"class":92,"line":93},[6522],{"type":20,"tag":90,"props":6523,"children":6524},{"style":97},[6525],{"type":30,"value":4517},{"type":20,"tag":90,"props":6527,"children":6528},{"class":92,"line":103},[6529],{"type":20,"tag":90,"props":6530,"children":6531},{"style":97},[6532],{"type":30,"value":6533}," * Preserve the standard, jquery ajax based persistance method as ajaxSync.\n",{"type":20,"tag":90,"props":6535,"children":6536},{"class":92,"line":113},[6537],{"type":20,"tag":90,"props":6538,"children":6539},{"style":97},[6540],{"type":30,"value":4549},{"type":20,"tag":90,"props":6542,"children":6543},{"class":92,"line":152},[6544,6549,6553,6557,6561,6565,6569,6573,6577,6581,6585],{"type":20,"tag":90,"props":6545,"children":6546},{"style":117},[6547],{"type":30,"value":6548},"Backbone.",{"type":20,"tag":90,"props":6550,"children":6551},{"style":135},[6552],{"type":30,"value":4758},{"type":20,"tag":90,"props":6554,"children":6555},{"style":123},[6556],{"type":30,"value":1113},{"type":20,"tag":90,"props":6558,"children":6559},{"style":123},[6560],{"type":30,"value":4625},{"type":20,"tag":90,"props":6562,"children":6563},{"style":117},[6564],{"type":30,"value":4557},{"type":20,"tag":90,"props":6566,"children":6567},{"style":4569},[6568],{"type":30,"value":4775},{"type":20,"tag":90,"props":6570,"children":6571},{"style":117},[6572],{"type":30,"value":1260},{"type":20,"tag":90,"props":6574,"children":6575},{"style":4569},[6576],{"type":30,"value":4784},{"type":20,"tag":90,"props":6578,"children":6579},{"style":117},[6580],{"type":30,"value":1260},{"type":20,"tag":90,"props":6582,"children":6583},{"style":4569},[6584],{"type":30,"value":4793},{"type":20,"tag":90,"props":6586,"children":6587},{"style":117},[6588],{"type":30,"value":4603},{"type":20,"tag":90,"props":6590,"children":6591},{"class":92,"line":160},[6592,6597,6601,6605,6609,6613],{"type":20,"tag":90,"props":6593,"children":6594},{"style":123},[6595],{"type":30,"value":6596},"    return",{"type":20,"tag":90,"props":6598,"children":6599},{"style":117},[6600],{"type":30,"value":4810},{"type":20,"tag":90,"props":6602,"children":6603},{"style":135},[6604],{"type":30,"value":4815},{"type":20,"tag":90,"props":6606,"children":6607},{"style":117},[6608],{"type":30,"value":4557},{"type":20,"tag":90,"props":6610,"children":6611},{"style":146},[6612],{"type":30,"value":4824},{"type":20,"tag":90,"props":6614,"children":6615},{"style":117},[6616],{"type":30,"value":4829},{"type":20,"tag":90,"props":6618,"children":6619},{"class":92,"line":174},[6620],{"type":20,"tag":90,"props":6621,"children":6622},{"style":117},[6623],{"type":30,"value":6624},"};\n",{"type":20,"tag":21,"props":6626,"children":6627},{},[6628,6630,6635,6637,6642],{"type":30,"value":6629},"The comment says it all - we're preserving the standard ",{"type":20,"tag":86,"props":6631,"children":6633},{"className":6632},[],[6634],{"type":30,"value":4878},{"type":30,"value":6636}," as ",{"type":20,"tag":86,"props":6638,"children":6640},{"className":6639},[],[6641],{"type":30,"value":4758},{"type":30,"value":6643},", so if we want some collection or model to use the standard persistence method, we can.",{"type":20,"tag":21,"props":6645,"children":6646},{},[6647],{"type":30,"value":6648},"We can specify ajaxSync as our preferred sync method when we extend the collection:",{"type":20,"tag":79,"props":6650,"children":6652},{"className":4503,"code":6651,"language":4505,"meta":8,"style":8},"var collection = new (Backbone.Collection.extend({url:'/api/url', model:Backbone.Model, sync:Backbone.ajaxSync}))();\n",[6653],{"type":20,"tag":86,"props":6654,"children":6655},{"__ignoreMap":8},[6656],{"type":20,"tag":90,"props":6657,"children":6658},{"class":92,"line":93},[6659,6664,6669,6673,6677,6682,6686,6691,6696],{"type":20,"tag":90,"props":6660,"children":6661},{"style":123},[6662],{"type":30,"value":6663},"var",{"type":20,"tag":90,"props":6665,"children":6666},{"style":117},[6667],{"type":30,"value":6668}," collection ",{"type":20,"tag":90,"props":6670,"children":6671},{"style":123},[6672],{"type":30,"value":126},{"type":20,"tag":90,"props":6674,"children":6675},{"style":123},[6676],{"type":30,"value":4643},{"type":20,"tag":90,"props":6678,"children":6679},{"style":117},[6680],{"type":30,"value":6681}," (Backbone.Collection.",{"type":20,"tag":90,"props":6683,"children":6684},{"style":135},[6685],{"type":30,"value":4941},{"type":20,"tag":90,"props":6687,"children":6688},{"style":117},[6689],{"type":30,"value":6690},"({url:",{"type":20,"tag":90,"props":6692,"children":6693},{"style":129},[6694],{"type":30,"value":6695},"'/api/url'",{"type":20,"tag":90,"props":6697,"children":6698},{"style":117},[6699],{"type":30,"value":6700},", model:Backbone.Model, sync:Backbone.ajaxSync}))();\n",{"type":20,"tag":79,"props":6702,"children":6704},{"className":4503,"code":6703,"language":4505,"meta":8,"style":8},"/**\n * Replace the standard sync function with our new, websocket/socket.io based solution.\n */\nBackbone.sync = function(method, model, options){\n    var opts = _.extend({}, options),\n    defer = $.Deferred(),\n    promise = defer.promise(),\n    namespace,\n    socket;\n\n    opts.url = (opts.url) ? _.result(opts, 'url') : (model.url) ? _.result(model, 'url') : void 0;\n    // If no url property has been specified, throw an error, as per the standard Backbone sync\n    if (!opts.url) urlError();\n    // Transform the url into a namespace\n    namespace = Backbone.Model.prototype.namespace.call(this, opts.url);\n",[6705],{"type":20,"tag":86,"props":6706,"children":6707},{"__ignoreMap":8},[6708,6715,6723,6730,6777,6804,6828,6852,6860,6868,6875,6963,6971,6999,7007],{"type":20,"tag":90,"props":6709,"children":6710},{"class":92,"line":93},[6711],{"type":20,"tag":90,"props":6712,"children":6713},{"style":97},[6714],{"type":30,"value":4517},{"type":20,"tag":90,"props":6716,"children":6717},{"class":92,"line":103},[6718],{"type":20,"tag":90,"props":6719,"children":6720},{"style":97},[6721],{"type":30,"value":6722}," * Replace the standard sync function with our new, websocket/socket.io based solution.\n",{"type":20,"tag":90,"props":6724,"children":6725},{"class":92,"line":113},[6726],{"type":20,"tag":90,"props":6727,"children":6728},{"style":97},[6729],{"type":30,"value":4549},{"type":20,"tag":90,"props":6731,"children":6732},{"class":92,"line":152},[6733,6737,6741,6745,6749,6753,6757,6761,6765,6769,6773],{"type":20,"tag":90,"props":6734,"children":6735},{"style":117},[6736],{"type":30,"value":6548},{"type":20,"tag":90,"props":6738,"children":6739},{"style":135},[6740],{"type":30,"value":4878},{"type":20,"tag":90,"props":6742,"children":6743},{"style":123},[6744],{"type":30,"value":1113},{"type":20,"tag":90,"props":6746,"children":6747},{"style":123},[6748],{"type":30,"value":4625},{"type":20,"tag":90,"props":6750,"children":6751},{"style":117},[6752],{"type":30,"value":4557},{"type":20,"tag":90,"props":6754,"children":6755},{"style":4569},[6756],{"type":30,"value":4775},{"type":20,"tag":90,"props":6758,"children":6759},{"style":117},[6760],{"type":30,"value":1260},{"type":20,"tag":90,"props":6762,"children":6763},{"style":4569},[6764],{"type":30,"value":4784},{"type":20,"tag":90,"props":6766,"children":6767},{"style":117},[6768],{"type":30,"value":1260},{"type":20,"tag":90,"props":6770,"children":6771},{"style":4569},[6772],{"type":30,"value":4793},{"type":20,"tag":90,"props":6774,"children":6775},{"style":117},[6776],{"type":30,"value":4603},{"type":20,"tag":90,"props":6778,"children":6779},{"class":92,"line":160},[6780,6784,6788,6792,6796,6800],{"type":20,"tag":90,"props":6781,"children":6782},{"style":123},[6783],{"type":30,"value":4611},{"type":20,"tag":90,"props":6785,"children":6786},{"style":117},[6787],{"type":30,"value":4927},{"type":20,"tag":90,"props":6789,"children":6790},{"style":123},[6791],{"type":30,"value":126},{"type":20,"tag":90,"props":6793,"children":6794},{"style":117},[6795],{"type":30,"value":4936},{"type":20,"tag":90,"props":6797,"children":6798},{"style":135},[6799],{"type":30,"value":4941},{"type":20,"tag":90,"props":6801,"children":6802},{"style":117},[6803],{"type":30,"value":4946},{"type":20,"tag":90,"props":6805,"children":6806},{"class":92,"line":174},[6807,6812,6816,6820,6824],{"type":20,"tag":90,"props":6808,"children":6809},{"style":117},[6810],{"type":30,"value":6811},"    defer ",{"type":20,"tag":90,"props":6813,"children":6814},{"style":123},[6815],{"type":30,"value":126},{"type":20,"tag":90,"props":6817,"children":6818},{"style":117},[6819],{"type":30,"value":4963},{"type":20,"tag":90,"props":6821,"children":6822},{"style":135},[6823],{"type":30,"value":4968},{"type":20,"tag":90,"props":6825,"children":6826},{"style":117},[6827],{"type":30,"value":4973},{"type":20,"tag":90,"props":6829,"children":6830},{"class":92,"line":183},[6831,6836,6840,6844,6848],{"type":20,"tag":90,"props":6832,"children":6833},{"style":117},[6834],{"type":30,"value":6835},"    promise ",{"type":20,"tag":90,"props":6837,"children":6838},{"style":123},[6839],{"type":30,"value":126},{"type":20,"tag":90,"props":6841,"children":6842},{"style":117},[6843],{"type":30,"value":4990},{"type":20,"tag":90,"props":6845,"children":6846},{"style":135},[6847],{"type":30,"value":4995},{"type":20,"tag":90,"props":6849,"children":6850},{"style":117},[6851],{"type":30,"value":4973},{"type":20,"tag":90,"props":6853,"children":6854},{"class":92,"line":191},[6855],{"type":20,"tag":90,"props":6856,"children":6857},{"style":117},[6858],{"type":30,"value":6859},"    namespace,\n",{"type":20,"tag":90,"props":6861,"children":6862},{"class":92,"line":200},[6863],{"type":20,"tag":90,"props":6864,"children":6865},{"style":117},[6866],{"type":30,"value":6867},"    socket;\n",{"type":20,"tag":90,"props":6869,"children":6870},{"class":92,"line":229},[6871],{"type":20,"tag":90,"props":6872,"children":6873},{"emptyLinePlaceholder":107},[6874],{"type":30,"value":110},{"type":20,"tag":90,"props":6876,"children":6877},{"class":92,"line":247},[6878,6883,6887,6891,6895,6899,6903,6907,6911,6915,6919,6923,6927,6931,6935,6939,6943,6947,6951,6955,6959],{"type":20,"tag":90,"props":6879,"children":6880},{"style":117},[6881],{"type":30,"value":6882},"    opts.url ",{"type":20,"tag":90,"props":6884,"children":6885},{"style":123},[6886],{"type":30,"value":126},{"type":20,"tag":90,"props":6888,"children":6889},{"style":117},[6890],{"type":30,"value":5039},{"type":20,"tag":90,"props":6892,"children":6893},{"style":123},[6894],{"type":30,"value":5044},{"type":20,"tag":90,"props":6896,"children":6897},{"style":117},[6898],{"type":30,"value":4936},{"type":20,"tag":90,"props":6900,"children":6901},{"style":135},[6902],{"type":30,"value":5053},{"type":20,"tag":90,"props":6904,"children":6905},{"style":117},[6906],{"type":30,"value":5058},{"type":20,"tag":90,"props":6908,"children":6909},{"style":129},[6910],{"type":30,"value":5063},{"type":20,"tag":90,"props":6912,"children":6913},{"style":117},[6914],{"type":30,"value":5068},{"type":20,"tag":90,"props":6916,"children":6917},{"style":123},[6918],{"type":30,"value":1717},{"type":20,"tag":90,"props":6920,"children":6921},{"style":117},[6922],{"type":30,"value":5077},{"type":20,"tag":90,"props":6924,"children":6925},{"style":123},[6926],{"type":30,"value":5044},{"type":20,"tag":90,"props":6928,"children":6929},{"style":117},[6930],{"type":30,"value":4936},{"type":20,"tag":90,"props":6932,"children":6933},{"style":135},[6934],{"type":30,"value":5053},{"type":20,"tag":90,"props":6936,"children":6937},{"style":117},[6938],{"type":30,"value":5094},{"type":20,"tag":90,"props":6940,"children":6941},{"style":129},[6942],{"type":30,"value":5063},{"type":20,"tag":90,"props":6944,"children":6945},{"style":117},[6946],{"type":30,"value":5068},{"type":20,"tag":90,"props":6948,"children":6949},{"style":123},[6950],{"type":30,"value":1717},{"type":20,"tag":90,"props":6952,"children":6953},{"style":123},[6954],{"type":30,"value":5111},{"type":20,"tag":90,"props":6956,"children":6957},{"style":146},[6958],{"type":30,"value":5116},{"type":20,"tag":90,"props":6960,"children":6961},{"style":117},[6962],{"type":30,"value":2151},{"type":20,"tag":90,"props":6964,"children":6965},{"class":92,"line":255},[6966],{"type":20,"tag":90,"props":6967,"children":6968},{"style":97},[6969],{"type":30,"value":6970},"    // If no url property has been specified, throw an error, as per the standard Backbone sync\n",{"type":20,"tag":90,"props":6972,"children":6973},{"class":92,"line":264},[6974,6979,6983,6987,6991,6995],{"type":20,"tag":90,"props":6975,"children":6976},{"style":123},[6977],{"type":30,"value":6978},"    if",{"type":20,"tag":90,"props":6980,"children":6981},{"style":117},[6982],{"type":30,"value":5141},{"type":20,"tag":90,"props":6984,"children":6985},{"style":123},[6986],{"type":30,"value":5146},{"type":20,"tag":90,"props":6988,"children":6989},{"style":117},[6990],{"type":30,"value":5151},{"type":20,"tag":90,"props":6992,"children":6993},{"style":135},[6994],{"type":30,"value":5156},{"type":20,"tag":90,"props":6996,"children":6997},{"style":117},[6998],{"type":30,"value":5161},{"type":20,"tag":90,"props":7000,"children":7001},{"class":92,"line":273},[7002],{"type":20,"tag":90,"props":7003,"children":7004},{"style":97},[7005],{"type":30,"value":7006},"    // Transform the url into a namespace\n",{"type":20,"tag":90,"props":7008,"children":7009},{"class":92,"line":292},[7010,7015,7019,7023,7027,7031,7035,7039,7043],{"type":20,"tag":90,"props":7011,"children":7012},{"style":117},[7013],{"type":30,"value":7014},"    namespace ",{"type":20,"tag":90,"props":7016,"children":7017},{"style":123},[7018],{"type":30,"value":126},{"type":20,"tag":90,"props":7020,"children":7021},{"style":117},[7022],{"type":30,"value":5186},{"type":20,"tag":90,"props":7024,"children":7025},{"style":146},[7026],{"type":30,"value":4692},{"type":20,"tag":90,"props":7028,"children":7029},{"style":117},[7030],{"type":30,"value":5195},{"type":20,"tag":90,"props":7032,"children":7033},{"style":135},[7034],{"type":30,"value":4815},{"type":20,"tag":90,"props":7036,"children":7037},{"style":117},[7038],{"type":30,"value":4557},{"type":20,"tag":90,"props":7040,"children":7041},{"style":146},[7042],{"type":30,"value":4824},{"type":20,"tag":90,"props":7044,"children":7045},{"style":117},[7046],{"type":30,"value":5212},{"type":20,"tag":21,"props":7048,"children":7049},{},[7050,7052,7058,7060,7065],{"type":30,"value":7051},"So, we ensure options is an object (potentially empty, if no options have been passed to us), create a jQuery Deferred object and it's promise, and declare namespace and socket for later use. Then, we attempt to determine the url, from the options first or, if not set there, from the model. Note the use of underscore's ",{"type":20,"tag":25,"props":7053,"children":7056},{"href":7054,"rel":7055},"http://underscorejs.org/#result",[38],[7057],{"type":30,"value":5053},{"type":30,"value":7059}," function - ",{"type":20,"tag":86,"props":7061,"children":7063},{"className":7062},[],[7064],{"type":30,"value":5903},{"type":30,"value":7066}," can be either a function returning a string, or a string itself. If no url is found, we throw the backbone standard error. Otherwise, we translate the url into a namespace, using backbone conventions - more on that later.",{"type":20,"tag":79,"props":7068,"children":7070},{"className":4503,"code":7069,"language":4505,"meta":8,"style":8},"// Determine what data we're sending, and ensure id is present if we're performing a PATCH call\nif (!opts.data && model) opts.data = opts.attrs || model.toJSON(options) || {};\nif ((opts.data.id === null || opts.data.id === void 0) && opts.patch === true && model){\n    opts.data.id = model.id;\n}\n// Determine which websocket to use - set in options or on model\nsocket = opts.socket || model.socket;\n",[7071],{"type":20,"tag":86,"props":7072,"children":7073},{"__ignoreMap":8},[7074,7082,7142,7209,7225,7232,7240],{"type":20,"tag":90,"props":7075,"children":7076},{"class":92,"line":93},[7077],{"type":20,"tag":90,"props":7078,"children":7079},{"style":97},[7080],{"type":30,"value":7081},"// Determine what data we're sending, and ensure id is present if we're performing a PATCH call\n",{"type":20,"tag":90,"props":7083,"children":7084},{"class":92,"line":103},[7085,7090,7094,7098,7102,7106,7110,7114,7118,7122,7126,7130,7134,7138],{"type":20,"tag":90,"props":7086,"children":7087},{"style":123},[7088],{"type":30,"value":7089},"if",{"type":20,"tag":90,"props":7091,"children":7092},{"style":117},[7093],{"type":30,"value":5141},{"type":20,"tag":90,"props":7095,"children":7096},{"style":123},[7097],{"type":30,"value":5146},{"type":20,"tag":90,"props":7099,"children":7100},{"style":117},[7101],{"type":30,"value":5240},{"type":20,"tag":90,"props":7103,"children":7104},{"style":123},[7105],{"type":30,"value":5245},{"type":20,"tag":90,"props":7107,"children":7108},{"style":117},[7109],{"type":30,"value":5250},{"type":20,"tag":90,"props":7111,"children":7112},{"style":123},[7113],{"type":30,"value":126},{"type":20,"tag":90,"props":7115,"children":7116},{"style":117},[7117],{"type":30,"value":5259},{"type":20,"tag":90,"props":7119,"children":7120},{"style":123},[7121],{"type":30,"value":5264},{"type":20,"tag":90,"props":7123,"children":7124},{"style":117},[7125],{"type":30,"value":5269},{"type":20,"tag":90,"props":7127,"children":7128},{"style":135},[7129],{"type":30,"value":5274},{"type":20,"tag":90,"props":7131,"children":7132},{"style":117},[7133],{"type":30,"value":5279},{"type":20,"tag":90,"props":7135,"children":7136},{"style":123},[7137],{"type":30,"value":5264},{"type":20,"tag":90,"props":7139,"children":7140},{"style":117},[7141],{"type":30,"value":5288},{"type":20,"tag":90,"props":7143,"children":7144},{"class":92,"line":113},[7145,7149,7153,7157,7161,7165,7169,7173,7177,7181,7185,7189,7193,7197,7201,7205],{"type":20,"tag":90,"props":7146,"children":7147},{"style":123},[7148],{"type":30,"value":7089},{"type":20,"tag":90,"props":7150,"children":7151},{"style":117},[7152],{"type":30,"value":5300},{"type":20,"tag":90,"props":7154,"children":7155},{"style":123},[7156],{"type":30,"value":5305},{"type":20,"tag":90,"props":7158,"children":7159},{"style":146},[7160],{"type":30,"value":5310},{"type":20,"tag":90,"props":7162,"children":7163},{"style":123},[7164],{"type":30,"value":5315},{"type":20,"tag":90,"props":7166,"children":7167},{"style":117},[7168],{"type":30,"value":5320},{"type":20,"tag":90,"props":7170,"children":7171},{"style":123},[7172],{"type":30,"value":5305},{"type":20,"tag":90,"props":7174,"children":7175},{"style":123},[7176],{"type":30,"value":5111},{"type":20,"tag":90,"props":7178,"children":7179},{"style":146},[7180],{"type":30,"value":5116},{"type":20,"tag":90,"props":7182,"children":7183},{"style":117},[7184],{"type":30,"value":5068},{"type":20,"tag":90,"props":7186,"children":7187},{"style":123},[7188],{"type":30,"value":5245},{"type":20,"tag":90,"props":7190,"children":7191},{"style":117},[7192],{"type":30,"value":5345},{"type":20,"tag":90,"props":7194,"children":7195},{"style":123},[7196],{"type":30,"value":5305},{"type":20,"tag":90,"props":7198,"children":7199},{"style":146},[7200],{"type":30,"value":5354},{"type":20,"tag":90,"props":7202,"children":7203},{"style":123},[7204],{"type":30,"value":5359},{"type":20,"tag":90,"props":7206,"children":7207},{"style":117},[7208],{"type":30,"value":5364},{"type":20,"tag":90,"props":7210,"children":7211},{"class":92,"line":152},[7212,7217,7221],{"type":20,"tag":90,"props":7213,"children":7214},{"style":117},[7215],{"type":30,"value":7216},"    opts.data.id ",{"type":20,"tag":90,"props":7218,"children":7219},{"style":123},[7220],{"type":30,"value":126},{"type":20,"tag":90,"props":7222,"children":7223},{"style":117},[7224],{"type":30,"value":5381},{"type":20,"tag":90,"props":7226,"children":7227},{"class":92,"line":160},[7228],{"type":20,"tag":90,"props":7229,"children":7230},{"style":117},[7231],{"type":30,"value":1273},{"type":20,"tag":90,"props":7233,"children":7234},{"class":92,"line":174},[7235],{"type":20,"tag":90,"props":7236,"children":7237},{"style":97},[7238],{"type":30,"value":7239},"// Determine which websocket to use - set in options or on model\n",{"type":20,"tag":90,"props":7241,"children":7242},{"class":92,"line":183},[7243,7248,7252,7256,7260],{"type":20,"tag":90,"props":7244,"children":7245},{"style":117},[7246],{"type":30,"value":7247},"socket ",{"type":20,"tag":90,"props":7249,"children":7250},{"style":123},[7251],{"type":30,"value":126},{"type":20,"tag":90,"props":7253,"children":7254},{"style":117},[7255],{"type":30,"value":5414},{"type":20,"tag":90,"props":7257,"children":7258},{"style":123},[7259],{"type":30,"value":5264},{"type":20,"tag":90,"props":7261,"children":7262},{"style":117},[7263],{"type":30,"value":5423},{"type":20,"tag":21,"props":7265,"children":7266},{},[7267],{"type":30,"value":7268},"Note that we're deciding what socket to use in the same order as we determined url - first checking the options for the socket to have been passed in with this sync request, then checking the model. If you expect that socket may not be set on either, you may want to add a check at this point. If you intend to use a globally available socket, this is also where you'd add that as a default.",{"type":20,"tag":79,"props":7270,"children":7272},{"className":4503,"code":7271,"language":4505,"meta":8,"style":8}," // Add a listener for our namespaced method, and resolve or reject our deferred based on the response\nsocket.once(namespace+method, function(res){\n    var success = (res && res.success); // Expects server json response to contain a boolean 'success' field\n    if (success)\n    {\n        if (_.isFunction(options.success)) options.success(res);\n        defer.resolve(res);\n        return;\n    }\n    if (_.isFunction(options.error)) options.error(res);\n    defer.reject(res);\n});\n",[7273],{"type":20,"tag":86,"props":7274,"children":7275},{"__ignoreMap":8},[7276,7284,7324,7355,7366,7374,7401,7417,7428,7436,7463,7479],{"type":20,"tag":90,"props":7277,"children":7278},{"class":92,"line":93},[7279],{"type":20,"tag":90,"props":7280,"children":7281},{"style":97},[7282],{"type":30,"value":7283}," // Add a listener for our namespaced method, and resolve or reject our deferred based on the response\n",{"type":20,"tag":90,"props":7285,"children":7286},{"class":92,"line":103},[7287,7292,7296,7300,7304,7308,7312,7316,7320],{"type":20,"tag":90,"props":7288,"children":7289},{"style":117},[7290],{"type":30,"value":7291},"socket.",{"type":20,"tag":90,"props":7293,"children":7294},{"style":135},[7295],{"type":30,"value":5444},{"type":20,"tag":90,"props":7297,"children":7298},{"style":117},[7299],{"type":30,"value":5449},{"type":20,"tag":90,"props":7301,"children":7302},{"style":123},[7303],{"type":30,"value":5454},{"type":20,"tag":90,"props":7305,"children":7306},{"style":117},[7307],{"type":30,"value":5459},{"type":20,"tag":90,"props":7309,"children":7310},{"style":123},[7311],{"type":30,"value":4562},{"type":20,"tag":90,"props":7313,"children":7314},{"style":117},[7315],{"type":30,"value":4557},{"type":20,"tag":90,"props":7317,"children":7318},{"style":4569},[7319],{"type":30,"value":5472},{"type":20,"tag":90,"props":7321,"children":7322},{"style":117},[7323],{"type":30,"value":4603},{"type":20,"tag":90,"props":7325,"children":7326},{"class":92,"line":113},[7327,7331,7335,7339,7343,7347,7351],{"type":20,"tag":90,"props":7328,"children":7329},{"style":123},[7330],{"type":30,"value":4611},{"type":20,"tag":90,"props":7332,"children":7333},{"style":117},[7334],{"type":30,"value":5489},{"type":20,"tag":90,"props":7336,"children":7337},{"style":123},[7338],{"type":30,"value":126},{"type":20,"tag":90,"props":7340,"children":7341},{"style":117},[7342],{"type":30,"value":5498},{"type":20,"tag":90,"props":7344,"children":7345},{"style":123},[7346],{"type":30,"value":5245},{"type":20,"tag":90,"props":7348,"children":7349},{"style":117},[7350],{"type":30,"value":5507},{"type":20,"tag":90,"props":7352,"children":7353},{"style":97},[7354],{"type":30,"value":5512},{"type":20,"tag":90,"props":7356,"children":7357},{"class":92,"line":152},[7358,7362],{"type":20,"tag":90,"props":7359,"children":7360},{"style":123},[7361],{"type":30,"value":6978},{"type":20,"tag":90,"props":7363,"children":7364},{"style":117},[7365],{"type":30,"value":5525},{"type":20,"tag":90,"props":7367,"children":7368},{"class":92,"line":160},[7369],{"type":20,"tag":90,"props":7370,"children":7371},{"style":117},[7372],{"type":30,"value":7373},"    {\n",{"type":20,"tag":90,"props":7375,"children":7376},{"class":92,"line":174},[7377,7381,7385,7389,7393,7397],{"type":20,"tag":90,"props":7378,"children":7379},{"style":123},[7380],{"type":30,"value":5136},{"type":20,"tag":90,"props":7382,"children":7383},{"style":117},[7384],{"type":30,"value":5546},{"type":20,"tag":90,"props":7386,"children":7387},{"style":135},[7388],{"type":30,"value":5551},{"type":20,"tag":90,"props":7390,"children":7391},{"style":117},[7392],{"type":30,"value":5556},{"type":20,"tag":90,"props":7394,"children":7395},{"style":135},[7396],{"type":30,"value":5561},{"type":20,"tag":90,"props":7398,"children":7399},{"style":117},[7400],{"type":30,"value":5566},{"type":20,"tag":90,"props":7402,"children":7403},{"class":92,"line":183},[7404,7409,7413],{"type":20,"tag":90,"props":7405,"children":7406},{"style":117},[7407],{"type":30,"value":7408},"        defer.",{"type":20,"tag":90,"props":7410,"children":7411},{"style":135},[7412],{"type":30,"value":5579},{"type":20,"tag":90,"props":7414,"children":7415},{"style":117},[7416],{"type":30,"value":5566},{"type":20,"tag":90,"props":7418,"children":7419},{"class":92,"line":191},[7420,7424],{"type":20,"tag":90,"props":7421,"children":7422},{"style":123},[7423],{"type":30,"value":4805},{"type":20,"tag":90,"props":7425,"children":7426},{"style":117},[7427],{"type":30,"value":2151},{"type":20,"tag":90,"props":7429,"children":7430},{"class":92,"line":200},[7431],{"type":20,"tag":90,"props":7432,"children":7433},{"style":117},[7434],{"type":30,"value":7435},"    }\n",{"type":20,"tag":90,"props":7437,"children":7438},{"class":92,"line":229},[7439,7443,7447,7451,7455,7459],{"type":20,"tag":90,"props":7440,"children":7441},{"style":123},[7442],{"type":30,"value":6978},{"type":20,"tag":90,"props":7444,"children":7445},{"style":117},[7446],{"type":30,"value":5546},{"type":20,"tag":90,"props":7448,"children":7449},{"style":135},[7450],{"type":30,"value":5551},{"type":20,"tag":90,"props":7452,"children":7453},{"style":117},[7454],{"type":30,"value":5626},{"type":20,"tag":90,"props":7456,"children":7457},{"style":135},[7458],{"type":30,"value":5631},{"type":20,"tag":90,"props":7460,"children":7461},{"style":117},[7462],{"type":30,"value":5566},{"type":20,"tag":90,"props":7464,"children":7465},{"class":92,"line":247},[7466,7471,7475],{"type":20,"tag":90,"props":7467,"children":7468},{"style":117},[7469],{"type":30,"value":7470},"    defer.",{"type":20,"tag":90,"props":7472,"children":7473},{"style":135},[7474],{"type":30,"value":5649},{"type":20,"tag":90,"props":7476,"children":7477},{"style":117},[7478],{"type":30,"value":5566},{"type":20,"tag":90,"props":7480,"children":7481},{"class":92,"line":255},[7482],{"type":20,"tag":90,"props":7483,"children":7484},{"style":117},[7485],{"type":30,"value":7486},"});\n",{"type":20,"tag":21,"props":7488,"children":7489},{},[7490,7492,7498,7500,7506,7508,7514],{"type":30,"value":7491},"Now, we add a listener for our namespace and request method. I'll go into more detail on this shortly, but the general form will look like ",{"type":20,"tag":86,"props":7493,"children":7495},{"className":7494},[],[7496],{"type":30,"value":7497},"url:components:method",{"type":30,"value":7499},", e.g. ",{"type":20,"tag":86,"props":7501,"children":7503},{"className":7502},[],[7504],{"type":30,"value":7505},"api:json:get",{"type":30,"value":7507}," or ",{"type":20,"tag":86,"props":7509,"children":7511},{"className":7510},[],[7512],{"type":30,"value":7513},"api:json:post",{"type":30,"value":615},{"type":20,"tag":21,"props":7516,"children":7517},{},[7518,7520,7525],{"type":30,"value":7519},"We expect the server to reply with json that will include a boolean ",{"type":20,"tag":86,"props":7521,"children":7523},{"className":7522},[],[7524],{"type":30,"value":5561},{"type":30,"value":7526}," field, and decide whether to trigger any success or error functions based on whether we've received a response and that response indicates success. We at this point also resolve or reject the promise we created earlier, and will return shortly.",{"type":20,"tag":21,"props":7528,"children":7529},{},[7530,7532,7538],{"type":30,"value":7531},"An earlier version of the code used the ",{"type":20,"tag":86,"props":7533,"children":7535},{"className":7534},[],[7536],{"type":30,"value":7537},"callback",{"type":30,"value":7539}," method of emitting, that looks like:",{"type":20,"tag":79,"props":7541,"children":7543},{"className":4503,"code":7542,"language":4505,"meta":8,"style":8},"socket.emit(namespace+method, opts.data, function(res){ // ... resolve promise ...  }\n",[7544],{"type":20,"tag":86,"props":7545,"children":7546},{"__ignoreMap":8},[7547],{"type":20,"tag":90,"props":7548,"children":7549},{"class":92,"line":93},[7550,7554,7558,7562,7566,7571,7575,7579,7583,7588],{"type":20,"tag":90,"props":7551,"children":7552},{"style":117},[7553],{"type":30,"value":7291},{"type":20,"tag":90,"props":7555,"children":7556},{"style":135},[7557],{"type":30,"value":5692},{"type":20,"tag":90,"props":7559,"children":7560},{"style":117},[7561],{"type":30,"value":5449},{"type":20,"tag":90,"props":7563,"children":7564},{"style":123},[7565],{"type":30,"value":5454},{"type":20,"tag":90,"props":7567,"children":7568},{"style":117},[7569],{"type":30,"value":7570},"method, opts.data, ",{"type":20,"tag":90,"props":7572,"children":7573},{"style":123},[7574],{"type":30,"value":4562},{"type":20,"tag":90,"props":7576,"children":7577},{"style":117},[7578],{"type":30,"value":4557},{"type":20,"tag":90,"props":7580,"children":7581},{"style":4569},[7582],{"type":30,"value":5472},{"type":20,"tag":90,"props":7584,"children":7585},{"style":117},[7586],{"type":30,"value":7587},"){ ",{"type":20,"tag":90,"props":7589,"children":7590},{"style":97},[7591],{"type":30,"value":7592},"// ... resolve promise ...  }\n",{"type":20,"tag":21,"props":7594,"children":7595},{},[7596,7598,7605],{"type":30,"value":7597},"Why the change? This type of request emits a ",{"type":20,"tag":25,"props":7599,"children":7602},{"href":7600,"rel":7601},"https://github.com/automattic/socket.io-protocol",[38],[7603],{"type":30,"value":7604},"Data ACK packet",{"type":30,"value":7606},", which combines the ack packet (acknowledging the request) with the data expected of the response. It seems straightforward, but the protocol dictates that communication is BLOCKED until the ack packet is received, and now you've mandated that the ack packet not get sent until its ready to send the data along with it. Not an issue if you don't mind serving in order of request, and don't expect gathering the data to return to take long, but if you want to take advantage of async, out-of-order serving of requests, you need to use the approach we've discussed above, which sends an EVENT packet which can be responded to with an immediate ACK, and sent data later when it's ready.",{"type":20,"tag":79,"props":7608,"children":7610},{"className":4503,"code":7609,"language":4505,"meta":8,"style":8}," // Emit our namespaced method and the model+opts data\nsocket.emit(namespace+method, opts.data);\n\n// Trigger the request event on the model, as per backbone spec\nmodel.trigger('request', model, promise, opts);\n// Return the promise for us to use as per usual (hanging .done blocks off, add to a .when, etc.)\nreturn promise;\n",[7611],{"type":20,"tag":86,"props":7612,"children":7613},{"__ignoreMap":8},[7614,7622,7645,7652,7660,7684,7692],{"type":20,"tag":90,"props":7615,"children":7616},{"class":92,"line":93},[7617],{"type":20,"tag":90,"props":7618,"children":7619},{"style":97},[7620],{"type":30,"value":7621}," // Emit our namespaced method and the model+opts data\n",{"type":20,"tag":90,"props":7623,"children":7624},{"class":92,"line":103},[7625,7629,7633,7637,7641],{"type":20,"tag":90,"props":7626,"children":7627},{"style":117},[7628],{"type":30,"value":7291},{"type":20,"tag":90,"props":7630,"children":7631},{"style":135},[7632],{"type":30,"value":5692},{"type":20,"tag":90,"props":7634,"children":7635},{"style":117},[7636],{"type":30,"value":5449},{"type":20,"tag":90,"props":7638,"children":7639},{"style":123},[7640],{"type":30,"value":5454},{"type":20,"tag":90,"props":7642,"children":7643},{"style":117},[7644],{"type":30,"value":5705},{"type":20,"tag":90,"props":7646,"children":7647},{"class":92,"line":113},[7648],{"type":20,"tag":90,"props":7649,"children":7650},{"emptyLinePlaceholder":107},[7651],{"type":30,"value":110},{"type":20,"tag":90,"props":7653,"children":7654},{"class":92,"line":152},[7655],{"type":20,"tag":90,"props":7656,"children":7657},{"style":97},[7658],{"type":30,"value":7659},"// Trigger the request event on the model, as per backbone spec\n",{"type":20,"tag":90,"props":7661,"children":7662},{"class":92,"line":160},[7663,7668,7672,7676,7680],{"type":20,"tag":90,"props":7664,"children":7665},{"style":117},[7666],{"type":30,"value":7667},"model.",{"type":20,"tag":90,"props":7669,"children":7670},{"style":135},[7671],{"type":30,"value":5736},{"type":20,"tag":90,"props":7673,"children":7674},{"style":117},[7675],{"type":30,"value":4557},{"type":20,"tag":90,"props":7677,"children":7678},{"style":129},[7679],{"type":30,"value":5745},{"type":20,"tag":90,"props":7681,"children":7682},{"style":117},[7683],{"type":30,"value":5750},{"type":20,"tag":90,"props":7685,"children":7686},{"class":92,"line":174},[7687],{"type":20,"tag":90,"props":7688,"children":7689},{"style":97},[7690],{"type":30,"value":7691},"// Return the promise for us to use as per usual (hanging .done blocks off, add to a .when, etc.)\n",{"type":20,"tag":90,"props":7693,"children":7694},{"class":92,"line":183},[7695,7700],{"type":20,"tag":90,"props":7696,"children":7697},{"style":123},[7698],{"type":30,"value":7699},"return",{"type":20,"tag":90,"props":7701,"children":7702},{"style":117},[7703],{"type":30,"value":5772},{"type":20,"tag":21,"props":7705,"children":7706},{},[7707],{"type":30,"value":7708},"Comments say it all for this one.",{"type":20,"tag":79,"props":7710,"children":7712},{"className":4503,"code":7711,"language":4505,"meta":8,"style":8},"/**\n * Break url apart to create namespace - every '/' save any pre/post-fixing the url will become a ':' indicating\n * namespace - so a collection that maps to /api/posts will now have its events on the namespace\n * api:posts: (ie. api:posts:create, api:posts:delete, etc.), and a model that maps to /api/posts/21\n * will have events on api:posts:21: (ie. api:posts:21:update, api:posts:21:patch, etc.)\n * @param {string=} url\n */\nBackbone.Model.prototype.namespace = function(url){\n    url = url || this.url();\n    return _.trim(url, '/').replace('/', ':') + \":\";\n};\n",[7713],{"type":20,"tag":86,"props":7714,"children":7715},{"__ignoreMap":8},[7716,7723,7731,7739,7747,7755,7775,7782,7822,7858,7921],{"type":20,"tag":90,"props":7717,"children":7718},{"class":92,"line":93},[7719],{"type":20,"tag":90,"props":7720,"children":7721},{"style":97},[7722],{"type":30,"value":4517},{"type":20,"tag":90,"props":7724,"children":7725},{"class":92,"line":103},[7726],{"type":20,"tag":90,"props":7727,"children":7728},{"style":97},[7729],{"type":30,"value":7730}," * Break url apart to create namespace - every '/' save any pre/post-fixing the url will become a ':' indicating\n",{"type":20,"tag":90,"props":7732,"children":7733},{"class":92,"line":113},[7734],{"type":20,"tag":90,"props":7735,"children":7736},{"style":97},[7737],{"type":30,"value":7738}," * namespace - so a collection that maps to /api/posts will now have its events on the namespace\n",{"type":20,"tag":90,"props":7740,"children":7741},{"class":92,"line":152},[7742],{"type":20,"tag":90,"props":7743,"children":7744},{"style":97},[7745],{"type":30,"value":7746}," * api:posts: (ie. api:posts:create, api:posts:delete, etc.), and a model that maps to /api/posts/21\n",{"type":20,"tag":90,"props":7748,"children":7749},{"class":92,"line":160},[7750],{"type":20,"tag":90,"props":7751,"children":7752},{"style":97},[7753],{"type":30,"value":7754}," * will have events on api:posts:21: (ie. api:posts:21:update, api:posts:21:patch, etc.)\n",{"type":20,"tag":90,"props":7756,"children":7757},{"class":92,"line":174},[7758,7763,7767,7771],{"type":20,"tag":90,"props":7759,"children":7760},{"style":97},[7761],{"type":30,"value":7762}," * ",{"type":20,"tag":90,"props":7764,"children":7765},{"style":123},[7766],{"type":30,"value":5846},{"type":20,"tag":90,"props":7768,"children":7769},{"style":135},[7770],{"type":30,"value":5851},{"type":20,"tag":90,"props":7772,"children":7773},{"style":117},[7774],{"type":30,"value":5856},{"type":20,"tag":90,"props":7776,"children":7777},{"class":92,"line":183},[7778],{"type":20,"tag":90,"props":7779,"children":7780},{"style":97},[7781],{"type":30,"value":4549},{"type":20,"tag":90,"props":7783,"children":7784},{"class":92,"line":191},[7785,7790,7794,7798,7802,7806,7810,7814,7818],{"type":20,"tag":90,"props":7786,"children":7787},{"style":117},[7788],{"type":30,"value":7789},"Backbone.Model.",{"type":20,"tag":90,"props":7791,"children":7792},{"style":146},[7793],{"type":30,"value":4692},{"type":20,"tag":90,"props":7795,"children":7796},{"style":117},[7797],{"type":30,"value":615},{"type":20,"tag":90,"props":7799,"children":7800},{"style":135},[7801],{"type":30,"value":5886},{"type":20,"tag":90,"props":7803,"children":7804},{"style":123},[7805],{"type":30,"value":1113},{"type":20,"tag":90,"props":7807,"children":7808},{"style":123},[7809],{"type":30,"value":4625},{"type":20,"tag":90,"props":7811,"children":7812},{"style":117},[7813],{"type":30,"value":4557},{"type":20,"tag":90,"props":7815,"children":7816},{"style":4569},[7817],{"type":30,"value":5903},{"type":20,"tag":90,"props":7819,"children":7820},{"style":117},[7821],{"type":30,"value":4603},{"type":20,"tag":90,"props":7823,"children":7824},{"class":92,"line":200},[7825,7830,7834,7838,7842,7846,7850,7854],{"type":20,"tag":90,"props":7826,"children":7827},{"style":117},[7828],{"type":30,"value":7829},"    url ",{"type":20,"tag":90,"props":7831,"children":7832},{"style":123},[7833],{"type":30,"value":126},{"type":20,"tag":90,"props":7835,"children":7836},{"style":117},[7837],{"type":30,"value":5925},{"type":20,"tag":90,"props":7839,"children":7840},{"style":123},[7841],{"type":30,"value":5264},{"type":20,"tag":90,"props":7843,"children":7844},{"style":146},[7845],{"type":30,"value":5934},{"type":20,"tag":90,"props":7847,"children":7848},{"style":117},[7849],{"type":30,"value":615},{"type":20,"tag":90,"props":7851,"children":7852},{"style":135},[7853],{"type":30,"value":5903},{"type":20,"tag":90,"props":7855,"children":7856},{"style":117},[7857],{"type":30,"value":5161},{"type":20,"tag":90,"props":7859,"children":7860},{"class":92,"line":229},[7861,7865,7869,7873,7877,7881,7885,7889,7893,7897,7901,7905,7909,7913,7917],{"type":20,"tag":90,"props":7862,"children":7863},{"style":123},[7864],{"type":30,"value":6596},{"type":20,"tag":90,"props":7866,"children":7867},{"style":117},[7868],{"type":30,"value":4936},{"type":20,"tag":90,"props":7870,"children":7871},{"style":135},[7872],{"type":30,"value":5963},{"type":20,"tag":90,"props":7874,"children":7875},{"style":117},[7876],{"type":30,"value":5968},{"type":20,"tag":90,"props":7878,"children":7879},{"style":129},[7880],{"type":30,"value":5973},{"type":20,"tag":90,"props":7882,"children":7883},{"style":117},[7884],{"type":30,"value":5978},{"type":20,"tag":90,"props":7886,"children":7887},{"style":135},[7888],{"type":30,"value":5983},{"type":20,"tag":90,"props":7890,"children":7891},{"style":117},[7892],{"type":30,"value":4557},{"type":20,"tag":90,"props":7894,"children":7895},{"style":129},[7896],{"type":30,"value":5973},{"type":20,"tag":90,"props":7898,"children":7899},{"style":117},[7900],{"type":30,"value":1260},{"type":20,"tag":90,"props":7902,"children":7903},{"style":129},[7904],{"type":30,"value":6000},{"type":20,"tag":90,"props":7906,"children":7907},{"style":117},[7908],{"type":30,"value":5068},{"type":20,"tag":90,"props":7910,"children":7911},{"style":123},[7912],{"type":30,"value":5454},{"type":20,"tag":90,"props":7914,"children":7915},{"style":129},[7916],{"type":30,"value":6013},{"type":20,"tag":90,"props":7918,"children":7919},{"style":117},[7920],{"type":30,"value":2151},{"type":20,"tag":90,"props":7922,"children":7923},{"class":92,"line":247},[7924],{"type":20,"tag":90,"props":7925,"children":7926},{"style":117},[7927],{"type":30,"value":6624},{"type":20,"tag":21,"props":7929,"children":7930},{},[7931],{"type":30,"value":7932},"This one too, I think. Note, this isn't a required part of implementing socket.io - it just nicely mirros the style of events that backbone uses internally.",{"type":20,"tag":79,"props":7934,"children":7936},{"className":4503,"code":7935,"language":4505,"meta":8,"style":8},"/**\n * Override EventEmitter.emit and SocketNamespace reference for socket.io to add a catch all case for the\n * wildcard ('*') character. Now, socket.on('*') will catch any event, with the name of the caught event\n * passed to the handler as the first argument.\n */\nio.EventEmitter.prototype.emit = function(name){\n    var args = Array.prototype.slice.call(arguments, 1);\n\n    eventEmit.apply(this, ['*', name].concat(args));\n    eventEmit.apply(this, [name].concat(args));\n};\nio.SocketNamespace.prototype.$emit = io.EventEmitter.prototype.emit;\n",[7937],{"type":20,"tag":86,"props":7938,"children":7939},{"__ignoreMap":8},[7940,7947,7955,7963,7971,7978,8018,8073,8080,8120,8151,8158],{"type":20,"tag":90,"props":7941,"children":7942},{"class":92,"line":93},[7943],{"type":20,"tag":90,"props":7944,"children":7945},{"style":97},[7946],{"type":30,"value":4517},{"type":20,"tag":90,"props":7948,"children":7949},{"class":92,"line":103},[7950],{"type":20,"tag":90,"props":7951,"children":7952},{"style":97},[7953],{"type":30,"value":7954}," * Override EventEmitter.emit and SocketNamespace reference for socket.io to add a catch all case for the\n",{"type":20,"tag":90,"props":7956,"children":7957},{"class":92,"line":113},[7958],{"type":20,"tag":90,"props":7959,"children":7960},{"style":97},[7961],{"type":30,"value":7962}," * wildcard ('*') character. Now, socket.on('*') will catch any event, with the name of the caught event\n",{"type":20,"tag":90,"props":7964,"children":7965},{"class":92,"line":152},[7966],{"type":20,"tag":90,"props":7967,"children":7968},{"style":97},[7969],{"type":30,"value":7970}," * passed to the handler as the first argument.\n",{"type":20,"tag":90,"props":7972,"children":7973},{"class":92,"line":160},[7974],{"type":20,"tag":90,"props":7975,"children":7976},{"style":97},[7977],{"type":30,"value":4549},{"type":20,"tag":90,"props":7979,"children":7980},{"class":92,"line":174},[7981,7986,7990,7994,7998,8002,8006,8010,8014],{"type":20,"tag":90,"props":7982,"children":7983},{"style":117},[7984],{"type":30,"value":7985},"io.EventEmitter.",{"type":20,"tag":90,"props":7987,"children":7988},{"style":146},[7989],{"type":30,"value":4692},{"type":20,"tag":90,"props":7991,"children":7992},{"style":117},[7993],{"type":30,"value":615},{"type":20,"tag":90,"props":7995,"children":7996},{"style":135},[7997],{"type":30,"value":5692},{"type":20,"tag":90,"props":7999,"children":8000},{"style":123},[8001],{"type":30,"value":1113},{"type":20,"tag":90,"props":8003,"children":8004},{"style":123},[8005],{"type":30,"value":4625},{"type":20,"tag":90,"props":8007,"children":8008},{"style":117},[8009],{"type":30,"value":4557},{"type":20,"tag":90,"props":8011,"children":8012},{"style":4569},[8013],{"type":30,"value":6115},{"type":20,"tag":90,"props":8015,"children":8016},{"style":117},[8017],{"type":30,"value":4603},{"type":20,"tag":90,"props":8019,"children":8020},{"class":92,"line":183},[8021,8025,8029,8033,8037,8041,8045,8049,8053,8057,8061,8065,8069],{"type":20,"tag":90,"props":8022,"children":8023},{"style":123},[8024],{"type":30,"value":4611},{"type":20,"tag":90,"props":8026,"children":8027},{"style":117},[8028],{"type":30,"value":6132},{"type":20,"tag":90,"props":8030,"children":8031},{"style":123},[8032],{"type":30,"value":126},{"type":20,"tag":90,"props":8034,"children":8035},{"style":146},[8036],{"type":30,"value":6141},{"type":20,"tag":90,"props":8038,"children":8039},{"style":117},[8040],{"type":30,"value":615},{"type":20,"tag":90,"props":8042,"children":8043},{"style":146},[8044],{"type":30,"value":4692},{"type":20,"tag":90,"props":8046,"children":8047},{"style":117},[8048],{"type":30,"value":6154},{"type":20,"tag":90,"props":8050,"children":8051},{"style":135},[8052],{"type":30,"value":4815},{"type":20,"tag":90,"props":8054,"children":8055},{"style":117},[8056],{"type":30,"value":4557},{"type":20,"tag":90,"props":8058,"children":8059},{"style":146},[8060],{"type":30,"value":6167},{"type":20,"tag":90,"props":8062,"children":8063},{"style":117},[8064],{"type":30,"value":1260},{"type":20,"tag":90,"props":8066,"children":8067},{"style":146},[8068],{"type":30,"value":6176},{"type":20,"tag":90,"props":8070,"children":8071},{"style":117},[8072],{"type":30,"value":4662},{"type":20,"tag":90,"props":8074,"children":8075},{"class":92,"line":191},[8076],{"type":20,"tag":90,"props":8077,"children":8078},{"emptyLinePlaceholder":107},[8079],{"type":30,"value":110},{"type":20,"tag":90,"props":8081,"children":8082},{"class":92,"line":200},[8083,8088,8092,8096,8100,8104,8108,8112,8116],{"type":20,"tag":90,"props":8084,"children":8085},{"style":117},[8086],{"type":30,"value":8087},"    eventEmit.",{"type":20,"tag":90,"props":8089,"children":8090},{"style":135},[8091],{"type":30,"value":6202},{"type":20,"tag":90,"props":8093,"children":8094},{"style":117},[8095],{"type":30,"value":4557},{"type":20,"tag":90,"props":8097,"children":8098},{"style":146},[8099],{"type":30,"value":4824},{"type":20,"tag":90,"props":8101,"children":8102},{"style":117},[8103],{"type":30,"value":6215},{"type":20,"tag":90,"props":8105,"children":8106},{"style":129},[8107],{"type":30,"value":6220},{"type":20,"tag":90,"props":8109,"children":8110},{"style":117},[8111],{"type":30,"value":6225},{"type":20,"tag":90,"props":8113,"children":8114},{"style":135},[8115],{"type":30,"value":6230},{"type":20,"tag":90,"props":8117,"children":8118},{"style":117},[8119],{"type":30,"value":6235},{"type":20,"tag":90,"props":8121,"children":8122},{"class":92,"line":229},[8123,8127,8131,8135,8139,8143,8147],{"type":20,"tag":90,"props":8124,"children":8125},{"style":117},[8126],{"type":30,"value":8087},{"type":20,"tag":90,"props":8128,"children":8129},{"style":135},[8130],{"type":30,"value":6202},{"type":20,"tag":90,"props":8132,"children":8133},{"style":117},[8134],{"type":30,"value":4557},{"type":20,"tag":90,"props":8136,"children":8137},{"style":146},[8138],{"type":30,"value":4824},{"type":20,"tag":90,"props":8140,"children":8141},{"style":117},[8142],{"type":30,"value":6260},{"type":20,"tag":90,"props":8144,"children":8145},{"style":135},[8146],{"type":30,"value":6230},{"type":20,"tag":90,"props":8148,"children":8149},{"style":117},[8150],{"type":30,"value":6235},{"type":20,"tag":90,"props":8152,"children":8153},{"class":92,"line":247},[8154],{"type":20,"tag":90,"props":8155,"children":8156},{"style":117},[8157],{"type":30,"value":6624},{"type":20,"tag":90,"props":8159,"children":8160},{"class":92,"line":255},[8161,8166,8170,8174,8178,8182,8186],{"type":20,"tag":90,"props":8162,"children":8163},{"style":117},[8164],{"type":30,"value":8165},"io.SocketNamespace.",{"type":20,"tag":90,"props":8167,"children":8168},{"style":146},[8169],{"type":30,"value":4692},{"type":20,"tag":90,"props":8171,"children":8172},{"style":117},[8173],{"type":30,"value":6294},{"type":20,"tag":90,"props":8175,"children":8176},{"style":123},[8177],{"type":30,"value":126},{"type":20,"tag":90,"props":8179,"children":8180},{"style":117},[8181],{"type":30,"value":4687},{"type":20,"tag":90,"props":8183,"children":8184},{"style":146},[8185],{"type":30,"value":4692},{"type":20,"tag":90,"props":8187,"children":8188},{"style":117},[8189],{"type":30,"value":6311},{"type":20,"tag":21,"props":8191,"children":8192},{},[8193,8195,8200],{"type":30,"value":8194},"And here's the reason why we saved the io ",{"type":20,"tag":86,"props":8196,"children":8198},{"className":8197},[],[8199],{"type":30,"value":5692},{"type":30,"value":8201}," function earlier - this little shim sits in front of the standard emit and allows us to add a wildcard catch-all for events on a socket.",{"type":20,"tag":21,"props":8203,"children":8204},{},[8205],{"type":30,"value":8206},"And that's all folks! Of course, you'll need to support your implementation on the server-side - how exactly you go about that will depend on the language and library your using.",{"type":20,"tag":21,"props":8208,"children":8209},{},[8210],{"type":30,"value":8211},"I do have one more goodie for you, though - here's a version of the above tailored for those of you using Marionette:",{"type":20,"tag":79,"props":8213,"children":8215},{"className":4503,"code":8214,"language":4505,"meta":8,"style":8},"/**\n * Copyright (c) Christopher Keefer. All Rights Reserved.\n *\n * Overrides the default transport for Backbone syncing to use websockets via socket.io. Includes marionette     \n * convenience code, specifically for sending socket-related events along the global event aggregator.\n */\n(function(app, Backbone, Marionette, $, _, io){\n    var urlError = function(){\n        throw new Error('A \"url\" property or function must be specified.');\n    },\n        eventEmit = io.EventEmitter.prototype.emit,\n        ajaxSync = Backbone.sync;\n\n    /**\n     * Preserve the standard, jquery ajax based persistance method as ajaxSync.\n     */\n    Backbone.ajaxSync = function(method, model, options){\n        return ajaxSync.call(this, method, model, options);\n    };\n\n    /**\n     * Replace the standard sync function with our new, websocket/socket.io based solution.\n     */\n    Backbone.sync = function(method, model, options){\n        var opts = _.extend({}, options),\n            defer = $.Deferred(),\n            promise = defer.promise(),\n            namespace,\n            socket;\n\n        opts.url = (opts.url) ? _.result(opts, 'url') : (model.url) ? _.result(model, 'url') : void 0;\n        // If no url property has been specified, throw an error, as per the standard Backbone sync\n        if (!opts.url) urlError();\n        namespace = Backbone.Model.prototype.namespace.call(this, opts.url);\n        // Determine what data we're sending, and ensure id is present if we're performing a PATCH call\n        if (!opts.data && model) opts.data = opts.attrs || model.toJSON(options) || {};\n        if ((opts.data.id === null || opts.data.id === void 0) && opts.patch === true && model){\n            opts.data.id = model.id;\n        }\n        // Determine which websocket to use - set in options, on model, or on global app\n        socket = opts.socket || model.socket || app.socket;\n        // Trigger the app event aggregator for interested listeners to know we're about to request data via websocket\n        app.vent.trigger('backbone:request', namespace);\n        // Add a listener for our namespaced method, and resolve or reject our deferred based on the response\n        socket.once(namespace+method, function(res){\n            var success = (res && res.success);\n            // Trigger the app event aggregator to indicate we've received a return from the server, and success\n            app.vent.trigger('backbone:receive', namespace, success);\n            if (success)\n            {\n                if (_.isFunction(options.success)) options.success(res);\n                defer.resolve(res);\n                return;\n            }\n            if (_.isFunction(options.error)) options.error(res);\n            defer.reject(res);\n        });\n\n        // Emit our namespaced method and the model+opts data\n        socket.emit(namespace+method, opts.data);\n\n        // Trigger the request event on the model, as per backbone spec\n        model.trigger('request', model, promise, opts);\n        // Return the promise for us to use as per usual (hanging .done blocks off, add to a .when, etc.)\n        return promise;\n    };\n\n    /**\n     * Break url apart to create namespace - every '/' save any pre/post-fixing the url will become a ':' indicating\n     * namespace - so a collection that maps to /api/posts will now have its events on the namespace\n     * api:posts: (ie. api:posts:create, api:posts:delete, etc.), and a model that maps to /api/posts/21\n     * will have events on api:posts:21: (ie. api:posts:21:update, api:posts:21:patch, etc.)\n     * @param {string=} url\n     */\n    Backbone.Model.prototype.namespace = function(url){\n        url = url || this.url();\n        return _.trim(url, '/').replace('/', ':') + \":\";\n    };\n\n    /**\n     * Override EventEmitter.emit and SocketNamespace reference for socket.io to add a catch all case for the\n     * wildcard ('*') character. Now, socket.on('*') will catch any event, with the name of the caught event\n     * passed to the handler as the first argument.\n    */\n    io.EventEmitter.prototype.emit = function(name){\n        var args = Array.prototype.slice.call(arguments, 1);\n\n        eventEmit.apply(this, ['*', name].concat(args));\n        eventEmit.apply(this, [name].concat(args));\n    };\n    io.SocketNamespace.prototype.$emit = io.EventEmitter.prototype.emit;\n\n    /**\n     * Create a socket io instance that will echo all events into the application event aggregator, so that\n     * collections, models, etc. can listen on app.vent for their events.\n     * @param {string=} url\n     * @constructor\n     */\n    Marionette.Application.prototype.SocketIO = function(url){\n        var socket = io.connect(url, {\n            transports:['websocket']\n        });\n\n        /**\n         * On any event from the server, trigger it on the app event aggregator. The first\n         * argument will always be the name of the event.\n         */\n        socket.on('*', function(){\n            var args = Array.prototype.slice.call(arguments, 0);\n            app.vent.trigger(args[0], args.slice(1));\n        });\n\n        /**\n         * On error, trigger the socket:error event on the global event aggregator for \n         * interested listeners.\n         */\n        socket.on('error', function(err){\n            app.vent.trigger('socket:error', err);\n        });\n\n        return socket;\n    }\n})(app /* replace with your global app object */, Backbone, Backbone.Marionette, jQuery, _, io);\n",[8216],{"type":20,"tag":86,"props":8217,"children":8218},{"__ignoreMap":8},[8219,8226,8233,8240,8248,8256,8263,8327,8350,8377,8384,8407,8422,8429,8436,8443,8450,8497,8524,8531,8538,8545,8552,8559,8606,8633,8656,8679,8686,8693,8700,8787,8794,8821,8860,8867,8926,8993,9008,9015,9023,9056,9064,9090,9097,9136,9164,9172,9198,9209,9216,9243,9258,9269,9276,9303,9318,9325,9332,9339,9362,9369,9376,9399,9406,9417,9424,9431,9438,9445,9452,9459,9466,9485,9492,9531,9566,9629,9636,9643,9650,9657,9664,9671,9678,9717,9772,9779,9818,9850,9858,9890,9898,9906,9915,9924,9944,9957,9965,10007,10039,10057,10065,10073,10082,10091,10100,10109,10142,10199,10243,10251,10259,10267,10276,10285,10293,10335,10361,10369,10377,10390,10398],{"type":20,"tag":90,"props":8220,"children":8221},{"class":92,"line":93},[8222],{"type":20,"tag":90,"props":8223,"children":8224},{"style":97},[8225],{"type":30,"value":4517},{"type":20,"tag":90,"props":8227,"children":8228},{"class":92,"line":103},[8229],{"type":20,"tag":90,"props":8230,"children":8231},{"style":97},[8232],{"type":30,"value":4525},{"type":20,"tag":90,"props":8234,"children":8235},{"class":92,"line":113},[8236],{"type":20,"tag":90,"props":8237,"children":8238},{"style":97},[8239],{"type":30,"value":4533},{"type":20,"tag":90,"props":8241,"children":8242},{"class":92,"line":152},[8243],{"type":20,"tag":90,"props":8244,"children":8245},{"style":97},[8246],{"type":30,"value":8247}," * Overrides the default transport for Backbone syncing to use websockets via socket.io. Includes marionette     \n",{"type":20,"tag":90,"props":8249,"children":8250},{"class":92,"line":160},[8251],{"type":20,"tag":90,"props":8252,"children":8253},{"style":97},[8254],{"type":30,"value":8255}," * convenience code, specifically for sending socket-related events along the global event aggregator.\n",{"type":20,"tag":90,"props":8257,"children":8258},{"class":92,"line":174},[8259],{"type":20,"tag":90,"props":8260,"children":8261},{"style":97},[8262],{"type":30,"value":4549},{"type":20,"tag":90,"props":8264,"children":8265},{"class":92,"line":183},[8266,8270,8274,8278,8283,8287,8291,8295,8299,8303,8307,8311,8315,8319,8323],{"type":20,"tag":90,"props":8267,"children":8268},{"style":117},[8269],{"type":30,"value":4557},{"type":20,"tag":90,"props":8271,"children":8272},{"style":123},[8273],{"type":30,"value":4562},{"type":20,"tag":90,"props":8275,"children":8276},{"style":117},[8277],{"type":30,"value":4557},{"type":20,"tag":90,"props":8279,"children":8280},{"style":4569},[8281],{"type":30,"value":8282},"app",{"type":20,"tag":90,"props":8284,"children":8285},{"style":117},[8286],{"type":30,"value":1260},{"type":20,"tag":90,"props":8288,"children":8289},{"style":4569},[8290],{"type":30,"value":4572},{"type":20,"tag":90,"props":8292,"children":8293},{"style":117},[8294],{"type":30,"value":1260},{"type":20,"tag":90,"props":8296,"children":8297},{"style":4569},[8298],{"type":30,"value":4439},{"type":20,"tag":90,"props":8300,"children":8301},{"style":117},[8302],{"type":30,"value":1260},{"type":20,"tag":90,"props":8304,"children":8305},{"style":4569},[8306],{"type":30,"value":2452},{"type":20,"tag":90,"props":8308,"children":8309},{"style":117},[8310],{"type":30,"value":1260},{"type":20,"tag":90,"props":8312,"children":8313},{"style":4569},[8314],{"type":30,"value":4589},{"type":20,"tag":90,"props":8316,"children":8317},{"style":117},[8318],{"type":30,"value":1260},{"type":20,"tag":90,"props":8320,"children":8321},{"style":4569},[8322],{"type":30,"value":4598},{"type":20,"tag":90,"props":8324,"children":8325},{"style":117},[8326],{"type":30,"value":4603},{"type":20,"tag":90,"props":8328,"children":8329},{"class":92,"line":191},[8330,8334,8338,8342,8346],{"type":20,"tag":90,"props":8331,"children":8332},{"style":123},[8333],{"type":30,"value":4611},{"type":20,"tag":90,"props":8335,"children":8336},{"style":135},[8337],{"type":30,"value":4616},{"type":20,"tag":90,"props":8339,"children":8340},{"style":123},[8341],{"type":30,"value":1113},{"type":20,"tag":90,"props":8343,"children":8344},{"style":123},[8345],{"type":30,"value":4625},{"type":20,"tag":90,"props":8347,"children":8348},{"style":117},[8349],{"type":30,"value":4630},{"type":20,"tag":90,"props":8351,"children":8352},{"class":92,"line":200},[8353,8357,8361,8365,8369,8373],{"type":20,"tag":90,"props":8354,"children":8355},{"style":123},[8356],{"type":30,"value":4638},{"type":20,"tag":90,"props":8358,"children":8359},{"style":123},[8360],{"type":30,"value":4643},{"type":20,"tag":90,"props":8362,"children":8363},{"style":135},[8364],{"type":30,"value":4648},{"type":20,"tag":90,"props":8366,"children":8367},{"style":117},[8368],{"type":30,"value":4557},{"type":20,"tag":90,"props":8370,"children":8371},{"style":129},[8372],{"type":30,"value":4657},{"type":20,"tag":90,"props":8374,"children":8375},{"style":117},[8376],{"type":30,"value":4662},{"type":20,"tag":90,"props":8378,"children":8379},{"class":92,"line":229},[8380],{"type":20,"tag":90,"props":8381,"children":8382},{"style":117},[8383],{"type":30,"value":4670},{"type":20,"tag":90,"props":8385,"children":8386},{"class":92,"line":247},[8387,8391,8395,8399,8403],{"type":20,"tag":90,"props":8388,"children":8389},{"style":117},[8390],{"type":30,"value":4678},{"type":20,"tag":90,"props":8392,"children":8393},{"style":123},[8394],{"type":30,"value":126},{"type":20,"tag":90,"props":8396,"children":8397},{"style":117},[8398],{"type":30,"value":4687},{"type":20,"tag":90,"props":8400,"children":8401},{"style":146},[8402],{"type":30,"value":4692},{"type":20,"tag":90,"props":8404,"children":8405},{"style":117},[8406],{"type":30,"value":4697},{"type":20,"tag":90,"props":8408,"children":8409},{"class":92,"line":255},[8410,8414,8418],{"type":20,"tag":90,"props":8411,"children":8412},{"style":117},[8413],{"type":30,"value":4705},{"type":20,"tag":90,"props":8415,"children":8416},{"style":123},[8417],{"type":30,"value":126},{"type":20,"tag":90,"props":8419,"children":8420},{"style":117},[8421],{"type":30,"value":4714},{"type":20,"tag":90,"props":8423,"children":8424},{"class":92,"line":264},[8425],{"type":20,"tag":90,"props":8426,"children":8427},{"emptyLinePlaceholder":107},[8428],{"type":30,"value":110},{"type":20,"tag":90,"props":8430,"children":8431},{"class":92,"line":273},[8432],{"type":20,"tag":90,"props":8433,"children":8434},{"style":97},[8435],{"type":30,"value":4729},{"type":20,"tag":90,"props":8437,"children":8438},{"class":92,"line":292},[8439],{"type":20,"tag":90,"props":8440,"children":8441},{"style":97},[8442],{"type":30,"value":4737},{"type":20,"tag":90,"props":8444,"children":8445},{"class":92,"line":1658},[8446],{"type":20,"tag":90,"props":8447,"children":8448},{"style":97},[8449],{"type":30,"value":4745},{"type":20,"tag":90,"props":8451,"children":8452},{"class":92,"line":2281},[8453,8457,8461,8465,8469,8473,8477,8481,8485,8489,8493],{"type":20,"tag":90,"props":8454,"children":8455},{"style":117},[8456],{"type":30,"value":4753},{"type":20,"tag":90,"props":8458,"children":8459},{"style":135},[8460],{"type":30,"value":4758},{"type":20,"tag":90,"props":8462,"children":8463},{"style":123},[8464],{"type":30,"value":1113},{"type":20,"tag":90,"props":8466,"children":8467},{"style":123},[8468],{"type":30,"value":4625},{"type":20,"tag":90,"props":8470,"children":8471},{"style":117},[8472],{"type":30,"value":4557},{"type":20,"tag":90,"props":8474,"children":8475},{"style":4569},[8476],{"type":30,"value":4775},{"type":20,"tag":90,"props":8478,"children":8479},{"style":117},[8480],{"type":30,"value":1260},{"type":20,"tag":90,"props":8482,"children":8483},{"style":4569},[8484],{"type":30,"value":4784},{"type":20,"tag":90,"props":8486,"children":8487},{"style":117},[8488],{"type":30,"value":1260},{"type":20,"tag":90,"props":8490,"children":8491},{"style":4569},[8492],{"type":30,"value":4793},{"type":20,"tag":90,"props":8494,"children":8495},{"style":117},[8496],{"type":30,"value":4603},{"type":20,"tag":90,"props":8498,"children":8499},{"class":92,"line":2290},[8500,8504,8508,8512,8516,8520],{"type":20,"tag":90,"props":8501,"children":8502},{"style":123},[8503],{"type":30,"value":4805},{"type":20,"tag":90,"props":8505,"children":8506},{"style":117},[8507],{"type":30,"value":4810},{"type":20,"tag":90,"props":8509,"children":8510},{"style":135},[8511],{"type":30,"value":4815},{"type":20,"tag":90,"props":8513,"children":8514},{"style":117},[8515],{"type":30,"value":4557},{"type":20,"tag":90,"props":8517,"children":8518},{"style":146},[8519],{"type":30,"value":4824},{"type":20,"tag":90,"props":8521,"children":8522},{"style":117},[8523],{"type":30,"value":4829},{"type":20,"tag":90,"props":8525,"children":8526},{"class":92,"line":2298},[8527],{"type":20,"tag":90,"props":8528,"children":8529},{"style":117},[8530],{"type":30,"value":4837},{"type":20,"tag":90,"props":8532,"children":8533},{"class":92,"line":2316},[8534],{"type":20,"tag":90,"props":8535,"children":8536},{"emptyLinePlaceholder":107},[8537],{"type":30,"value":110},{"type":20,"tag":90,"props":8539,"children":8540},{"class":92,"line":2325},[8541],{"type":20,"tag":90,"props":8542,"children":8543},{"style":97},[8544],{"type":30,"value":4729},{"type":20,"tag":90,"props":8546,"children":8547},{"class":92,"line":2344},[8548],{"type":20,"tag":90,"props":8549,"children":8550},{"style":97},[8551],{"type":30,"value":4859},{"type":20,"tag":90,"props":8553,"children":8554},{"class":92,"line":2352},[8555],{"type":20,"tag":90,"props":8556,"children":8557},{"style":97},[8558],{"type":30,"value":4745},{"type":20,"tag":90,"props":8560,"children":8561},{"class":92,"line":2361},[8562,8566,8570,8574,8578,8582,8586,8590,8594,8598,8602],{"type":20,"tag":90,"props":8563,"children":8564},{"style":117},[8565],{"type":30,"value":4753},{"type":20,"tag":90,"props":8567,"children":8568},{"style":135},[8569],{"type":30,"value":4878},{"type":20,"tag":90,"props":8571,"children":8572},{"style":123},[8573],{"type":30,"value":1113},{"type":20,"tag":90,"props":8575,"children":8576},{"style":123},[8577],{"type":30,"value":4625},{"type":20,"tag":90,"props":8579,"children":8580},{"style":117},[8581],{"type":30,"value":4557},{"type":20,"tag":90,"props":8583,"children":8584},{"style":4569},[8585],{"type":30,"value":4775},{"type":20,"tag":90,"props":8587,"children":8588},{"style":117},[8589],{"type":30,"value":1260},{"type":20,"tag":90,"props":8591,"children":8592},{"style":4569},[8593],{"type":30,"value":4784},{"type":20,"tag":90,"props":8595,"children":8596},{"style":117},[8597],{"type":30,"value":1260},{"type":20,"tag":90,"props":8599,"children":8600},{"style":4569},[8601],{"type":30,"value":4793},{"type":20,"tag":90,"props":8603,"children":8604},{"style":117},[8605],{"type":30,"value":4603},{"type":20,"tag":90,"props":8607,"children":8608},{"class":92,"line":2379},[8609,8613,8617,8621,8625,8629],{"type":20,"tag":90,"props":8610,"children":8611},{"style":123},[8612],{"type":30,"value":4922},{"type":20,"tag":90,"props":8614,"children":8615},{"style":117},[8616],{"type":30,"value":4927},{"type":20,"tag":90,"props":8618,"children":8619},{"style":123},[8620],{"type":30,"value":126},{"type":20,"tag":90,"props":8622,"children":8623},{"style":117},[8624],{"type":30,"value":4936},{"type":20,"tag":90,"props":8626,"children":8627},{"style":135},[8628],{"type":30,"value":4941},{"type":20,"tag":90,"props":8630,"children":8631},{"style":117},[8632],{"type":30,"value":4946},{"type":20,"tag":90,"props":8634,"children":8635},{"class":92,"line":2387},[8636,8640,8644,8648,8652],{"type":20,"tag":90,"props":8637,"children":8638},{"style":117},[8639],{"type":30,"value":4954},{"type":20,"tag":90,"props":8641,"children":8642},{"style":123},[8643],{"type":30,"value":126},{"type":20,"tag":90,"props":8645,"children":8646},{"style":117},[8647],{"type":30,"value":4963},{"type":20,"tag":90,"props":8649,"children":8650},{"style":135},[8651],{"type":30,"value":4968},{"type":20,"tag":90,"props":8653,"children":8654},{"style":117},[8655],{"type":30,"value":4973},{"type":20,"tag":90,"props":8657,"children":8658},{"class":92,"line":2396},[8659,8663,8667,8671,8675],{"type":20,"tag":90,"props":8660,"children":8661},{"style":117},[8662],{"type":30,"value":4981},{"type":20,"tag":90,"props":8664,"children":8665},{"style":123},[8666],{"type":30,"value":126},{"type":20,"tag":90,"props":8668,"children":8669},{"style":117},[8670],{"type":30,"value":4990},{"type":20,"tag":90,"props":8672,"children":8673},{"style":135},[8674],{"type":30,"value":4995},{"type":20,"tag":90,"props":8676,"children":8677},{"style":117},[8678],{"type":30,"value":4973},{"type":20,"tag":90,"props":8680,"children":8681},{"class":92,"line":2405},[8682],{"type":20,"tag":90,"props":8683,"children":8684},{"style":117},[8685],{"type":30,"value":5007},{"type":20,"tag":90,"props":8687,"children":8688},{"class":92,"line":2413},[8689],{"type":20,"tag":90,"props":8690,"children":8691},{"style":117},[8692],{"type":30,"value":5015},{"type":20,"tag":90,"props":8694,"children":8695},{"class":92,"line":2422},[8696],{"type":20,"tag":90,"props":8697,"children":8698},{"emptyLinePlaceholder":107},[8699],{"type":30,"value":110},{"type":20,"tag":90,"props":8701,"children":8702},{"class":92,"line":2460},[8703,8707,8711,8715,8719,8723,8727,8731,8735,8739,8743,8747,8751,8755,8759,8763,8767,8771,8775,8779,8783],{"type":20,"tag":90,"props":8704,"children":8705},{"style":117},[8706],{"type":30,"value":5030},{"type":20,"tag":90,"props":8708,"children":8709},{"style":123},[8710],{"type":30,"value":126},{"type":20,"tag":90,"props":8712,"children":8713},{"style":117},[8714],{"type":30,"value":5039},{"type":20,"tag":90,"props":8716,"children":8717},{"style":123},[8718],{"type":30,"value":5044},{"type":20,"tag":90,"props":8720,"children":8721},{"style":117},[8722],{"type":30,"value":4936},{"type":20,"tag":90,"props":8724,"children":8725},{"style":135},[8726],{"type":30,"value":5053},{"type":20,"tag":90,"props":8728,"children":8729},{"style":117},[8730],{"type":30,"value":5058},{"type":20,"tag":90,"props":8732,"children":8733},{"style":129},[8734],{"type":30,"value":5063},{"type":20,"tag":90,"props":8736,"children":8737},{"style":117},[8738],{"type":30,"value":5068},{"type":20,"tag":90,"props":8740,"children":8741},{"style":123},[8742],{"type":30,"value":1717},{"type":20,"tag":90,"props":8744,"children":8745},{"style":117},[8746],{"type":30,"value":5077},{"type":20,"tag":90,"props":8748,"children":8749},{"style":123},[8750],{"type":30,"value":5044},{"type":20,"tag":90,"props":8752,"children":8753},{"style":117},[8754],{"type":30,"value":4936},{"type":20,"tag":90,"props":8756,"children":8757},{"style":135},[8758],{"type":30,"value":5053},{"type":20,"tag":90,"props":8760,"children":8761},{"style":117},[8762],{"type":30,"value":5094},{"type":20,"tag":90,"props":8764,"children":8765},{"style":129},[8766],{"type":30,"value":5063},{"type":20,"tag":90,"props":8768,"children":8769},{"style":117},[8770],{"type":30,"value":5068},{"type":20,"tag":90,"props":8772,"children":8773},{"style":123},[8774],{"type":30,"value":1717},{"type":20,"tag":90,"props":8776,"children":8777},{"style":123},[8778],{"type":30,"value":5111},{"type":20,"tag":90,"props":8780,"children":8781},{"style":146},[8782],{"type":30,"value":5116},{"type":20,"tag":90,"props":8784,"children":8785},{"style":117},[8786],{"type":30,"value":2151},{"type":20,"tag":90,"props":8788,"children":8789},{"class":92,"line":2468},[8790],{"type":20,"tag":90,"props":8791,"children":8792},{"style":97},[8793],{"type":30,"value":5128},{"type":20,"tag":90,"props":8795,"children":8796},{"class":92,"line":2477},[8797,8801,8805,8809,8813,8817],{"type":20,"tag":90,"props":8798,"children":8799},{"style":123},[8800],{"type":30,"value":5136},{"type":20,"tag":90,"props":8802,"children":8803},{"style":117},[8804],{"type":30,"value":5141},{"type":20,"tag":90,"props":8806,"children":8807},{"style":123},[8808],{"type":30,"value":5146},{"type":20,"tag":90,"props":8810,"children":8811},{"style":117},[8812],{"type":30,"value":5151},{"type":20,"tag":90,"props":8814,"children":8815},{"style":135},[8816],{"type":30,"value":5156},{"type":20,"tag":90,"props":8818,"children":8819},{"style":117},[8820],{"type":30,"value":5161},{"type":20,"tag":90,"props":8822,"children":8823},{"class":92,"line":2486},[8824,8828,8832,8836,8840,8844,8848,8852,8856],{"type":20,"tag":90,"props":8825,"children":8826},{"style":117},[8827],{"type":30,"value":5177},{"type":20,"tag":90,"props":8829,"children":8830},{"style":123},[8831],{"type":30,"value":126},{"type":20,"tag":90,"props":8833,"children":8834},{"style":117},[8835],{"type":30,"value":5186},{"type":20,"tag":90,"props":8837,"children":8838},{"style":146},[8839],{"type":30,"value":4692},{"type":20,"tag":90,"props":8841,"children":8842},{"style":117},[8843],{"type":30,"value":5195},{"type":20,"tag":90,"props":8845,"children":8846},{"style":135},[8847],{"type":30,"value":4815},{"type":20,"tag":90,"props":8849,"children":8850},{"style":117},[8851],{"type":30,"value":4557},{"type":20,"tag":90,"props":8853,"children":8854},{"style":146},[8855],{"type":30,"value":4824},{"type":20,"tag":90,"props":8857,"children":8858},{"style":117},[8859],{"type":30,"value":5212},{"type":20,"tag":90,"props":8861,"children":8862},{"class":92,"line":2494},[8863],{"type":20,"tag":90,"props":8864,"children":8865},{"style":97},[8866],{"type":30,"value":5220},{"type":20,"tag":90,"props":8868,"children":8869},{"class":92,"line":2503},[8870,8874,8878,8882,8886,8890,8894,8898,8902,8906,8910,8914,8918,8922],{"type":20,"tag":90,"props":8871,"children":8872},{"style":123},[8873],{"type":30,"value":5136},{"type":20,"tag":90,"props":8875,"children":8876},{"style":117},[8877],{"type":30,"value":5141},{"type":20,"tag":90,"props":8879,"children":8880},{"style":123},[8881],{"type":30,"value":5146},{"type":20,"tag":90,"props":8883,"children":8884},{"style":117},[8885],{"type":30,"value":5240},{"type":20,"tag":90,"props":8887,"children":8888},{"style":123},[8889],{"type":30,"value":5245},{"type":20,"tag":90,"props":8891,"children":8892},{"style":117},[8893],{"type":30,"value":5250},{"type":20,"tag":90,"props":8895,"children":8896},{"style":123},[8897],{"type":30,"value":126},{"type":20,"tag":90,"props":8899,"children":8900},{"style":117},[8901],{"type":30,"value":5259},{"type":20,"tag":90,"props":8903,"children":8904},{"style":123},[8905],{"type":30,"value":5264},{"type":20,"tag":90,"props":8907,"children":8908},{"style":117},[8909],{"type":30,"value":5269},{"type":20,"tag":90,"props":8911,"children":8912},{"style":135},[8913],{"type":30,"value":5274},{"type":20,"tag":90,"props":8915,"children":8916},{"style":117},[8917],{"type":30,"value":5279},{"type":20,"tag":90,"props":8919,"children":8920},{"style":123},[8921],{"type":30,"value":5264},{"type":20,"tag":90,"props":8923,"children":8924},{"style":117},[8925],{"type":30,"value":5288},{"type":20,"tag":90,"props":8927,"children":8928},{"class":92,"line":2521},[8929,8933,8937,8941,8945,8949,8953,8957,8961,8965,8969,8973,8977,8981,8985,8989],{"type":20,"tag":90,"props":8930,"children":8931},{"style":123},[8932],{"type":30,"value":5136},{"type":20,"tag":90,"props":8934,"children":8935},{"style":117},[8936],{"type":30,"value":5300},{"type":20,"tag":90,"props":8938,"children":8939},{"style":123},[8940],{"type":30,"value":5305},{"type":20,"tag":90,"props":8942,"children":8943},{"style":146},[8944],{"type":30,"value":5310},{"type":20,"tag":90,"props":8946,"children":8947},{"style":123},[8948],{"type":30,"value":5315},{"type":20,"tag":90,"props":8950,"children":8951},{"style":117},[8952],{"type":30,"value":5320},{"type":20,"tag":90,"props":8954,"children":8955},{"style":123},[8956],{"type":30,"value":5305},{"type":20,"tag":90,"props":8958,"children":8959},{"style":123},[8960],{"type":30,"value":5111},{"type":20,"tag":90,"props":8962,"children":8963},{"style":146},[8964],{"type":30,"value":5116},{"type":20,"tag":90,"props":8966,"children":8967},{"style":117},[8968],{"type":30,"value":5068},{"type":20,"tag":90,"props":8970,"children":8971},{"style":123},[8972],{"type":30,"value":5245},{"type":20,"tag":90,"props":8974,"children":8975},{"style":117},[8976],{"type":30,"value":5345},{"type":20,"tag":90,"props":8978,"children":8979},{"style":123},[8980],{"type":30,"value":5305},{"type":20,"tag":90,"props":8982,"children":8983},{"style":146},[8984],{"type":30,"value":5354},{"type":20,"tag":90,"props":8986,"children":8987},{"style":123},[8988],{"type":30,"value":5359},{"type":20,"tag":90,"props":8990,"children":8991},{"style":117},[8992],{"type":30,"value":5364},{"type":20,"tag":90,"props":8994,"children":8995},{"class":92,"line":2529},[8996,9000,9004],{"type":20,"tag":90,"props":8997,"children":8998},{"style":117},[8999],{"type":30,"value":5372},{"type":20,"tag":90,"props":9001,"children":9002},{"style":123},[9003],{"type":30,"value":126},{"type":20,"tag":90,"props":9005,"children":9006},{"style":117},[9007],{"type":30,"value":5381},{"type":20,"tag":90,"props":9009,"children":9010},{"class":92,"line":2538},[9011],{"type":20,"tag":90,"props":9012,"children":9013},{"style":117},[9014],{"type":30,"value":5389},{"type":20,"tag":90,"props":9016,"children":9017},{"class":92,"line":2547},[9018],{"type":20,"tag":90,"props":9019,"children":9020},{"style":97},[9021],{"type":30,"value":9022},"        // Determine which websocket to use - set in options, on model, or on global app\n",{"type":20,"tag":90,"props":9024,"children":9025},{"class":92,"line":2556},[9026,9030,9034,9038,9042,9047,9051],{"type":20,"tag":90,"props":9027,"children":9028},{"style":117},[9029],{"type":30,"value":5405},{"type":20,"tag":90,"props":9031,"children":9032},{"style":123},[9033],{"type":30,"value":126},{"type":20,"tag":90,"props":9035,"children":9036},{"style":117},[9037],{"type":30,"value":5414},{"type":20,"tag":90,"props":9039,"children":9040},{"style":123},[9041],{"type":30,"value":5264},{"type":20,"tag":90,"props":9043,"children":9044},{"style":117},[9045],{"type":30,"value":9046}," model.socket ",{"type":20,"tag":90,"props":9048,"children":9049},{"style":123},[9050],{"type":30,"value":5264},{"type":20,"tag":90,"props":9052,"children":9053},{"style":117},[9054],{"type":30,"value":9055}," app.socket;\n",{"type":20,"tag":90,"props":9057,"children":9058},{"class":92,"line":2564},[9059],{"type":20,"tag":90,"props":9060,"children":9061},{"style":97},[9062],{"type":30,"value":9063},"        // Trigger the app event aggregator for interested listeners to know we're about to request data via websocket\n",{"type":20,"tag":90,"props":9065,"children":9066},{"class":92,"line":2573},[9067,9072,9076,9080,9085],{"type":20,"tag":90,"props":9068,"children":9069},{"style":117},[9070],{"type":30,"value":9071},"        app.vent.",{"type":20,"tag":90,"props":9073,"children":9074},{"style":135},[9075],{"type":30,"value":5736},{"type":20,"tag":90,"props":9077,"children":9078},{"style":117},[9079],{"type":30,"value":4557},{"type":20,"tag":90,"props":9081,"children":9082},{"style":129},[9083],{"type":30,"value":9084},"'backbone:request'",{"type":20,"tag":90,"props":9086,"children":9087},{"style":117},[9088],{"type":30,"value":9089},", namespace);\n",{"type":20,"tag":90,"props":9091,"children":9092},{"class":92,"line":2582},[9093],{"type":20,"tag":90,"props":9094,"children":9095},{"style":97},[9096],{"type":30,"value":5431},{"type":20,"tag":90,"props":9098,"children":9099},{"class":92,"line":2600},[9100,9104,9108,9112,9116,9120,9124,9128,9132],{"type":20,"tag":90,"props":9101,"children":9102},{"style":117},[9103],{"type":30,"value":5439},{"type":20,"tag":90,"props":9105,"children":9106},{"style":135},[9107],{"type":30,"value":5444},{"type":20,"tag":90,"props":9109,"children":9110},{"style":117},[9111],{"type":30,"value":5449},{"type":20,"tag":90,"props":9113,"children":9114},{"style":123},[9115],{"type":30,"value":5454},{"type":20,"tag":90,"props":9117,"children":9118},{"style":117},[9119],{"type":30,"value":5459},{"type":20,"tag":90,"props":9121,"children":9122},{"style":123},[9123],{"type":30,"value":4562},{"type":20,"tag":90,"props":9125,"children":9126},{"style":117},[9127],{"type":30,"value":4557},{"type":20,"tag":90,"props":9129,"children":9130},{"style":4569},[9131],{"type":30,"value":5472},{"type":20,"tag":90,"props":9133,"children":9134},{"style":117},[9135],{"type":30,"value":4603},{"type":20,"tag":90,"props":9137,"children":9138},{"class":92,"line":2608},[9139,9143,9147,9151,9155,9159],{"type":20,"tag":90,"props":9140,"children":9141},{"style":123},[9142],{"type":30,"value":5484},{"type":20,"tag":90,"props":9144,"children":9145},{"style":117},[9146],{"type":30,"value":5489},{"type":20,"tag":90,"props":9148,"children":9149},{"style":123},[9150],{"type":30,"value":126},{"type":20,"tag":90,"props":9152,"children":9153},{"style":117},[9154],{"type":30,"value":5498},{"type":20,"tag":90,"props":9156,"children":9157},{"style":123},[9158],{"type":30,"value":5245},{"type":20,"tag":90,"props":9160,"children":9161},{"style":117},[9162],{"type":30,"value":9163}," res.success);\n",{"type":20,"tag":90,"props":9165,"children":9166},{"class":92,"line":2626},[9167],{"type":20,"tag":90,"props":9168,"children":9169},{"style":97},[9170],{"type":30,"value":9171},"            // Trigger the app event aggregator to indicate we've received a return from the server, and success\n",{"type":20,"tag":90,"props":9173,"children":9174},{"class":92,"line":2634},[9175,9180,9184,9188,9193],{"type":20,"tag":90,"props":9176,"children":9177},{"style":117},[9178],{"type":30,"value":9179},"            app.vent.",{"type":20,"tag":90,"props":9181,"children":9182},{"style":135},[9183],{"type":30,"value":5736},{"type":20,"tag":90,"props":9185,"children":9186},{"style":117},[9187],{"type":30,"value":4557},{"type":20,"tag":90,"props":9189,"children":9190},{"style":129},[9191],{"type":30,"value":9192},"'backbone:receive'",{"type":20,"tag":90,"props":9194,"children":9195},{"style":117},[9196],{"type":30,"value":9197},", namespace, success);\n",{"type":20,"tag":90,"props":9199,"children":9200},{"class":92,"line":5586},[9201,9205],{"type":20,"tag":90,"props":9202,"children":9203},{"style":123},[9204],{"type":30,"value":5520},{"type":20,"tag":90,"props":9206,"children":9207},{"style":117},[9208],{"type":30,"value":5525},{"type":20,"tag":90,"props":9210,"children":9211},{"class":92,"line":5599},[9212],{"type":20,"tag":90,"props":9213,"children":9214},{"style":117},[9215],{"type":30,"value":5533},{"type":20,"tag":90,"props":9217,"children":9218},{"class":92,"line":5608},[9219,9223,9227,9231,9235,9239],{"type":20,"tag":90,"props":9220,"children":9221},{"style":123},[9222],{"type":30,"value":5541},{"type":20,"tag":90,"props":9224,"children":9225},{"style":117},[9226],{"type":30,"value":5546},{"type":20,"tag":90,"props":9228,"children":9229},{"style":135},[9230],{"type":30,"value":5551},{"type":20,"tag":90,"props":9232,"children":9233},{"style":117},[9234],{"type":30,"value":5556},{"type":20,"tag":90,"props":9236,"children":9237},{"style":135},[9238],{"type":30,"value":5561},{"type":20,"tag":90,"props":9240,"children":9241},{"style":117},[9242],{"type":30,"value":5566},{"type":20,"tag":90,"props":9244,"children":9245},{"class":92,"line":5638},[9246,9250,9254],{"type":20,"tag":90,"props":9247,"children":9248},{"style":117},[9249],{"type":30,"value":5574},{"type":20,"tag":90,"props":9251,"children":9252},{"style":135},[9253],{"type":30,"value":5579},{"type":20,"tag":90,"props":9255,"children":9256},{"style":117},[9257],{"type":30,"value":5566},{"type":20,"tag":90,"props":9259,"children":9260},{"class":92,"line":5656},[9261,9265],{"type":20,"tag":90,"props":9262,"children":9263},{"style":123},[9264],{"type":30,"value":5592},{"type":20,"tag":90,"props":9266,"children":9267},{"style":117},[9268],{"type":30,"value":2151},{"type":20,"tag":90,"props":9270,"children":9271},{"class":92,"line":5665},[9272],{"type":20,"tag":90,"props":9273,"children":9274},{"style":117},[9275],{"type":30,"value":5605},{"type":20,"tag":90,"props":9277,"children":9278},{"class":92,"line":5673},[9279,9283,9287,9291,9295,9299],{"type":20,"tag":90,"props":9280,"children":9281},{"style":123},[9282],{"type":30,"value":5520},{"type":20,"tag":90,"props":9284,"children":9285},{"style":117},[9286],{"type":30,"value":5546},{"type":20,"tag":90,"props":9288,"children":9289},{"style":135},[9290],{"type":30,"value":5551},{"type":20,"tag":90,"props":9292,"children":9293},{"style":117},[9294],{"type":30,"value":5626},{"type":20,"tag":90,"props":9296,"children":9297},{"style":135},[9298],{"type":30,"value":5631},{"type":20,"tag":90,"props":9300,"children":9301},{"style":117},[9302],{"type":30,"value":5566},{"type":20,"tag":90,"props":9304,"children":9305},{"class":92,"line":5682},[9306,9310,9314],{"type":20,"tag":90,"props":9307,"children":9308},{"style":117},[9309],{"type":30,"value":5644},{"type":20,"tag":90,"props":9311,"children":9312},{"style":135},[9313],{"type":30,"value":5649},{"type":20,"tag":90,"props":9315,"children":9316},{"style":117},[9317],{"type":30,"value":5566},{"type":20,"tag":90,"props":9319,"children":9320},{"class":92,"line":5708},[9321],{"type":20,"tag":90,"props":9322,"children":9323},{"style":117},[9324],{"type":30,"value":5662},{"type":20,"tag":90,"props":9326,"children":9327},{"class":92,"line":5716},[9328],{"type":20,"tag":90,"props":9329,"children":9330},{"emptyLinePlaceholder":107},[9331],{"type":30,"value":110},{"type":20,"tag":90,"props":9333,"children":9334},{"class":92,"line":5725},[9335],{"type":20,"tag":90,"props":9336,"children":9337},{"style":97},[9338],{"type":30,"value":5679},{"type":20,"tag":90,"props":9340,"children":9341},{"class":92,"line":5753},[9342,9346,9350,9354,9358],{"type":20,"tag":90,"props":9343,"children":9344},{"style":117},[9345],{"type":30,"value":5439},{"type":20,"tag":90,"props":9347,"children":9348},{"style":135},[9349],{"type":30,"value":5692},{"type":20,"tag":90,"props":9351,"children":9352},{"style":117},[9353],{"type":30,"value":5449},{"type":20,"tag":90,"props":9355,"children":9356},{"style":123},[9357],{"type":30,"value":5454},{"type":20,"tag":90,"props":9359,"children":9360},{"style":117},[9361],{"type":30,"value":5705},{"type":20,"tag":90,"props":9363,"children":9364},{"class":92,"line":5762},[9365],{"type":20,"tag":90,"props":9366,"children":9367},{"emptyLinePlaceholder":107},[9368],{"type":30,"value":110},{"type":20,"tag":90,"props":9370,"children":9371},{"class":92,"line":5775},[9372],{"type":20,"tag":90,"props":9373,"children":9374},{"style":97},[9375],{"type":30,"value":5722},{"type":20,"tag":90,"props":9377,"children":9378},{"class":92,"line":5783},[9379,9383,9387,9391,9395],{"type":20,"tag":90,"props":9380,"children":9381},{"style":117},[9382],{"type":30,"value":5731},{"type":20,"tag":90,"props":9384,"children":9385},{"style":135},[9386],{"type":30,"value":5736},{"type":20,"tag":90,"props":9388,"children":9389},{"style":117},[9390],{"type":30,"value":4557},{"type":20,"tag":90,"props":9392,"children":9393},{"style":129},[9394],{"type":30,"value":5745},{"type":20,"tag":90,"props":9396,"children":9397},{"style":117},[9398],{"type":30,"value":5750},{"type":20,"tag":90,"props":9400,"children":9401},{"class":92,"line":5791},[9402],{"type":20,"tag":90,"props":9403,"children":9404},{"style":97},[9405],{"type":30,"value":5759},{"type":20,"tag":90,"props":9407,"children":9408},{"class":92,"line":5799},[9409,9413],{"type":20,"tag":90,"props":9410,"children":9411},{"style":123},[9412],{"type":30,"value":4805},{"type":20,"tag":90,"props":9414,"children":9415},{"style":117},[9416],{"type":30,"value":5772},{"type":20,"tag":90,"props":9418,"children":9419},{"class":92,"line":5808},[9420],{"type":20,"tag":90,"props":9421,"children":9422},{"style":117},[9423],{"type":30,"value":4837},{"type":20,"tag":90,"props":9425,"children":9426},{"class":92,"line":5817},[9427],{"type":20,"tag":90,"props":9428,"children":9429},{"emptyLinePlaceholder":107},[9430],{"type":30,"value":110},{"type":20,"tag":90,"props":9432,"children":9433},{"class":92,"line":5826},[9434],{"type":20,"tag":90,"props":9435,"children":9436},{"style":97},[9437],{"type":30,"value":4729},{"type":20,"tag":90,"props":9439,"children":9440},{"class":92,"line":5835},[9441],{"type":20,"tag":90,"props":9442,"children":9443},{"style":97},[9444],{"type":30,"value":5805},{"type":20,"tag":90,"props":9446,"children":9447},{"class":92,"line":5859},[9448],{"type":20,"tag":90,"props":9449,"children":9450},{"style":97},[9451],{"type":30,"value":5814},{"type":20,"tag":90,"props":9453,"children":9454},{"class":92,"line":5867},[9455],{"type":20,"tag":90,"props":9456,"children":9457},{"style":97},[9458],{"type":30,"value":5823},{"type":20,"tag":90,"props":9460,"children":9461},{"class":92,"line":5910},[9462],{"type":20,"tag":90,"props":9463,"children":9464},{"style":97},[9465],{"type":30,"value":5832},{"type":20,"tag":90,"props":9467,"children":9468},{"class":92,"line":5949},[9469,9473,9477,9481],{"type":20,"tag":90,"props":9470,"children":9471},{"style":97},[9472],{"type":30,"value":5841},{"type":20,"tag":90,"props":9474,"children":9475},{"style":123},[9476],{"type":30,"value":5846},{"type":20,"tag":90,"props":9478,"children":9479},{"style":135},[9480],{"type":30,"value":5851},{"type":20,"tag":90,"props":9482,"children":9483},{"style":117},[9484],{"type":30,"value":5856},{"type":20,"tag":90,"props":9486,"children":9487},{"class":92,"line":6020},[9488],{"type":20,"tag":90,"props":9489,"children":9490},{"style":97},[9491],{"type":30,"value":4745},{"type":20,"tag":90,"props":9493,"children":9494},{"class":92,"line":6028},[9495,9499,9503,9507,9511,9515,9519,9523,9527],{"type":20,"tag":90,"props":9496,"children":9497},{"style":117},[9498],{"type":30,"value":5873},{"type":20,"tag":90,"props":9500,"children":9501},{"style":146},[9502],{"type":30,"value":4692},{"type":20,"tag":90,"props":9504,"children":9505},{"style":117},[9506],{"type":30,"value":615},{"type":20,"tag":90,"props":9508,"children":9509},{"style":135},[9510],{"type":30,"value":5886},{"type":20,"tag":90,"props":9512,"children":9513},{"style":123},[9514],{"type":30,"value":1113},{"type":20,"tag":90,"props":9516,"children":9517},{"style":123},[9518],{"type":30,"value":4625},{"type":20,"tag":90,"props":9520,"children":9521},{"style":117},[9522],{"type":30,"value":4557},{"type":20,"tag":90,"props":9524,"children":9525},{"style":4569},[9526],{"type":30,"value":5903},{"type":20,"tag":90,"props":9528,"children":9529},{"style":117},[9530],{"type":30,"value":4603},{"type":20,"tag":90,"props":9532,"children":9533},{"class":92,"line":6036},[9534,9538,9542,9546,9550,9554,9558,9562],{"type":20,"tag":90,"props":9535,"children":9536},{"style":117},[9537],{"type":30,"value":5916},{"type":20,"tag":90,"props":9539,"children":9540},{"style":123},[9541],{"type":30,"value":126},{"type":20,"tag":90,"props":9543,"children":9544},{"style":117},[9545],{"type":30,"value":5925},{"type":20,"tag":90,"props":9547,"children":9548},{"style":123},[9549],{"type":30,"value":5264},{"type":20,"tag":90,"props":9551,"children":9552},{"style":146},[9553],{"type":30,"value":5934},{"type":20,"tag":90,"props":9555,"children":9556},{"style":117},[9557],{"type":30,"value":615},{"type":20,"tag":90,"props":9559,"children":9560},{"style":135},[9561],{"type":30,"value":5903},{"type":20,"tag":90,"props":9563,"children":9564},{"style":117},[9565],{"type":30,"value":5161},{"type":20,"tag":90,"props":9567,"children":9568},{"class":92,"line":6044},[9569,9573,9577,9581,9585,9589,9593,9597,9601,9605,9609,9613,9617,9621,9625],{"type":20,"tag":90,"props":9570,"children":9571},{"style":123},[9572],{"type":30,"value":4805},{"type":20,"tag":90,"props":9574,"children":9575},{"style":117},[9576],{"type":30,"value":4936},{"type":20,"tag":90,"props":9578,"children":9579},{"style":135},[9580],{"type":30,"value":5963},{"type":20,"tag":90,"props":9582,"children":9583},{"style":117},[9584],{"type":30,"value":5968},{"type":20,"tag":90,"props":9586,"children":9587},{"style":129},[9588],{"type":30,"value":5973},{"type":20,"tag":90,"props":9590,"children":9591},{"style":117},[9592],{"type":30,"value":5978},{"type":20,"tag":90,"props":9594,"children":9595},{"style":135},[9596],{"type":30,"value":5983},{"type":20,"tag":90,"props":9598,"children":9599},{"style":117},[9600],{"type":30,"value":4557},{"type":20,"tag":90,"props":9602,"children":9603},{"style":129},[9604],{"type":30,"value":5973},{"type":20,"tag":90,"props":9606,"children":9607},{"style":117},[9608],{"type":30,"value":1260},{"type":20,"tag":90,"props":9610,"children":9611},{"style":129},[9612],{"type":30,"value":6000},{"type":20,"tag":90,"props":9614,"children":9615},{"style":117},[9616],{"type":30,"value":5068},{"type":20,"tag":90,"props":9618,"children":9619},{"style":123},[9620],{"type":30,"value":5454},{"type":20,"tag":90,"props":9622,"children":9623},{"style":129},[9624],{"type":30,"value":6013},{"type":20,"tag":90,"props":9626,"children":9627},{"style":117},[9628],{"type":30,"value":2151},{"type":20,"tag":90,"props":9630,"children":9631},{"class":92,"line":6053},[9632],{"type":20,"tag":90,"props":9633,"children":9634},{"style":117},[9635],{"type":30,"value":4837},{"type":20,"tag":90,"props":9637,"children":9638},{"class":92,"line":6062},[9639],{"type":20,"tag":90,"props":9640,"children":9641},{"emptyLinePlaceholder":107},[9642],{"type":30,"value":110},{"type":20,"tag":90,"props":9644,"children":9645},{"class":92,"line":6071},[9646],{"type":20,"tag":90,"props":9647,"children":9648},{"style":97},[9649],{"type":30,"value":4729},{"type":20,"tag":90,"props":9651,"children":9652},{"class":92,"line":6080},[9653],{"type":20,"tag":90,"props":9654,"children":9655},{"style":97},[9656],{"type":30,"value":6050},{"type":20,"tag":90,"props":9658,"children":9659},{"class":92,"line":6122},[9660],{"type":20,"tag":90,"props":9661,"children":9662},{"style":97},[9663],{"type":30,"value":6059},{"type":20,"tag":90,"props":9665,"children":9666},{"class":92,"line":6183},[9667],{"type":20,"tag":90,"props":9668,"children":9669},{"style":97},[9670],{"type":30,"value":6068},{"type":20,"tag":90,"props":9672,"children":9673},{"class":92,"line":6191},[9674],{"type":20,"tag":90,"props":9675,"children":9676},{"style":97},[9677],{"type":30,"value":6077},{"type":20,"tag":90,"props":9679,"children":9680},{"class":92,"line":6238},[9681,9685,9689,9693,9697,9701,9705,9709,9713],{"type":20,"tag":90,"props":9682,"children":9683},{"style":117},[9684],{"type":30,"value":6086},{"type":20,"tag":90,"props":9686,"children":9687},{"style":146},[9688],{"type":30,"value":4692},{"type":20,"tag":90,"props":9690,"children":9691},{"style":117},[9692],{"type":30,"value":615},{"type":20,"tag":90,"props":9694,"children":9695},{"style":135},[9696],{"type":30,"value":5692},{"type":20,"tag":90,"props":9698,"children":9699},{"style":123},[9700],{"type":30,"value":1113},{"type":20,"tag":90,"props":9702,"children":9703},{"style":123},[9704],{"type":30,"value":4625},{"type":20,"tag":90,"props":9706,"children":9707},{"style":117},[9708],{"type":30,"value":4557},{"type":20,"tag":90,"props":9710,"children":9711},{"style":4569},[9712],{"type":30,"value":6115},{"type":20,"tag":90,"props":9714,"children":9715},{"style":117},[9716],{"type":30,"value":4603},{"type":20,"tag":90,"props":9718,"children":9719},{"class":92,"line":6271},[9720,9724,9728,9732,9736,9740,9744,9748,9752,9756,9760,9764,9768],{"type":20,"tag":90,"props":9721,"children":9722},{"style":123},[9723],{"type":30,"value":4922},{"type":20,"tag":90,"props":9725,"children":9726},{"style":117},[9727],{"type":30,"value":6132},{"type":20,"tag":90,"props":9729,"children":9730},{"style":123},[9731],{"type":30,"value":126},{"type":20,"tag":90,"props":9733,"children":9734},{"style":146},[9735],{"type":30,"value":6141},{"type":20,"tag":90,"props":9737,"children":9738},{"style":117},[9739],{"type":30,"value":615},{"type":20,"tag":90,"props":9741,"children":9742},{"style":146},[9743],{"type":30,"value":4692},{"type":20,"tag":90,"props":9745,"children":9746},{"style":117},[9747],{"type":30,"value":6154},{"type":20,"tag":90,"props":9749,"children":9750},{"style":135},[9751],{"type":30,"value":4815},{"type":20,"tag":90,"props":9753,"children":9754},{"style":117},[9755],{"type":30,"value":4557},{"type":20,"tag":90,"props":9757,"children":9758},{"style":146},[9759],{"type":30,"value":6167},{"type":20,"tag":90,"props":9761,"children":9762},{"style":117},[9763],{"type":30,"value":1260},{"type":20,"tag":90,"props":9765,"children":9766},{"style":146},[9767],{"type":30,"value":6176},{"type":20,"tag":90,"props":9769,"children":9770},{"style":117},[9771],{"type":30,"value":4662},{"type":20,"tag":90,"props":9773,"children":9774},{"class":92,"line":6279},[9775],{"type":20,"tag":90,"props":9776,"children":9777},{"emptyLinePlaceholder":107},[9778],{"type":30,"value":110},{"type":20,"tag":90,"props":9780,"children":9781},{"class":92,"line":6314},[9782,9786,9790,9794,9798,9802,9806,9810,9814],{"type":20,"tag":90,"props":9783,"children":9784},{"style":117},[9785],{"type":30,"value":6197},{"type":20,"tag":90,"props":9787,"children":9788},{"style":135},[9789],{"type":30,"value":6202},{"type":20,"tag":90,"props":9791,"children":9792},{"style":117},[9793],{"type":30,"value":4557},{"type":20,"tag":90,"props":9795,"children":9796},{"style":146},[9797],{"type":30,"value":4824},{"type":20,"tag":90,"props":9799,"children":9800},{"style":117},[9801],{"type":30,"value":6215},{"type":20,"tag":90,"props":9803,"children":9804},{"style":129},[9805],{"type":30,"value":6220},{"type":20,"tag":90,"props":9807,"children":9808},{"style":117},[9809],{"type":30,"value":6225},{"type":20,"tag":90,"props":9811,"children":9812},{"style":135},[9813],{"type":30,"value":6230},{"type":20,"tag":90,"props":9815,"children":9816},{"style":117},[9817],{"type":30,"value":6235},{"type":20,"tag":90,"props":9819,"children":9821},{"class":92,"line":9820},89,[9822,9826,9830,9834,9838,9842,9846],{"type":20,"tag":90,"props":9823,"children":9824},{"style":117},[9825],{"type":30,"value":6197},{"type":20,"tag":90,"props":9827,"children":9828},{"style":135},[9829],{"type":30,"value":6202},{"type":20,"tag":90,"props":9831,"children":9832},{"style":117},[9833],{"type":30,"value":4557},{"type":20,"tag":90,"props":9835,"children":9836},{"style":146},[9837],{"type":30,"value":4824},{"type":20,"tag":90,"props":9839,"children":9840},{"style":117},[9841],{"type":30,"value":6260},{"type":20,"tag":90,"props":9843,"children":9844},{"style":135},[9845],{"type":30,"value":6230},{"type":20,"tag":90,"props":9847,"children":9848},{"style":117},[9849],{"type":30,"value":6235},{"type":20,"tag":90,"props":9851,"children":9853},{"class":92,"line":9852},90,[9854],{"type":20,"tag":90,"props":9855,"children":9856},{"style":117},[9857],{"type":30,"value":4837},{"type":20,"tag":90,"props":9859,"children":9861},{"class":92,"line":9860},91,[9862,9866,9870,9874,9878,9882,9886],{"type":20,"tag":90,"props":9863,"children":9864},{"style":117},[9865],{"type":30,"value":6285},{"type":20,"tag":90,"props":9867,"children":9868},{"style":146},[9869],{"type":30,"value":4692},{"type":20,"tag":90,"props":9871,"children":9872},{"style":117},[9873],{"type":30,"value":6294},{"type":20,"tag":90,"props":9875,"children":9876},{"style":123},[9877],{"type":30,"value":126},{"type":20,"tag":90,"props":9879,"children":9880},{"style":117},[9881],{"type":30,"value":4687},{"type":20,"tag":90,"props":9883,"children":9884},{"style":146},[9885],{"type":30,"value":4692},{"type":20,"tag":90,"props":9887,"children":9888},{"style":117},[9889],{"type":30,"value":6311},{"type":20,"tag":90,"props":9891,"children":9893},{"class":92,"line":9892},92,[9894],{"type":20,"tag":90,"props":9895,"children":9896},{"emptyLinePlaceholder":107},[9897],{"type":30,"value":110},{"type":20,"tag":90,"props":9899,"children":9901},{"class":92,"line":9900},93,[9902],{"type":20,"tag":90,"props":9903,"children":9904},{"style":97},[9905],{"type":30,"value":4729},{"type":20,"tag":90,"props":9907,"children":9909},{"class":92,"line":9908},94,[9910],{"type":20,"tag":90,"props":9911,"children":9912},{"style":97},[9913],{"type":30,"value":9914},"     * Create a socket io instance that will echo all events into the application event aggregator, so that\n",{"type":20,"tag":90,"props":9916,"children":9918},{"class":92,"line":9917},95,[9919],{"type":20,"tag":90,"props":9920,"children":9921},{"style":97},[9922],{"type":30,"value":9923},"     * collections, models, etc. can listen on app.vent for their events.\n",{"type":20,"tag":90,"props":9925,"children":9927},{"class":92,"line":9926},96,[9928,9932,9936,9940],{"type":20,"tag":90,"props":9929,"children":9930},{"style":97},[9931],{"type":30,"value":5841},{"type":20,"tag":90,"props":9933,"children":9934},{"style":123},[9935],{"type":30,"value":5846},{"type":20,"tag":90,"props":9937,"children":9938},{"style":135},[9939],{"type":30,"value":5851},{"type":20,"tag":90,"props":9941,"children":9942},{"style":117},[9943],{"type":30,"value":5856},{"type":20,"tag":90,"props":9945,"children":9947},{"class":92,"line":9946},97,[9948,9952],{"type":20,"tag":90,"props":9949,"children":9950},{"style":97},[9951],{"type":30,"value":5841},{"type":20,"tag":90,"props":9953,"children":9954},{"style":123},[9955],{"type":30,"value":9956},"@constructor\n",{"type":20,"tag":90,"props":9958,"children":9960},{"class":92,"line":9959},98,[9961],{"type":20,"tag":90,"props":9962,"children":9963},{"style":97},[9964],{"type":30,"value":4745},{"type":20,"tag":90,"props":9966,"children":9968},{"class":92,"line":9967},99,[9969,9974,9978,9982,9987,9991,9995,9999,10003],{"type":20,"tag":90,"props":9970,"children":9971},{"style":117},[9972],{"type":30,"value":9973},"    Marionette.Application.",{"type":20,"tag":90,"props":9975,"children":9976},{"style":146},[9977],{"type":30,"value":4692},{"type":20,"tag":90,"props":9979,"children":9980},{"style":117},[9981],{"type":30,"value":615},{"type":20,"tag":90,"props":9983,"children":9984},{"style":135},[9985],{"type":30,"value":9986},"SocketIO",{"type":20,"tag":90,"props":9988,"children":9989},{"style":123},[9990],{"type":30,"value":1113},{"type":20,"tag":90,"props":9992,"children":9993},{"style":123},[9994],{"type":30,"value":4625},{"type":20,"tag":90,"props":9996,"children":9997},{"style":117},[9998],{"type":30,"value":4557},{"type":20,"tag":90,"props":10000,"children":10001},{"style":4569},[10002],{"type":30,"value":5903},{"type":20,"tag":90,"props":10004,"children":10005},{"style":117},[10006],{"type":30,"value":4603},{"type":20,"tag":90,"props":10008,"children":10010},{"class":92,"line":10009},100,[10011,10015,10020,10024,10029,10034],{"type":20,"tag":90,"props":10012,"children":10013},{"style":123},[10014],{"type":30,"value":4922},{"type":20,"tag":90,"props":10016,"children":10017},{"style":117},[10018],{"type":30,"value":10019}," socket ",{"type":20,"tag":90,"props":10021,"children":10022},{"style":123},[10023],{"type":30,"value":126},{"type":20,"tag":90,"props":10025,"children":10026},{"style":117},[10027],{"type":30,"value":10028}," io.",{"type":20,"tag":90,"props":10030,"children":10031},{"style":135},[10032],{"type":30,"value":10033},"connect",{"type":20,"tag":90,"props":10035,"children":10036},{"style":117},[10037],{"type":30,"value":10038},"(url, {\n",{"type":20,"tag":90,"props":10040,"children":10042},{"class":92,"line":10041},101,[10043,10048,10053],{"type":20,"tag":90,"props":10044,"children":10045},{"style":117},[10046],{"type":30,"value":10047},"            transports:[",{"type":20,"tag":90,"props":10049,"children":10050},{"style":129},[10051],{"type":30,"value":10052},"'websocket'",{"type":20,"tag":90,"props":10054,"children":10055},{"style":117},[10056],{"type":30,"value":1587},{"type":20,"tag":90,"props":10058,"children":10060},{"class":92,"line":10059},102,[10061],{"type":20,"tag":90,"props":10062,"children":10063},{"style":117},[10064],{"type":30,"value":5662},{"type":20,"tag":90,"props":10066,"children":10068},{"class":92,"line":10067},103,[10069],{"type":20,"tag":90,"props":10070,"children":10071},{"emptyLinePlaceholder":107},[10072],{"type":30,"value":110},{"type":20,"tag":90,"props":10074,"children":10076},{"class":92,"line":10075},104,[10077],{"type":20,"tag":90,"props":10078,"children":10079},{"style":97},[10080],{"type":30,"value":10081},"        /**\n",{"type":20,"tag":90,"props":10083,"children":10085},{"class":92,"line":10084},105,[10086],{"type":20,"tag":90,"props":10087,"children":10088},{"style":97},[10089],{"type":30,"value":10090},"         * On any event from the server, trigger it on the app event aggregator. The first\n",{"type":20,"tag":90,"props":10092,"children":10094},{"class":92,"line":10093},106,[10095],{"type":20,"tag":90,"props":10096,"children":10097},{"style":97},[10098],{"type":30,"value":10099},"         * argument will always be the name of the event.\n",{"type":20,"tag":90,"props":10101,"children":10103},{"class":92,"line":10102},107,[10104],{"type":20,"tag":90,"props":10105,"children":10106},{"style":97},[10107],{"type":30,"value":10108},"         */\n",{"type":20,"tag":90,"props":10110,"children":10112},{"class":92,"line":10111},108,[10113,10117,10122,10126,10130,10134,10138],{"type":20,"tag":90,"props":10114,"children":10115},{"style":117},[10116],{"type":30,"value":5439},{"type":20,"tag":90,"props":10118,"children":10119},{"style":135},[10120],{"type":30,"value":10121},"on",{"type":20,"tag":90,"props":10123,"children":10124},{"style":117},[10125],{"type":30,"value":4557},{"type":20,"tag":90,"props":10127,"children":10128},{"style":129},[10129],{"type":30,"value":6220},{"type":20,"tag":90,"props":10131,"children":10132},{"style":117},[10133],{"type":30,"value":1260},{"type":20,"tag":90,"props":10135,"children":10136},{"style":123},[10137],{"type":30,"value":4562},{"type":20,"tag":90,"props":10139,"children":10140},{"style":117},[10141],{"type":30,"value":4630},{"type":20,"tag":90,"props":10143,"children":10145},{"class":92,"line":10144},109,[10146,10150,10154,10158,10162,10166,10170,10174,10178,10182,10186,10190,10195],{"type":20,"tag":90,"props":10147,"children":10148},{"style":123},[10149],{"type":30,"value":5484},{"type":20,"tag":90,"props":10151,"children":10152},{"style":117},[10153],{"type":30,"value":6132},{"type":20,"tag":90,"props":10155,"children":10156},{"style":123},[10157],{"type":30,"value":126},{"type":20,"tag":90,"props":10159,"children":10160},{"style":146},[10161],{"type":30,"value":6141},{"type":20,"tag":90,"props":10163,"children":10164},{"style":117},[10165],{"type":30,"value":615},{"type":20,"tag":90,"props":10167,"children":10168},{"style":146},[10169],{"type":30,"value":4692},{"type":20,"tag":90,"props":10171,"children":10172},{"style":117},[10173],{"type":30,"value":6154},{"type":20,"tag":90,"props":10175,"children":10176},{"style":135},[10177],{"type":30,"value":4815},{"type":20,"tag":90,"props":10179,"children":10180},{"style":117},[10181],{"type":30,"value":4557},{"type":20,"tag":90,"props":10183,"children":10184},{"style":146},[10185],{"type":30,"value":6167},{"type":20,"tag":90,"props":10187,"children":10188},{"style":117},[10189],{"type":30,"value":1260},{"type":20,"tag":90,"props":10191,"children":10192},{"style":146},[10193],{"type":30,"value":10194},"0",{"type":20,"tag":90,"props":10196,"children":10197},{"style":117},[10198],{"type":30,"value":4662},{"type":20,"tag":90,"props":10200,"children":10202},{"class":92,"line":10201},110,[10203,10207,10211,10216,10220,10225,10230,10234,10238],{"type":20,"tag":90,"props":10204,"children":10205},{"style":117},[10206],{"type":30,"value":9179},{"type":20,"tag":90,"props":10208,"children":10209},{"style":135},[10210],{"type":30,"value":5736},{"type":20,"tag":90,"props":10212,"children":10213},{"style":117},[10214],{"type":30,"value":10215},"(args[",{"type":20,"tag":90,"props":10217,"children":10218},{"style":146},[10219],{"type":30,"value":10194},{"type":20,"tag":90,"props":10221,"children":10222},{"style":117},[10223],{"type":30,"value":10224},"], args.",{"type":20,"tag":90,"props":10226,"children":10227},{"style":135},[10228],{"type":30,"value":10229},"slice",{"type":20,"tag":90,"props":10231,"children":10232},{"style":117},[10233],{"type":30,"value":4557},{"type":20,"tag":90,"props":10235,"children":10236},{"style":146},[10237],{"type":30,"value":6176},{"type":20,"tag":90,"props":10239,"children":10240},{"style":117},[10241],{"type":30,"value":10242},"));\n",{"type":20,"tag":90,"props":10244,"children":10246},{"class":92,"line":10245},111,[10247],{"type":20,"tag":90,"props":10248,"children":10249},{"style":117},[10250],{"type":30,"value":5662},{"type":20,"tag":90,"props":10252,"children":10254},{"class":92,"line":10253},112,[10255],{"type":20,"tag":90,"props":10256,"children":10257},{"emptyLinePlaceholder":107},[10258],{"type":30,"value":110},{"type":20,"tag":90,"props":10260,"children":10262},{"class":92,"line":10261},113,[10263],{"type":20,"tag":90,"props":10264,"children":10265},{"style":97},[10266],{"type":30,"value":10081},{"type":20,"tag":90,"props":10268,"children":10270},{"class":92,"line":10269},114,[10271],{"type":20,"tag":90,"props":10272,"children":10273},{"style":97},[10274],{"type":30,"value":10275},"         * On error, trigger the socket:error event on the global event aggregator for \n",{"type":20,"tag":90,"props":10277,"children":10279},{"class":92,"line":10278},115,[10280],{"type":20,"tag":90,"props":10281,"children":10282},{"style":97},[10283],{"type":30,"value":10284},"         * interested listeners.\n",{"type":20,"tag":90,"props":10286,"children":10288},{"class":92,"line":10287},116,[10289],{"type":20,"tag":90,"props":10290,"children":10291},{"style":97},[10292],{"type":30,"value":10108},{"type":20,"tag":90,"props":10294,"children":10296},{"class":92,"line":10295},117,[10297,10301,10305,10309,10314,10318,10322,10326,10331],{"type":20,"tag":90,"props":10298,"children":10299},{"style":117},[10300],{"type":30,"value":5439},{"type":20,"tag":90,"props":10302,"children":10303},{"style":135},[10304],{"type":30,"value":10121},{"type":20,"tag":90,"props":10306,"children":10307},{"style":117},[10308],{"type":30,"value":4557},{"type":20,"tag":90,"props":10310,"children":10311},{"style":129},[10312],{"type":30,"value":10313},"'error'",{"type":20,"tag":90,"props":10315,"children":10316},{"style":117},[10317],{"type":30,"value":1260},{"type":20,"tag":90,"props":10319,"children":10320},{"style":123},[10321],{"type":30,"value":4562},{"type":20,"tag":90,"props":10323,"children":10324},{"style":117},[10325],{"type":30,"value":4557},{"type":20,"tag":90,"props":10327,"children":10328},{"style":4569},[10329],{"type":30,"value":10330},"err",{"type":20,"tag":90,"props":10332,"children":10333},{"style":117},[10334],{"type":30,"value":4603},{"type":20,"tag":90,"props":10336,"children":10338},{"class":92,"line":10337},118,[10339,10343,10347,10351,10356],{"type":20,"tag":90,"props":10340,"children":10341},{"style":117},[10342],{"type":30,"value":9179},{"type":20,"tag":90,"props":10344,"children":10345},{"style":135},[10346],{"type":30,"value":5736},{"type":20,"tag":90,"props":10348,"children":10349},{"style":117},[10350],{"type":30,"value":4557},{"type":20,"tag":90,"props":10352,"children":10353},{"style":129},[10354],{"type":30,"value":10355},"'socket:error'",{"type":20,"tag":90,"props":10357,"children":10358},{"style":117},[10359],{"type":30,"value":10360},", err);\n",{"type":20,"tag":90,"props":10362,"children":10364},{"class":92,"line":10363},119,[10365],{"type":20,"tag":90,"props":10366,"children":10367},{"style":117},[10368],{"type":30,"value":5662},{"type":20,"tag":90,"props":10370,"children":10372},{"class":92,"line":10371},120,[10373],{"type":20,"tag":90,"props":10374,"children":10375},{"emptyLinePlaceholder":107},[10376],{"type":30,"value":110},{"type":20,"tag":90,"props":10378,"children":10380},{"class":92,"line":10379},121,[10381,10385],{"type":20,"tag":90,"props":10382,"children":10383},{"style":123},[10384],{"type":30,"value":4805},{"type":20,"tag":90,"props":10386,"children":10387},{"style":117},[10388],{"type":30,"value":10389}," socket;\n",{"type":20,"tag":90,"props":10391,"children":10393},{"class":92,"line":10392},122,[10394],{"type":20,"tag":90,"props":10395,"children":10396},{"style":117},[10397],{"type":30,"value":7435},{"type":20,"tag":90,"props":10399,"children":10401},{"class":92,"line":10400},123,[10402,10407,10412],{"type":20,"tag":90,"props":10403,"children":10404},{"style":117},[10405],{"type":30,"value":10406},"})(app ",{"type":20,"tag":90,"props":10408,"children":10409},{"style":97},[10410],{"type":30,"value":10411},"/* replace with your global app object */",{"type":20,"tag":90,"props":10413,"children":10414},{"style":117},[10415],{"type":30,"value":10416},", Backbone, Backbone.Marionette, jQuery, _, io);\n",{"type":20,"tag":21,"props":10418,"children":10419},{},[10420],{"type":30,"value":10421},"As always, comments are appreciated.",{"type":20,"tag":2722,"props":10423,"children":10424},{},[10425],{"type":30,"value":2726},{"title":8,"searchDepth":113,"depth":113,"links":10427},[],"content:ckeefer:2014-6:backbonesocketsync.md","ckeefer/2014-6/backbonesocketsync.md","ckeefer/2014-6/backbonesocketsync",{"user":2743,"name":2744},1780330271106]