Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #21172 > unrolled thread

Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral

Started byjonas.thornvall@gmail.com
First post2013-09-06 01:12 -0700
Last post2013-09-09 19:38 +0100
Articles 6 — 4 participants

Back to article view | Back to comp.lang.javascript


Contents

  Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral jonas.thornvall@gmail.com - 2013-09-06 01:12 -0700
    Re: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral Ken <usenet-so@abdiassoftware.com> - 2013-09-06 18:37 -0500
      Re: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral jonas.thornvall@gmail.com - 2013-09-06 23:15 -0700
    Re: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> - 2013-09-07 21:21 +0100
      Re: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral Stefan Weiss <krewecherl@gmail.com> - 2013-09-08 02:04 +0200
        WAS: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> - 2013-09-09 19:38 +0100

#21172 — Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral

Fromjonas.thornvall@gmail.com
Date2013-09-06 01:12 -0700
SubjectMake an anime that draws primes different from offsets number++ , it's a variant of ulam spiral
Message-ID<2c5d4c48-eb2b-4ade-9a00-6dc5f50c8c87@googlegroups.com>
What i basicly want to do is to call the function anime plotting it again and again from different offsets -> numberGlobal. ( The divisor set size of square, font)

But i can not get it to work, anyone good at canvas?


<!DOCTYPE html>
<html>
<head></head>
<canvas id="myCanvas" width="4000" height="4000">Your browser does not support the HTML5 canvas tag.</canvas>

<script type="text/javascript">
var divisorGlobal=10;
var numberGlobal=1;


function isPrime(n) {
 if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false; 
 var m=Math.sqrt(n);
 for (var i=2;i<=m;i++) if (n%i==0) return false;
 return true;
}

function clear() {
  ctx.clearRect(0,0,4000,4000);
}

function anime() {

divisor=10;
number=1;
divisor=divisorGlobal;
number=numberGlobal;
asize=62/divisor;
storlek=54;
fstor=15/divisor;
afonten="bold "+fstor+"px Arial";
height=storlek/divisor;
width=storlek/divisor;
v_inner=0;
h_inner=0;
h_outer=0;
v_outer=0;
down=1;
back=2;

ctx.fillStyle='yellow';
ctx.fillRect(h_inner,v_outer,width,height);
ctx.fillStyle = "blue";
ctx.font = afonten;
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner+15; 
h_outer=h_outer+asize;
number++;

while(number<10000){
vertical=0;
v_outer=0;
v_inner=v_outer;
h_inner=h_outer;
while(vertical<down){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+1, v_inner+12);
v_inner=v_inner+asize;
vertical++;
number++;
}

down++;
q=0;
h_inner=h_outer;

while(q<back){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner-asize;
q++;
number++;
}

back++;
h_outer=h_outer+asize;

}
number++;
}

function draw() {
  clear();
  anime(divisorGlobal,numberGlobal);
  numberGlobal++;
}



function init() {
  canvas = document.getElementById("myCanvas");
  ctx = canvas.getContext("2d");
  return setInterval(anime,10);
}

init();

</script>

[toc] | [next] | [standalone]


#21177

FromKen <usenet-so@abdiassoftware.com>
Date2013-09-06 18:37 -0500
Message-ID<l0dp0n$lf4$1@speranza.aioe.org>
In reply to#21172
On 06.09.2013 03:12, jonas.thornvall@gmail.com wrote:
> function draw() {
>    clear();
>    anime(divisorGlobal,numberGlobal);
>    numberGlobal++;
> }

There are a lot of issues in the code but to target the essential -

To animate call like this:

   function draw() {

       clear();
       anime(divisorGlobal,numberGlobal);
       numberGlobal++;

       requestAnimationFrame(draw);
   }

requestAnimationFrame is a more low-level approach which works more 
efficiently and guarantees to synchronize to the monitors VBLANK 
(contrary to setInterval and setTimeout which can only approximate this 
as they only takes integer value (60 fps is about 16.7 ms per frame). 
This means smoother animations and less resources used.

Which of course implies that the setInterval call is removed and 
replaced with a call to:

    draw();

instead to start the loop.

requestAnimationFrame must be prefixed in some browsers (Firefox is 
about to release version without need for prefix) so you can use this 
shim by Paul Irish to get around that and to support older versions 
(http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/) 
(I corrected the name below):

   window.requestAnimationFrame = (function(){
     return  window.requestAnimationFrame       ||
             window.webkitRequestAnimationFrame ||
             window.mozRequestAnimationFrame    ||
             function( callback ){
               window.setTimeout(callback, 1000 / 60);
             };
   })();

You might want to implement a condition in your loop so you are able to 
stop it from running, something like this:

   var isPlaying = true,
       requestId;

   function loop() {
     // render here
     if (isPlaying === true)
       requestId = requestAnimationFrame(loop);
   }

   function stop() {
     isPlaying = false;
     cancelAnimationFrame(requestId);
   }

(see link above for shim for cancelAnimationFrame - it's strictly not 
necessary but it doesn't hurt to support it)

PS: 4000x4000 canvas is very huge... you /will/ run into performance 
problems especially since you clear the whole canvas for each frame 
(which will probably result in a lower framerate depending on computer).

When you are doing this:

   function anime() {

     divisor=10;
     number=1;
     divisor=divisorGlobal;
     ....

you are setting /properties/ on the *window* object. This is not 
advicable. You should declare all of your variables like this:

   function anime() {

     var divisor=10;
     var number=1;
     var divisor=divisorGlobal;
     ....

or simply (this helps minifiers):

     var divisor=10,
         number=1,
         divisor=divisorGlobal,
         ....

Local scoped variables are faster to look up for the parser than global 
object properties so you may (or may not) notice performance gain 
depending on various factors (browser implementation being one). And 
setting things on window can accidentely override stuff.

Also, in your anime function include this line at the beginning:

     ctx.beginPath();

Looking at it roughly it does not appear you are adding to path (can't 
remeber on the fly if fillText() do or not, but in any case, if you do 
these paths will accumulate and things will be slower and slower for 
each frame. beginPath() resets the path.

Hope this is of some help.

-- 
Ken Fyrstenberg
Abdias Software
http://abdiassoftware.com/
(remove usenet- from address)

[toc] | [prev] | [next] | [standalone]


#21178

Fromjonas.thornvall@gmail.com
Date2013-09-06 23:15 -0700
Message-ID<0a7113fa-26a2-4b2d-ad12-4c53a49c1ba2@googlegroups.com>
In reply to#21177
Den lördagen den 7:e september 2013 kl. 01:37:34 UTC+2 skrev Ken:
> On 06.09.2013 03:12, jonas.thornvall@gmail.com wrote:
> 
> > function draw() {
> 
> >    clear();
> 
> >    anime(divisorGlobal,numberGlobal);
> 
> >    numberGlobal++;
> 
> > }
> 
> 
> 
> There are a lot of issues in the code but to target the essential -
> 
> 
> 
> To animate call like this:
> 
> 
> 
>    function draw() {
> 
> 
> 
>        clear();
> 
>        anime(divisorGlobal,numberGlobal);
> 
>        numberGlobal++;
> 
> 
> 
>        requestAnimationFrame(draw);
> 
>    }
> 
> 
> 
> requestAnimationFrame is a more low-level approach which works more 
> 
> efficiently and guarantees to synchronize to the monitors VBLANK 
> 
> (contrary to setInterval and setTimeout which can only approximate this 
> 
> as they only takes integer value (60 fps is about 16.7 ms per frame). 
> 
> This means smoother animations and less resources used.
> 
> 
> 
> Which of course implies that the setInterval call is removed and 
> 
> replaced with a call to:
> 
> 
> 
>     draw();
> 
> 
> 
> instead to start the loop.
> 
> 
> 
> requestAnimationFrame must be prefixed in some browsers (Firefox is 
> 
> about to release version without need for prefix) so you can use this 
> 
> shim by Paul Irish to get around that and to support older versions 
> 
> (http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/) 
> 
> (I corrected the name below):
> 
> 
> 
>    window.requestAnimationFrame = (function(){
> 
>      return  window.requestAnimationFrame       ||
> 
>              window.webkitRequestAnimationFrame ||
> 
>              window.mozRequestAnimationFrame    ||
> 
>              function( callback ){
> 
>                window.setTimeout(callback, 1000 / 60);
> 
>              };
> 
>    })();
> 
> 
> 
> You might want to implement a condition in your loop so you are able to 
> 
> stop it from running, something like this:
> 
> 
> 
>    var isPlaying = true,
> 
>        requestId;
> 
> 
> 
>    function loop() {
> 
>      // render here
> 
>      if (isPlaying === true)
> 
>        requestId = requestAnimationFrame(loop);
> 
>    }
> 
> 
> 
>    function stop() {
> 
>      isPlaying = false;
> 
>      cancelAnimationFrame(requestId);
> 
>    }
> 
> 
> 
> (see link above for shim for cancelAnimationFrame - it's strictly not 
> 
> necessary but it doesn't hurt to support it)
> 
> 
> 
> PS: 4000x4000 canvas is very huge... you /will/ run into performance 
> 
> problems especially since you clear the whole canvas for each frame 
> 
> (which will probably result in a lower framerate depending on computer).
> 
> 
> 
> When you are doing this:
> 
> 
> 
>    function anime() {
> 
> 
> 
>      divisor=10;
> 
>      number=1;
> 
>      divisor=divisorGlobal;
> 
>      ....
> 
> 
> 
> you are setting /properties/ on the *window* object. This is not 
> 
> advicable. You should declare all of your variables like this:
> 
> 
> 
>    function anime() {
> 
> 
> 
>      var divisor=10;
> 
>      var number=1;
> 
>      var divisor=divisorGlobal;
> 
>      ....
> 
> 
> 
> or simply (this helps minifiers):
> 
> 
> 
>      var divisor=10,
> 
>          number=1,
> 
>          divisor=divisorGlobal,
> 
>          ....
> 
> 
> 
> Local scoped variables are faster to look up for the parser than global 
> 
> object properties so you may (or may not) notice performance gain 
> 
> depending on various factors (browser implementation being one). And 
> 
> setting things on window can accidentely override stuff.
> 
> 
> 
> Also, in your anime function include this line at the beginning:
> 
> 
> 
>      ctx.beginPath();
> 
> 
> 
> Looking at it roughly it does not appear you are adding to path (can't 
> 
> remeber on the fly if fillText() do or not, but in any case, if you do 
> 
> these paths will accumulate and things will be slower and slower for 
> 
> each frame. beginPath() resets the path.
> 
> 
> 
> Hope this is of some help.
> 
> 
> 
> -- 
> 
> Ken Fyrstenberg
> 
> Abdias Software
> 
> http://abdiassoftware.com/
> 
> (remove usenet- from address)

Thanks Ken i will try to implement your suggestions to see if i can get any extra performance. The primality test can of course be better.

I did realise i called wrong function...
I aim to call the program frome form in a frameset and pass parameter so i can set distance between primes +1,+2,+3... and startvalue and so one.

At redraw i will also make it possible to set separation in start compared with previous frame so you could set 1,2,3... numbers apart or square apart.

Also i will try to incorporate a geometrical offset, see example two below.

And of course the ability to set size of drawed squares and fonts from the form.
If you want to try 2 examples of what the script is intended to do copy below.

Thanks for your suggestions will try to implement them.

<!DOCTYPE html>
<html>
<head></head>
<canvas id="myCanvas" width="4000" height="4000">Your browser does not support the HTML5 canvas tag.</canvas>

<script type="text/javascript">
var divisorGlobal=10;
var numberGlobal=1;


function isPrime(n) {
 if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false; 
 var m=Math.sqrt(n);
 for (var i=2;i<=m;i++) if (n%i==0) return false;
 return true;
}

function clear() {
  ctx.clearRect(0,0,800,800);
}

function anime() {

divisor=2;
//divisor=divisorGlobal;
number=numberGlobal;
asize=67/divisor;
storlek=54;
fstor=15/divisor;
afonten="bold "+fstor+"px Arial";
height=storlek/divisor;
width=storlek/divisor;
v_inner=0;
h_inner=0;
h_outer=0;
v_outer=0;
down=1;
back=2;

ctx.fillStyle='yellow';
ctx.fillRect(h_inner,v_outer,width,height);
ctx.fillStyle = "blue";
ctx.font = afonten;
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner+15; 
h_outer=h_outer+asize;
number++;

while(number<10000){
vertical=0;
v_outer=0;
v_inner=v_outer;
h_inner=h_outer;
while(vertical<down){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+1, v_inner+12);
v_inner=v_inner+asize;
vertical++;
number++;
}

down++;
q=0;
h_inner=h_outer;

while(q<back){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner-asize;
q++;
number++;
}

back++;
h_outer=h_outer+asize;

}
number++;
}

function draw() {
  clear();
  anime(divisorGlobal,numberGlobal);
  numberGlobal++;
}



function init() {
  canvas = document.getElementById("myCanvas");
  ctx = canvas.getContext("2d");
  return setInterval(draw,0);
//draw();
}

init();

</script>

Or this one with offset 1.
<!DOCTYPE html>
<html>
<head></head>
<canvas id="myCanvas" width="4000" height="4000">Your browser does not support the HTML5 canvas tag.</canvas>

<script type="text/javascript">
var divisorGlobal=10;
var numberGlobal=1;


function isPrime(n) {
 if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false; 
 var m=Math.sqrt(n);
 for (var i=2;i<=m;i++) if (n%i==0) return false;
 return true;
}

function clear() {
  ctx.clearRect(0,0,800,800);
}

function anime() {

divisor=2;
//divisor=divisorGlobal;
number=numberGlobal;
asize=67/divisor;
storlek=54;
fstor=15/divisor;
afonten="bold "+fstor+"px Arial";
height=storlek/divisor;
width=storlek/divisor;
v_inner=0;
h_inner=0;
h_outer=0;
v_outer=0;
down=1;
back=2;

//ctx.fillStyle='yellow';
//ctx.fillRect(h_inner,v_outer,width,height);
//ctx.fillStyle = "blue";
//ctx.font = afonten;
//if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
//h_inner=h_inner+15; 
h_outer=h_outer+asize;
//number++;

while(number<10000){
vertical=0;
v_outer=0;
v_inner=v_outer;
h_inner=h_outer;
while(vertical<down){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+1, v_inner+12);
v_inner=v_inner+asize;
vertical++;
number++;
}

down++;
q=0;
h_inner=h_outer;

while(q<back){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner-asize;
q++;
number++;
}

back++;
h_outer=h_outer+asize;

}
number++;
}

function draw() {
  clear();
  anime(divisorGlobal,numberGlobal);
  numberGlobal++;
}



function init() {
  canvas = document.getElementById("myCanvas");
  ctx = canvas.getContext("2d");
  return setInterval(draw,0);
//draw()
}

init();

</script>


[toc] | [prev] | [next] | [standalone]


#21192

FromDr J R Stockton <reply1300@merlyn.demon.co.uk.invalid>
Date2013-09-07 21:21 +0100
Message-ID<4L3Y5fIEr4KSFwEb@invalid.uk.co.demon.merlyn.invalid>
In reply to#21172
In comp.lang.javascript message <2c5d4c48-eb2b-4ade-9a00-6dc5f50c8c87@go
oglegroups.com>, Fri, 6 Sep 2013 01:12:03, jonas.thornvall@gmail.com
posted:

>What i basicly want to do is to call the function anime plotting it again and again from different offsets -> numberGlobal. ( The divisor set
>size of square, font)
>
>But i can not get it to work, anyone good at canvas?
>

The first thing you should do is learn how English should be written.
The second is to read the newsgroup FAQ and see how to write questions
for the group.

And the third is to start with the simplest possible Canvas and draw the
simplest lines on that, getting that right and advancing stepwise
whenever your understanding increases.

For your primes, I suggest the Sieve of Eratosthenes; on my P4/3G WinXP
PC, that takes about 4ms in FF23 & 1ms in Opera 12.16 to calculate
primes up to 11111.

Consider also those of Atkin and Sundaram, if more speed is needed.



FOR OTHERS ALSO :

My pages contain shown code actuated by buttons.  Usually, it is thought
to be obvious that a given button just calls a certain function, but
sometimes that is not the case, even though onClick has been set to a
shortish string.  I **NEVER** like to duplicate code so that one change
needs two edits.

I have something partly like the following Form, in js-misc0.htm#SE :

<form action="#">

 <input type=text name=X size=6 value=333>

 <input type=button value=" B " onClick="TA1.value=EratoB(+X.value)">

 <input type=button value=" ? "
  onClick="TF=this.form ; eval(this.title)"
  title="TF.TA1.value=EratoB(+TF.X.value)">

 <br><textarea name=TA1 rows=6 cols=66 readonly></textarea>

</form>


There, the buttons do the same when clicked, except that the second
pollutes TF, wherever that may be, and hovering over the button reveals
its effective code.  Of course, 'value' can be used instead of 'title'.

Untested : I suppose that I can use  onClick="Oozlum(this)" and define
Oozlum elsewhere.

Any suggestions for improvements?  TNNR.


FYI - Jibbering may be slow, but patience is a rewarded virtue.

-- 
 (c) John Stockton, nr London UK               Reply address via Home Page.
   news:comp.lang.javascript FAQ <http://www.jibbering.com/faq/index.html>.
   <http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
   <http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

[toc] | [prev] | [next] | [standalone]


#21197

FromStefan Weiss <krewecherl@gmail.com>
Date2013-09-08 02:04 +0200
Message-ID<l0getk$ksp$1@news.albasani.net>
In reply to#21192
On 2013-09-07 22:21, Dr J R Stockton wrote:
> FOR OTHERS ALSO :
> 
> My pages contain shown code actuated by buttons.  Usually, it is thought
> to be obvious that a given button just calls a certain function

It's the most common case, but with event bubbling and capturing, and
the possibility of attaching multiple listeners to an event, no such
assumption should be made.

> I have something partly like the following Form, in js-misc0.htm#SE :
> 
> <form action="#">
> 
>  <input type=text name=X size=6 value=333>
> 
>  <input type=button value=" B " onClick="TA1.value=EratoB(+X.value)">
> 
>  <input type=button value=" ? "
>   onClick="TF=this.form ; eval(this.title)"
>   title="TF.TA1.value=EratoB(+TF.X.value)">
> 
>  <br><textarea name=TA1 rows=6 cols=66 readonly></textarea>
> 
> </form>
> 
> 
> There, the buttons do the same when clicked, except that the second
> pollutes TF, wherever that may be, and hovering over the button reveals
> its effective code.

Without leakage:

 <input type=button value=" ? "
  onClick="eval('TA1.value=' + this.title)"
  title="EratoB(+X.value)">

Still shows the relevant code in the title (which, I think, is what you
wanted).

> Untested : I suppose that I can use  onClick="Oozlum(this)" and define
> Oozlum elsewhere.

Of course you can. Personally, I would much prefer a helper function,
compared to relying on the rather unintuitive identifier resolution in
event attributes (even more so in form elements).

> Any suggestions for improvements?  TNNR.

If two buttons (or two *anything*) do the same thing, they should be
combined into a single function (DRY). You can still eval() code from
there, if you must.

- stefan

[toc] | [prev] | [next] | [standalone]


#21238 — WAS: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral

FromDr J R Stockton <reply1300@merlyn.demon.co.uk.invalid>
Date2013-09-09 19:38 +0100
SubjectWAS: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral
Message-ID<FanH9boAXhLSFwaH@invalid.uk.co.demon.merlyn.invalid>
In reply to#21197
In comp.lang.javascript message <l0getk$ksp$1@news.albasani.net>, Sun, 8
Sep 2013 02:04:04, Stefan Weiss <krewecherl@gmail.com> posted:

>On 2013-09-07 22:21, Dr J R Stockton wrote:
>> FOR OTHERS ALSO :
>>
>> My pages contain shown code actuated by buttons.  Usually, it is thought
>> to be obvious that a given button just calls a certain function
>
>It's the most common case, but with event bubbling and capturing, and
>the possibility of attaching multiple listeners to an event, no such
>assumption should be made.

I meant that "obvious" to be taken in the context of the page section in
question and on the assumption that the page is intended to be helpful.


>> I have something partly like the following Form, in js-misc0.htm#SE :
>>
>> <form action="#">
>>
>>  <input type=text name=X size=6 value=333>
>>
>>  <input type=button value=" B " onClick="TA1.value=EratoB(+X.value)">
>>
>>  <input type=button value=" ? "
>>   onClick="TF=this.form ; eval(this.title)"
>>   title="TF.TA1.value=EratoB(+TF.X.value)">
>>
>>  <br><textarea name=TA1 rows=6 cols=66 readonly></textarea>
>>
>> </form>
>>
>>
>> There, the buttons do the same when clicked, except that the second
>> pollutes TF, wherever that may be, and hovering over the button reveals
>> its effective code.
>
>Without leakage:
>
> <input type=button value=" ? "
>  onClick="eval('TA1.value=' + this.title)"
>  title="EratoB(+X.value)">
>
>Still shows the relevant code in the title (which, I think, is what you
>wanted).

As title or as value; the preference depends on circumstances.

>> Untested : I suppose that I can use  onClick="Oozlum(this)" and define
>> Oozlum elsewhere.
>
>Of course you can. Personally, I would much prefer a helper function,
>compared to relying on the rather unintuitive identifier resolution in
>event attributes (even more so in form elements).

I was uncertain there.  Your code works in IE8, and in current Firefox
Opera Safari & Chrome.  Thanks.


-- 
 (c) John Stockton, nr London UK.  ?@merlyn.demon.co.uk  DOS 3.3, 6.20; WinXP.
  Web  <http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms and links.
   PAS EXE TXT ZIP via  <http://www.merlyn.demon.co.uk/programs/00index.htm>
   My DOS  <http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web