Files
PyRIGS/RIGS/static/js/asteroids.min.js
Arona Jones 3414204209 Refactor buildsystem to NPM/Gulp, port to BS4 & rewrite RIGS tests accordingly... (#412)
* Start to seperate versioning into its own app

* Start reworking invoice things

* Reduced overall font size a touch

* Improvements to generic lists

* Tweak some colours to be a bit less OTT

I need to work out if I can seperate background and primary colours like BS3 did

* Improvements to event table mobile

* First pass at mobile-ising the generic list

* Item table fixes

* Fixed fullcalendar print css not included

* Asset list table improvements

* Tweak asset list to be more in line with other lists

* Versioning template improvements

//TODO Rather than have seperate asset templates, convert 'id' into a template variable

* Tweak versioning templates to allow ID overrides

Asset specific templates begone. Still need to bring back the ID formatting for the Rigboard.

* Asset form fixes

* Use the right autocompleter.js...

* Breakout (most) user stuff to separate module

The model remains in RIGS for now, as it's pretty painful to move...

* Python Format/import opt

* Test Refactor Part 1 - Shuffle things around

* Fix migrations

TODO - need to ensure moved models are *moved* rather than deleted and recreated!

* Start on new tests

* Initial work on event create test reimpl

* Init other tests, more rigs test faffery

* Desaturate theme colors even more

Much closer to BS3

* Fix event item adding

Bit too heavy handed with the deduplication there Arona

* Initial refactor of event item testing

* Upgrade bootstrap-select

* Updated bootstrap-select for BS4

* Initial port of duplicate testing

Needs the latter half rewriting once we have an EventDetail POM

* Refactor date validation test

So close to killing test_functional.EventTest!

* Deduplication of testing code

* pep8

* Fix some tests

And some things that were actually borked

* FIX: Prevent setting access time after start time 

Cherry pick of d274ea4606. Will close #405.

* Refactor calendar tests

* FIX: Don't show asset buttons/history for basic users

* Really ought to get a pre-commit hook for pep8...

* Fully replace test_functional

* Dedupe generic search logic

* Fix the remaining tests

* Ensure submit button is scrolled to in tests

* Fix asset creation test + actually verify its results

* Make CI use latest (stable) chromedriver rather than some ancient one

Since Travis uses the latest stable chrome, should always match. Bash oneliner \o/

* Of course | is part of YAML syntax, of course...

Maybe this works.

* Update python version

Trying to get CI to match my local environment as much as possible...

* Minor test futzing

* Well that wasn't clever of me

* That was even less clever of me

* Revert to old submit wait behaviour

* What about if I did this

* Try disabling chrome cache

* Added screenshot recording of test failures

* Fixed RIGS tests not being run

* Fixed Pep8 - I promise I'll make a pre-commit hook sometime!

* Very initial work at togglable darktheme.

Dammit @alexdaniel654 just when I had my scope creep kinda under control. It'll be v. nice to have though...!

* More dark theme wangling

* Fix some asset template things

* FIX: CI Locale Issues

* Fix sample command

* Initial work at integrating the risk assessment

#136. No clever database structure as yet...

* FIX: Don't set every boolean input to radios

* Different approach to RA linking

* Move text definitions to somewhere more authoratitive

* FIX: Undo breakage causing autopep8

o.O

* Expand detail template

* Use correct view for RA history

* Initial work at coercing activity feed into showing RAs

Also shows Asset/Supplier on the homepage feed.

* Refactor activity feed template logic

Yay for removing arbitrary if/else chains!

* Initial work on caching activity feed

Server side that is. Ref #162.

* Start RA list template

* Refactor RA creation stuff, again

* Add H&S Details to Event Detail View

* Display venue notes in event detail

Notes are no use if nobody reads them. Not sure on this one.

* Add ability to filter event archive by status

Closes #168.

* Fix lingering naive time

* Use locmem cache in sqlite environments

Otherwise the tests just lock up totally. Should close #162

* Update dependencies

Mirrors/supersedes 0e67da82e2

* Add global ctrl/meta-enter shortcut for form submission

Wants rewriting for better efficiency, but hey, it works!

* Update dependencies

* Fix for a situation that should be impossible

* Fix navbar alignment

* FEAT: Improve 'omni'search

- Partialised template
- Added to assets header
- Added ability to search assets/suppliers
- Improved selection logic
- Have it display current query

* Move closemodal into PyRIGS

* Fix tests for search improvements

* Dark mode colour improvements

* Fix table colors for dry hires

* further darktheme fixes

* Remove the dark header from light theme

* Fix reload loops when CSS/JS is changed

* Move dark theme SCSS to separate file, fix inactive pagination styling

* Genercise detail pages

* Testing something re notes

I wonder if I can make that global, rather than per-template...

* Dark theme palette shenanigans

I just can't decide

* Match darktheme palette to forum darktheme palette

Why reinvent the wheel.

* Make supplier detail use the generic template

* Disable mobile event table PoC for now

* Remove the defaults from the RA fields + make them required

* More RA fixes

* Fixes to revisions for RAs

* Add bootstrap 4 test page

* Bunch of dark mode fixes from test page

* Do not use Django 'required' for radio selects

As this requires them to be True, whereas we just need to require that an option be entered.

* Properly fixed popover darktheme

* Fixed search for events

* Style fixes to asset list

* Start RA 'mark review' feature

* Add reviewing to revision history, fix RA editing not working

Also actually commit all the files, that helps

* Fix Power MIC being lost on RA edit

Why it is subtly different to the Event Update behaviour? Who knows

* Invalidate RA review if it is edited after review

* Start work on event checklist

* Add a button for creating and instantly voiding invoices

Handy dandy for when you have loads of cancelled events, like say, a pandemic

* Mooooore status chips, mooore

* Initial shenanigans on storing my overly fancy EC form

* Proof of concept for JSON parsing/storage

\o/

* Add new line functionality for vehicles/drivers

Might it have been easier to create 'dummy' models like with EventItems? Probably...

* Alter rig_count to not include un-checked-in dry hires

* Insert a divider between still-out dry hires and actually upcoming events on rigboard

* Initial work on new checklist handling. No more JSON!

* Versioning module now does magic

Automatic creation of views/urls for anything registered with reversion, with a small amount of hackage to preserve legacy stuff. (and the DAMNED asset IDs!) I would never get distracted...

* Cleanup

* Event checklist crew works

Mostly - its not happy with timezones

* Medium event power stuff done, barring worst case stuff

* Misc fixes

* Validation of power reqs

* Worst case points on checklist

* Templating improvements to RA/EC stuff

* Do event table color logic at python level

* Audit template fixes

* Restrict versioning to one level of depth for speed

Also fixed the template for nested changes

* Event properties internal/authorised always return a explicit boolean rather than sometimes None

* Use template filter for notes

* Fix list templates

TODO: Sensible place to define the 'expected answer' stuff.

* Fix cable table template

* Rethink rigboard color logic again

Also revert some broken stuff

* Test fixes

* Modify auth test so it doesn't try and test for external authorisations

Cause that's not a thing

* Why does this work

Bloody overzealous autoformatter...

* Formatting...

* Initial work on RA tests

* Pages/start of tests for EventChecklists

* Much better coverage of H&S things

* Cleanup & Squash migrations

* Fix wrong variable name in settings.py

* Fix broken invoice list template

* Add revision history to invoices/payments.

Also patches previously introduced reversion permissions hole.

Supersedes and closes #337.

* Various misc fixes

* Fix for my fix

* Curse youuuuu pep8

* Invoice template improvements

* Minor fixes

* More tweaks

* More fixes

* Major improvements/fixes to authorisation templates

* Add ability to mark event checklists as Large Event

This just disables the checks to allow the rest of it to be filled out for large events, though I expect paper forms may still be used...

* Remove database ID from generic list

* Put power threshold values in a collapse

* Use template filter for consistent removal of 'None links'

Plus cleaner template markup! More HTML-in-Python tho, which always feels a bit CSS-in-JS

* Tweak asset list markup

* Begin to change add buttons success -> primary

Also change search primary -> info to avoid clash

* Begin to improve event checklist on mobile

* Asset detail template improvements

* Fix #326 (again)

* Fix errors being squashed

* Fix rigboard validation tests

* Initial work on BS4 button templatetag

Newfeatureitis strikes again

* Allow multiple event checklists per event

TODO: Status chip now needs rethinking

* Minor event detail fixes

* Fix tests

* Rework button tag

* Mobile fixes for search

* Fix event checklist on mobile

* Redo light theme palette

* Switch rigboard new button to primary

* Kill off excess whitespace on rigboard

* Rigboard Timing display tweaks

* Fix tests

* Properly handle eventauthorisations in new versioning

It's not great, not terrible...

* Prevent creating duplicate revisions on event

Potential fix for #322 - I couldn't reproduce even before this change...

* Template improvements

* Minor test fixes

* Revert "Prevent creating duplicate revisions on event"

Apparently it was too strong at preventing dupes...

This reverts commit cce0ad0f9f.

# Conflicts:
#	RIGS/models.py

* Better approach to generic list templates + other deduplication

* Also apply better approach to generic detail pages

* One of these days I'll remember to test BEFORE pushing...

* And now the same for generic forms

* Display tick/cross rather than true/false in boolean version diffs

* Upgrade dependencies

* Fixes fixes fixes

* Fix dependency hell

Probably

* Correct handling of spaces in paperwork filenames

Also normalises display of Invoice IDs. Partial fix for #391.

* Buggerit millennium hand and shrimp

Knew I was gonna forget to fix the tests

* FIX: Set duplicated event status to provisional

Closes #398.

Flip flop. Flip flop.

* Update polyfill for datetime-local

Bloody Firefox. We love to hate you. Proper CSS of the fill to come, SoonTM.

Closes #391

* Curses!

* Minor typo fixes

* Initial pass at soop-consult confirmation screen for RAs

* Fix migration

* Make venue/date editable on EC

For multi venue, multi day events

Defaults to date and venue set on the event. Also made power MIC default to that set in RA

* Clearer logic for RA inverted fields

* (probably) fix tests

* Give keyholders supplier edit perm

* Generic list only displays edit button if user has perm

* Same perm check for generic details

* H&S Details takes up free space on non-internal events

* Remove flash of content when loading new rig page

* First pass at clearer display of asset list filters

* Fix tests / default to headless tests

(fingers crossed)

* Fix autocompleter.js to properly disable edit links again

* Move status color logic back to template

Cause that somehow makes it work better??

* Display note icon on event detail page

* Fix caching

* Put rounded corners back where they belong

* Remove lingering use of 'page-header'

BS removed that style

* More search and replace for BS changes

Thought I'd got them all. Clearly not!

* Remove enforced linebreak on status chips

* Fix horizontal-ness on some forms

* Remove animation on prefers-reduced-motion/low referesh rate devices

Also normalises handling of asset list cable table & improves its use of space on large devices

* Make version changes badges more readable

* First pass at making the calendar less crap

* Fix event table success logic

Yay for copy paste fails >.>

* Use borders rather than block colors for coloured tables under darktheme

* First pass at porting calendar from FC V3 to V5

Two major versions and all they did was rename a bunch of names...TWICE.

* Rework version name method to avoid blank names on eventchecklist vehicles/crew

* Fix cable test

* Made radio button focus much more obvious on dark theme

* Implement Jerb's wording changes

* Fix one test, break another...

* Fix recent change stream list mutation issue

* FIX: Do not naively cache event table

Not that easy, it turns out. Duh.

* FEAT: Implement #413 show associated assets on cable type detail pg

Closes #413

* Allow H&S for non-events

* Update emergency contact number

* Improvements to profile detail page

* Implement some of Jonny's suggested changes

TODO:
- Define event size at RA time, pass through to EC
- Have later power questions be context dependent

* Test fixes

* Add space for power/rigging plans to be linked to RAs

* Start move of event size logic to RA from Ec

* Javascript required shenanigans for RA power

* More moving of event size logic

* Fixing tests for new logic etc

* Why does this work

Indeed, it may not

* FIX: Stupid typo in versioning.py

* Further minor fixes to versioning

* Add icons to H&S menu items

* Should fix calendar breaking in production

* Small alignment fix in asset list

* Squash migrations

Co-authored-by: Matthew Smith <psyms13@nottingham.ac.uk>
2021-01-23 22:22:37 +00:00

1 line
18 KiB
JavaScript

!function(){function Asteroids(){function Vector(e,t){"Object"==typeof e?(this.x=e.x,this.y=e.y):(this.x=e,this.y=t)}function Line(e,t){this.p1=e,this.p2=t}window.ASTEROIDS||(window.ASTEROIDS={enemiesKilled:0}),Vector.prototype={cp:function(){return new Vector(this.x,this.y)},mul:function(e){return this.x*=e,this.y*=e,this},mulNew:function(e){return new Vector(this.x*e,this.y*e)},add:function(e){return this.x+=e.x,this.y+=e.y,this},addNew:function(e){return new Vector(this.x+e.x,this.y+e.y)},sub:function(e){return this.x-=e.x,this.y-=e.y,this},subNew:function(e){return new Vector(this.x-e.x,this.y-e.y)},rotate:function(e){var t=this.x,i=this.y;return this.x=t*Math.cos(e)-Math.sin(e)*i,this.y=t*Math.sin(e)+Math.cos(e)*i,this},rotateNew:function(e){return this.cp().rotate(e)},setAngle:function(e){var t=this.len();return this.x=Math.cos(e)*t,this.y=Math.sin(e)*t,this},setAngleNew:function(e){return this.cp().setAngle(e)},setLength:function(e){var t=this.len();return t?this.mul(e/t):this.x=this.y=e,this},setLengthNew:function(e){return this.cp().setLength(e)},normalize:function(){var e=this.len();return this.x/=e,this.y/=e,this},normalizeNew:function(){return this.cp().normalize()},angle:function(){return Math.atan2(this.y,this.x)},collidesWith:function(e){return this.x>e.x&&this.y>e.y&&this.x<e.x+e.width&&this.y<e.y+e.height},len:function(){var e=Math.sqrt(this.x*this.x+this.y*this.y);return e<.005&&e>-.005?0:e},is:function(e){return"object"==typeof e&&this.x==e.x&&this.y==e.y},toString:function(){return"[Vector("+this.x+", "+this.y+") angle: "+this.angle()+", length: "+this.len()+"]"}},Line.prototype={shift:function(e){this.p1.add(e),this.p2.add(e)},intersectsWithRect:function(e){var t=new Vector(e.x,e.y+e.height),i=new Vector(e.x,e.y),s=new Vector(e.x+e.width,e.y+e.height),n=new Vector(e.x+e.width,e.y);return this.p1.x>t.x&&this.p1.x<n.x&&this.p1.y<t.y&&this.p1.y>n.y&&this.p2.x>t.x&&this.p2.x<n.x&&this.p2.y<t.y&&this.p2.y>n.y||!!this.intersectsLine(new Line(i,t))||!!this.intersectsLine(new Line(t,s))||!!this.intersectsLine(new Line(i,n))||!!this.intersectsLine(new Line(n,s))},intersectsLine:function(e){var t=this.p1,i=this.p2,s=e.p1,n=e.p2,a=(n.y-s.y)*(i.x-t.x)-(n.x-s.x)*(i.y-t.y),o=(n.x-s.x)*(t.y-s.y)-(n.y-s.y)*(t.x-s.x),h=(i.x-t.x)*(t.y-s.y)-(i.y-t.y)*(t.x-s.x);if(0==a)return!1;var r=o/a,l=h/a;return r>=0&&r<=1&&l>=0&&l<=1}};var that=this,isIE=!!window.ActiveXObject,isIEQuirks=isIE&&"BackCompat"==document.compatMode,w=document.documentElement.clientWidth,h=document.documentElement.clientHeight;isIEQuirks&&(w=document.body.clientWidth,h=document.body.clientHeight);var playerWidth=20,playerHeight=30,playerVerts=[[-1*playerHeight/2,-1*playerWidth/2],[-1*playerHeight/2,playerWidth/2],[playerHeight/2,0]],ignoredTypes=["HTML","HEAD","BODY","SCRIPT","TITLE","META","STYLE","LINK"];window.ActiveXObject&&(ignoredTypes=["HTML","HEAD","BODY","SCRIPT","TITLE","META","STYLE","LINK","SHAPE","LINE","GROUP","IMAGE","STROKE","FILL","SKEW","PATH","TEXTPATH","INS"]);var hiddenTypes=["BR","HR"],FPS=50,acc=300,maxSpeed=600,rotSpeed=360,bulletSpeed=700,particleSpeed=400,timeBetweenFire=150,timeBetweenBlink=250,timeBetweenEnemyUpdate=isIE?1e4:2e3,bulletRadius=2,maxParticles=isIE?20:40,maxBullets=isIE?10:20,createFlames,rWidth,rIncrease,yWidth,yIncrease,halfR,halfY,halfPlayerHeight;function updateEnemyIndex(){for(var e,t=0;e=that.enemies[t];t++)removeClass(e,"ASTEROIDSYEAHENEMY");var i,s=document.body.getElementsByTagName("*");for(that.enemies=[],t=0;i=s[t];t++)-1==indexOf(ignoredTypes,i.tagName.toUpperCase())&&"g_vml_"!=i.prefix&&hasOnlyTextualChildren(i)&&"ASTEROIDSYEAH"!=i.className&&i.offsetHeight>0&&(i.aSize=size(i),that.enemies.push(i),addClass(i,"ASTEROIDSYEAHENEMY"),i.aAdded||(i.aAdded=!0,that.totalEnemies++))}function radians(e){return.0174532925*e}function degrees(e){return 57.2957795*e}function random(e,t){return Math.floor(Math.random()*(t+1)+e)}function code(e){var t={up:38,down:40,left:37,right:39,esc:27};return t[e]?t[e]:e.charCodeAt(0)}function boundsCheck(e){e.x>w?e.x=0:e.x<0&&(e.x=w),e.y>h?e.y=0:e.y<0&&(e.y=h)}function size(e){var t=e,i=0,s=0;do{i+=t.offsetLeft||0,s+=t.offsetTop||0,t=t.offsetParent}while(t);return{x:i,y:s,width:e.offsetWidth||10,height:e.offsetHeight||10}}function addEvent(e,t,i){e.addEventListener?e.addEventListener(t,i,!1):e.attachEvent&&(e["e"+t+i]=i,e[t+i]=function(){e["e"+t+i](window.event)},e.attachEvent("on"+t,e[t+i]))}function removeEvent(e,t,i){e.removeEventListener?e.removeEventListener(t,i,!1):e.detachEvent&&(e.detachEvent("on"+t,e[t+i]),e[t+i]=null,e["e"+t+i]=null)}function arrayRemove(e,t,i){var s=e.slice((i||t)+1||e.length);return e.length=t<0?e.length+t:t,e.push.apply(e,s)}function applyVisibility(e){for(var t,i=0;t=window.ASTEROIDSPLAYERS[i];i++)t.gameContainer.style.visibility=e}function getElementFromPoint(e,t){applyVisibility("hidden");var i=document.elementFromPoint(e,t);return i?(3==i.nodeType&&(i=i.parentNode),applyVisibility("visible"),i):(applyVisibility("visible"),!1)}function addParticles(e){for(var t=(new Date).getTime(),i=maxParticles,s=0;s<i;s++)that.particles.push({dir:new Vector(20*Math.random()-10,20*Math.random()-10).normalize(),pos:e.cp(),cameAlive:t})}function setScore(){that.points.innerHTML=10*window.ASTEROIDS.enemiesKilled}function hasOnlyTextualChildren(e){if(e.offsetLeft<-100&&e.offsetWidth>0&&e.offsetHeight>0)return!1;if(-1!=indexOf(hiddenTypes,e.tagName))return!0;if(0==e.offsetWidth&&0==e.offsetHeight)return!1;for(var t=0;t<e.childNodes.length;t++)if(-1==indexOf(hiddenTypes,e.childNodes[t].tagName)&&0!=e.childNodes[t].childNodes.length)return!1;return!0}function indexOf(e,t,i){if(e.indexOf)return e.indexOf(t,i);for(var s=e.length,n=i<0?Math.max(0,s+i):i||0;n<s;n++)if(e[n]===t)return n;return-1}function addClass(e,t){-1==e.className.indexOf(t)&&(e.className=(e.className+" "+t).replace(/\s+/g," ").replace(/^\s+|\s+$/g,""))}function removeClass(e,t){e.className=e.className.replace(new RegExp("(^|\\s)"+t+"(?:\\s|$)"),"$1")}function addStylesheet(e,t){var i=document.createElement("style");i.type="text/css",i.rel="stylesheet",i.id="ASTEROIDSYEAHSTYLES";try{i.innerHTML=e+"{"+t+"}"}catch(s){i.styleSheet.addRule(e,t)}document.getElementsByTagName("head")[0].appendChild(i)}function removeStylesheet(e){var t=document.getElementById(e);t&&t.parentNode.removeChild(t)}with(this.flame={r:[],y:[]},this.toggleBlinkStyle=function(){this.updated.blink.isActive?removeClass(document.body,"ASTEROIDSBLINK"):addClass(document.body,"ASTEROIDSBLINK"),this.updated.blink.isActive=!this.updated.blink.isActive},addStylesheet(".ASTEROIDSBLINK .ASTEROIDSYEAHENEMY","outline: 2px dotted red;"),this.pos=new Vector(100,100),this.lastPos=!1,this.vel=new Vector(0,0),this.dir=new Vector(0,1),this.keysPressed={},this.firedAt=!1,this.updated={enemies:!1,flame:(new Date).getTime(),blink:{time:0,isActive:!1}},this.scrollPos=new Vector(0,0),this.bullets=[],this.enemies=[],this.dying=[],this.totalEnemies=0,this.particles=[],updateEnemyIndex(),rWidth=playerWidth,rIncrease=.1*playerWidth,yWidth=.6*playerWidth,yIncrease=.2*yWidth,halfR=playerWidth/2,halfY=yWidth/2,halfPlayerHeight=playerHeight/2,createFlames=function(){that.flame.r=[[-1*halfPlayerHeight,-1*halfR]],that.flame.y=[[-1*halfPlayerHeight,-1*halfY]];for(var e=0;e<rWidth;e+=rIncrease)that.flame.r.push([-random(2,7)-halfPlayerHeight,e-halfR]);for(that.flame.r.push([-1*halfPlayerHeight,halfR]),e=0;e<yWidth;e+=yIncrease)that.flame.y.push([-random(2,7)-halfPlayerHeight,e-halfY]);that.flame.y.push([-1*halfPlayerHeight,halfY])},createFlames(),this.gameContainer=document.createElement("div"),this.gameContainer.className="ASTEROIDSYEAH",document.body.appendChild(this.gameContainer),this.canvas=document.createElement("canvas"),this.canvas.setAttribute("width",w),this.canvas.setAttribute("height",h),this.canvas.className="ASTEROIDSYEAH",this.canvas.style)width=w+"px",height=h+"px",position="fixed",top="0px",left="0px",bottom="0px",right="0px",zIndex="10000";"undefined"!=typeof G_vmlCanvasManager?(this.canvas=G_vmlCanvasManager.initElement(this.canvas),this.canvas.getContext||alert("So... you're using IE? Please join me at http://github.com/erkie/erkie.github.com if you think you can help")):this.canvas.getContext||alert("This program does not yet support your browser. Please join me at http://github.com/erkie/erkie.github.com if you think you can help"),addEvent(this.canvas,"mousedown",(function(e){e=e||window.event;var t=document.createElement("span");t.style.position="absolute",t.style.border="1px solid #999",t.style.background="white",t.style.color="black",t.innerHTML="Press Esc to quit",document.body.appendChild(t);var i=e.pageX||e.clientX+document.documentElement.scrollLeft,s=e.pageY||e.clientY+document.documentElement.scrollTop;t.style.left=i-t.offsetWidth/2+"px",t.style.top=s-t.offsetHeight/2+"px",setTimeout((function(){try{t.parentNode.removeChild(t)}catch(e){}}),1e3)}));var eventResize=function(){if(isIE)w=document.documentElement.clientWidth,h=document.documentElement.clientHeight,isIEQuirks&&(w=document.body.clientWidth,h=document.body.clientHeight),that.canvas.setAttribute("width",w),that.canvas.setAttribute("height",h);else with(that.canvas.style.display="none",w=document.documentElement.clientWidth,h=document.documentElement.clientHeight,that.canvas.setAttribute("width",w),that.canvas.setAttribute("height",h),that.canvas.style)display="block",width=w+"px",height=h+"px"};if(addEvent(window,"resize",eventResize),this.gameContainer.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.ctx.fillStyle="black",this.ctx.strokeStyle="black",document.getElementById("ASTEROIDS-NAVIGATION"))this.navigation=document.getElementById("ASTEROIDS-NAVIGATION"),this.points=document.getElementById("ASTEROIDS-POINTS");else{with(this.navigation=document.createElement("div"),this.navigation.id="ASTEROIDS-NAVIGATION",this.navigation.className="ASTEROIDSYEAH",this.navigation.style)fontFamily="Arial,sans-serif",position="fixed",zIndex="10001",bottom="10px",right="10px",textAlign="right";this.navigation.innerHTML="(press esc to quit) ",this.gameContainer.appendChild(this.navigation),this.points=document.createElement("span"),this.points.id="ASTEROIDS-POINTS",this.points.style.font="28pt Arial, sans-serif",this.points.style.fontWeight="bold",this.points.className="ASTEROIDSYEAH",this.navigation.appendChild(this.points)}if(isIEQuirks&&(this.gameContainer.style.position=this.canvas.style.position=this.navigation.style.position="absolute"),setScore(),"undefined"!=typeof G_vmlCanvasManager)for(var children=this.canvas.getElementsByTagName("*"),i=0,c;c=children[i];i++)addClass(c,"ASTEROIDSYEAH");var eventKeydown=function(e){switch(e=e||window.event,that.keysPressed[e.keyCode]=!0,e.keyCode){case code(" "):that.firedAt=1}if(-1!=indexOf([code("up"),code("down"),code("right"),code("left"),code(" "),code("B"),code("W"),code("A"),code("S"),code("D")],e.keyCode))return e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),e.returnValue=!1,e.cancelBubble=!0,!1};addEvent(document,"keydown",eventKeydown);var eventKeypress=function(e){if(e=e||window.event,-1!=indexOf([code("up"),code("down"),code("right"),code("left"),code(" "),code("W"),code("A"),code("S"),code("D")],e.keyCode||e.which))return e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),e.returnValue=!1,e.cancelBubble=!0,!1};addEvent(document,"keypress",eventKeypress);var eventKeyup=function(e){if(e=e||window.event,that.keysPressed[e.keyCode]=!1,-1!=indexOf([code("up"),code("down"),code("right"),code("left"),code(" "),code("B"),code("W"),code("A"),code("S"),code("D")],e.keyCode))return e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),e.returnValue=!1,e.cancelBubble=!0,!1};addEvent(document,"keyup",eventKeyup),this.ctx.clear=function(){this.clearRect(0,0,w,h)},this.ctx.clear(),this.ctx.drawLine=function(e,t,i,s){this.beginPath(),this.moveTo(e,t),this.lineTo(i,s),this.lineTo(i+1,s+1),this.closePath(),this.fill()},this.ctx.tracePoly=function(e){this.beginPath(),this.moveTo(e[0][0],e[0][1]);for(var t=1;t<e.length;t++)this.lineTo(e[t][0],e[t][1]);this.closePath()},this.ctx.drawPlayer=function(){this.save(),this.translate(that.pos.x,that.pos.y),this.rotate(that.dir.angle()),this.tracePoly(playerVerts),this.fillStyle="white",this.fill(),this.tracePoly(playerVerts),this.stroke(),this.restore()};var PI_SQ=2*Math.PI;this.ctx.drawBullets=function(e){for(var t=0;t<e.length;t++)this.beginPath(),this.arc(e[t].pos.x,e[t].pos.y,bulletRadius,0,PI_SQ,!0),this.closePath(),this.fill()};var randomParticleColor=function(){return["red","yellow"][random(0,1)]};this.ctx.drawParticles=function(e){for(var t=this.fillStyle,i=0;i<e.length;i++)this.fillStyle=randomParticleColor(),this.drawLine(e[i].pos.x,e[i].pos.y,e[i].pos.x-10*e[i].dir.x,e[i].pos.y-10*e[i].dir.y);this.fillStyle=t},this.ctx.drawFlames=function(e){this.save(),this.translate(that.pos.x,that.pos.y),this.rotate(that.dir.angle());var t=this.strokeStyle;this.strokeStyle="red",this.tracePoly(e.r),this.stroke(),this.strokeStyle="yellow",this.tracePoly(e.y),this.stroke(),this.strokeStyle=t,this.restore()};try{window.focus()}catch(e){}addParticles(this.pos),addClass(document.body,"ASTEROIDSYEAH");var isRunning=!0,lastUpdate=(new Date).getTime();this.update=function(){var e=!1,t=(new Date).getTime(),i=(t-lastUpdate)/1e3;lastUpdate=t;var s=!1;if(t-this.updated.flame>50&&(createFlames(),this.updated.flame=t),this.scrollPos.x=window.pageXOffset||document.documentElement.scrollLeft,this.scrollPos.y=window.pageYOffset||document.documentElement.scrollTop,this.keysPressed[code("up")]||this.keysPressed[code("W")]?(this.vel.add(this.dir.mulNew(acc*i)),s=!0):this.vel.mul(.96),(this.keysPressed[code("left")]||this.keysPressed[code("A")])&&(e=!0,this.dir.rotate(radians(rotSpeed*i*-1))),(this.keysPressed[code("right")]||this.keysPressed[code("D")])&&(e=!0,this.dir.rotate(radians(rotSpeed*i))),this.keysPressed[code(" ")]&&t-this.firedAt>timeBetweenFire&&(this.bullets.unshift({dir:this.dir.cp(),pos:this.pos.cp(),startVel:this.vel.cp(),cameAlive:t}),this.firedAt=t,this.bullets.length>maxBullets&&this.bullets.pop()),this.keysPressed[code("B")]?(this.updated.enemies||(updateEnemyIndex(),this.updated.enemies=!0),e=!0,this.updated.blink.time+=1e3*i,this.updated.blink.time>timeBetweenBlink&&(this.toggleBlinkStyle(),this.updated.blink.time=0)):this.updated.enemies=!1,this.keysPressed[code("esc")])destroy.apply(this);else{this.vel.len()>maxSpeed&&this.vel.setLength(maxSpeed),this.pos.add(this.vel.mulNew(i)),this.pos.x>w?(window.scrollTo(this.scrollPos.x+50,this.scrollPos.y),this.pos.x=0):this.pos.x<0&&(window.scrollTo(this.scrollPos.x-50,this.scrollPos.y),this.pos.x=w),this.pos.y>h?(window.scrollTo(this.scrollPos.x,this.scrollPos.y+.75*h),this.pos.y=0):this.pos.y<0&&(window.scrollTo(this.scrollPos.x,this.scrollPos.y-.75*h),this.pos.y=h);for(var n=this.bullets.length-1;n>=0;n--)if(t-this.bullets[n].cameAlive>2e3)this.bullets.splice(n,1),e=!0;else{var a=this.bullets[n].dir.setLengthNew(bulletSpeed*i).add(this.bullets[n].startVel.mulNew(i));this.bullets[n].pos.add(a),boundsCheck(this.bullets[n].pos);var o=getElementFromPoint(this.bullets[n].pos.x,this.bullets[n].pos.y);o&&o.tagName&&-1==indexOf(ignoredTypes,o.tagName.toUpperCase())&&hasOnlyTextualChildren(o)&&"ASTEROIDSYEAH"!=o.className&&(didKill=!0,addParticles(this.bullets[n].pos),this.dying.push(o),this.bullets.splice(n,1))}if(this.dying.length){for(n=this.dying.length-1;n>=0;n--)try{this.dying[n].parentNode&&window.ASTEROIDS.enemiesKilled++,this.dying[n].parentNode.removeChild(this.dying[n])}catch(e){}setScore(),this.dying=[]}for(n=this.particles.length-1;n>=0;n--)this.particles[n].pos.add(this.particles[n].dir.mulNew(particleSpeed*i*Math.random())),t-this.particles[n].cameAlive>1e3&&(this.particles.splice(n,1),e=!0);isIEQuirks&&(this.gameContainer.style.left=this.canvas.style.left=document.documentElement.scrollLeft+"px",this.gameContainer.style.top=this.canvas.style.top=document.documentElement.scrollTop+"px",this.navigation.style.right="10px",this.navigation.style.top=document.documentElement.scrollTop+document.body.clientHeight-this.navigation.clientHeight-10+"px"),(e||0!=this.bullets.length||0!=this.particles.length||!this.pos.is(this.lastPos)||this.vel.len()>0)&&(this.ctx.clear(),this.ctx.drawPlayer(),s&&this.ctx.drawFlames(that.flame),this.bullets.length&&this.ctx.drawBullets(this.bullets),this.particles.length&&this.ctx.drawParticles(this.particles)),this.lastPos=this.pos}};var updateFunc=function(){try{that.update.call(that)}catch(e){throw clearInterval(interval),e}},interval=setInterval(updateFunc,1e3/FPS);function destroy(){removeEvent(document,"keydown",eventKeydown),removeEvent(document,"keypress",eventKeypress),removeEvent(document,"keyup",eventKeyup),removeEvent(window,"resize",eventResize),isRunning=!1,removeStylesheet("ASTEROIDSYEAHSTYLES"),removeClass(document.body,"ASTEROIDSYEAH"),this.gameContainer.parentNode.removeChild(this.gameContainer)}}if(window.ASTEROIDSPLAYERS||(window.ASTEROIDSPLAYERS=[]),window.ActiveXObject&&!document.createElement("canvas").getContext){try{var xamlScript=document.createElement("script");xamlScript.setAttribute("type","text/xaml"),xamlScript.textContent='<?xml version="1.0"?><Canvas xmlns="http://schemas.microsoft.com/client/2007"></Canvas>',document.getElementsByTagName("head")[0].appendChild(xamlScript)}catch(e){}var script=document.createElement("script");script.setAttribute("type","text/javascript"),script.onreadystatechange=function(){"loaded"!=script.readyState&&"complete"!=script.readyState||"undefined"!=typeof G_vmlCanvasManager&&(window.ASTEROIDSPLAYERS[window.ASTEROIDSPLAYERS.length]=new Asteroids)},script.src="http://erkie.github.com/excanvas.js",document.getElementsByTagName("head")[0].appendChild(script)}else window.ASTEROIDSPLAYERS[window.ASTEROIDSPLAYERS.length]=new Asteroids}();