diff --git a/docs/lecs-quarto/lecture01.html b/docs/lecs-quarto/lecture01.html deleted file mode 100644 index 6b3a25e..0000000 --- a/docs/lecs-quarto/lecture01.html +++ /dev/null @@ -1,8914 +0,0 @@ - - - - - - - - - - - - - lecture01 - - - - - - - - - - - - - - - - - - - -
-
- - -
-
-

Introduction to Inference for Data Science

-

STAT 201 - Lecture 01

- -

-
-
-

Population and parameters

-
    -
  • Population: The set of all units we want to study;

  • -
  • Parameter: A quantity that summarizes the population (e.g., mean, median, std. dev., quantiles, min, max, proportion);

    -
      -
    • Parameters are constant (not random!);
    • -
    • Parameters are usually unknown;
    • -
  • -
  • Variable: A variable is an attribute of the elements in the population.

  • -
-
-
-

Example: Aquarium

-

An aquarium has 20 fish. We are interested in the average weight of the fish in the aquarium.

-
-
    -
  • Population: 20 fish in the aquarium;
  • -
  • Variable of interest: weight;
  • -
  • Parameter: average weight of the 20 fish in the aquarium (denoted by \(\mu\));
  • -
-
-
-
-

Example: Aquarium

-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Table 1: The weight of the 20 fish in the aquarium. (Note 1dkg = 10g). -
-Fish - -Weight (dkg) - -Fish - -Weight (dkg) - -Fish - -Weight (dkg) - -Fish - -Weight (dkg) -
-Fish #1 - -43 - -Fish #6 - -44 - -Fish #11 - -26 - -Fish #16 - -42 -
-Fish #2 - -46 - -Fish #7 - -41 - -Fish #12 - -47 - -Fish #17 - -36 -
-Fish #3 - -47 - -Fish #8 - -40 - -Fish #13 - -37 - -Fish #18 - -36 -
-Fish #4 - -59 - -Fish #9 - -43 - -Fish #14 - -42 - -Fish #19 - -61 -
-Fish #5 - -24 - -Fish #10 - -58 - -Fish #15 - -60 - -Fish #20 - -37 -
-
-
-

Sample and statistics

-
    -
  • Random Sample: a randomly selected subset of the population;

  • -
  • Statistic: a quantity calculated based on a sample (e.g., sample mean and sample std. dev.);

    -
      -
    • statistics used to estimate parameters;
    • -
    • statistics are random quantities (they depend on the sample drawn);
    • -
  • -
-
-
-

Example: Aquarium

-
    -
  • Suppose we randomly choose 3 fish from the aquarium to weigh them;

  • -
  • We can calculate the sample mean (denoted by \(\overline{y}\)), to estimate the population mean, \(\mu\).

  • -
-
-
    -
  • The problem is: there are 1140 possible samples of 3 fish we could select. -
      -
    • How close will \(\overline{y}\) be to \(\mu\)?
    • -
  • -
-
-
-
-

Example: Sampling Distribution

-
-

You might need to refresh this page to show the plot

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Table 2: All possible samples of three fish from the aquarium and their respective sample mean. -
-Sample - -Sample Mean (dkg) - -Sample - -Sample Mean (dkg) - -Sample - -Sample Mean (dkg) - -Sample - -Sample Mean (dkg) -
-(#1, #2, #3) - -45.33 - -(#1, #2, #4) - -49.33 - -(#1, #2, #5) - -37.67 - -(#1, #2, #6) - -44.33 -
-(#1, #2, #7) - -43.33 - -(#1, #2, #8) - -43.00 - -(#1, #2, #9) - -44.00 - -(#1, #2, #10) - -49.00 -
-(#1, #2, #11) - -38.33 - -(#1, #2, #12) - -45.33 - -(#1, #2, #13) - -42.00 - -(#1, #2, #14) - -43.67 -
-(#1, #2, #15) - -49.67 - -(#1, #2, #16) - -43.67 - -(#1, #2, #17) - -41.67 - -(#1, #2, #18) - -41.67 -
-(#1, #2, #19) - -50.00 - -(#1, #2, #20) - -42.00 - -(#1, #3, #4) - -49.67 - -(#1, #3, #5) - -38.00 -
-(#1, #3, #6) - -44.67 - -(#1, #3, #7) - -43.67 - -(#1, #3, #8) - -43.33 - -(#1, #3, #9) - -44.33 -
-(#1, #3, #10) - -49.33 - -(#1, #3, #11) - -38.67 - -(#1, #3, #12) - -45.67 - -(#1, #3, #13) - -42.33 -
-(#1, #3, #14) - -44.00 - -(#1, #3, #15) - -50.00 - -(#1, #3, #16) - -44.00 - -(#1, #3, #17) - -42.00 -
-(#1, #3, #18) - -42.00 - -(#1, #3, #19) - -50.33 - -(#1, #3, #20) - -42.33 - -(#1, #4, #5) - -42.00 -
-(#1, #4, #6) - -48.67 - -(#1, #4, #7) - -47.67 - -(#1, #4, #8) - -47.33 - -(#1, #4, #9) - -48.33 -
-(#1, #4, #10) - -53.33 - -(#1, #4, #11) - -42.67 - -(#1, #4, #12) - -49.67 - -(#1, #4, #13) - -46.33 -
-(#1, #4, #14) - -48.00 - -(#1, #4, #15) - -54.00 - -(#1, #4, #16) - -48.00 - -(#1, #4, #17) - -46.00 -
-(#1, #4, #18) - -46.00 - -(#1, #4, #19) - -54.33 - -(#1, #4, #20) - -46.33 - -(#1, #5, #6) - -37.00 -
-(#1, #5, #7) - -36.00 - -(#1, #5, #8) - -35.67 - -(#1, #5, #9) - -36.67 - -(#1, #5, #10) - -41.67 -
-(#1, #5, #11) - -31.00 - -(#1, #5, #12) - -38.00 - -(#1, #5, #13) - -34.67 - -(#1, #5, #14) - -36.33 -
-(#1, #5, #15) - -42.33 - -(#1, #5, #16) - -36.33 - -(#1, #5, #17) - -34.33 - -(#1, #5, #18) - -34.33 -
-(#1, #5, #19) - -42.67 - -(#1, #5, #20) - -34.67 - -(#1, #6, #7) - -42.67 - -(#1, #6, #8) - -42.33 -
-(#1, #6, #9) - -43.33 - -(#1, #6, #10) - -48.33 - -(#1, #6, #11) - -37.67 - -(#1, #6, #12) - -44.67 -
-(#1, #6, #13) - -41.33 - -(#1, #6, #14) - -43.00 - -(#1, #6, #15) - -49.00 - -(#1, #6, #16) - -43.00 -
-(#1, #6, #17) - -41.00 - -(#1, #6, #18) - -41.00 - -(#1, #6, #19) - -49.33 - -(#1, #6, #20) - -41.33 -
-(#1, #7, #8) - -41.33 - -(#1, #7, #9) - -42.33 - -(#1, #7, #10) - -47.33 - -(#1, #7, #11) - -36.67 -
-(#1, #7, #12) - -43.67 - -(#1, #7, #13) - -40.33 - -(#1, #7, #14) - -42.00 - -(#1, #7, #15) - -48.00 -
-(#1, #7, #16) - -42.00 - -(#1, #7, #17) - -40.00 - -(#1, #7, #18) - -40.00 - -(#1, #7, #19) - -48.33 -
-(#1, #7, #20) - -40.33 - -(#1, #8, #9) - -42.00 - -(#1, #8, #10) - -47.00 - -(#1, #8, #11) - -36.33 -
-(#1, #8, #12) - -43.33 - -(#1, #8, #13) - -40.00 - -(#1, #8, #14) - -41.67 - -(#1, #8, #15) - -47.67 -
-(#1, #8, #16) - -41.67 - -(#1, #8, #17) - -39.67 - -(#1, #8, #18) - -39.67 - -(#1, #8, #19) - -48.00 -
-(#1, #8, #20) - -40.00 - -(#1, #9, #10) - -48.00 - -(#1, #9, #11) - -37.33 - -(#1, #9, #12) - -44.33 -
-(#1, #9, #13) - -41.00 - -(#1, #9, #14) - -42.67 - -(#1, #9, #15) - -48.67 - -(#1, #9, #16) - -42.67 -
-(#1, #9, #17) - -40.67 - -(#1, #9, #18) - -40.67 - -(#1, #9, #19) - -49.00 - -(#1, #9, #20) - -41.00 -
-(#1, #10, #11) - -42.33 - -(#1, #10, #12) - -49.33 - -(#1, #10, #13) - -46.00 - -(#1, #10, #14) - -47.67 -
-(#1, #10, #15) - -53.67 - -(#1, #10, #16) - -47.67 - -(#1, #10, #17) - -45.67 - -(#1, #10, #18) - -45.67 -
-(#1, #10, #19) - -54.00 - -(#1, #10, #20) - -46.00 - -(#1, #11, #12) - -38.67 - -(#1, #11, #13) - -35.33 -
-(#1, #11, #14) - -37.00 - -(#1, #11, #15) - -43.00 - -(#1, #11, #16) - -37.00 - -(#1, #11, #17) - -35.00 -
-(#1, #11, #18) - -35.00 - -(#1, #11, #19) - -43.33 - -(#1, #11, #20) - -35.33 - -(#1, #12, #13) - -42.33 -
-(#1, #12, #14) - -44.00 - -(#1, #12, #15) - -50.00 - -(#1, #12, #16) - -44.00 - -(#1, #12, #17) - -42.00 -
-(#1, #12, #18) - -42.00 - -(#1, #12, #19) - -50.33 - -(#1, #12, #20) - -42.33 - -(#1, #13, #14) - -40.67 -
-(#1, #13, #15) - -46.67 - -(#1, #13, #16) - -40.67 - -(#1, #13, #17) - -38.67 - -(#1, #13, #18) - -38.67 -
-(#1, #13, #19) - -47.00 - -(#1, #13, #20) - -39.00 - -(#1, #14, #15) - -48.33 - -(#1, #14, #16) - -42.33 -
-(#1, #14, #17) - -40.33 - -(#1, #14, #18) - -40.33 - -(#1, #14, #19) - -48.67 - -(#1, #14, #20) - -40.67 -
-(#1, #15, #16) - -48.33 - -(#1, #15, #17) - -46.33 - -(#1, #15, #18) - -46.33 - -(#1, #15, #19) - -54.67 -
-(#1, #15, #20) - -46.67 - -(#1, #16, #17) - -40.33 - -(#1, #16, #18) - -40.33 - -(#1, #16, #19) - -48.67 -
-(#1, #16, #20) - -40.67 - -(#1, #17, #18) - -38.33 - -(#1, #17, #19) - -46.67 - -(#1, #17, #20) - -38.67 -
-(#1, #18, #19) - -46.67 - -(#1, #18, #20) - -38.67 - -(#1, #19, #20) - -47.00 - -(#2, #3, #4) - -50.67 -
-(#2, #3, #5) - -39.00 - -(#2, #3, #6) - -45.67 - -(#2, #3, #7) - -44.67 - -(#2, #3, #8) - -44.33 -
-(#2, #3, #9) - -45.33 - -(#2, #3, #10) - -50.33 - -(#2, #3, #11) - -39.67 - -(#2, #3, #12) - -46.67 -
-(#2, #3, #13) - -43.33 - -(#2, #3, #14) - -45.00 - -(#2, #3, #15) - -51.00 - -(#2, #3, #16) - -45.00 -
-(#2, #3, #17) - -43.00 - -(#2, #3, #18) - -43.00 - -(#2, #3, #19) - -51.33 - -(#2, #3, #20) - -43.33 -
-(#2, #4, #5) - -43.00 - -(#2, #4, #6) - -49.67 - -(#2, #4, #7) - -48.67 - -(#2, #4, #8) - -48.33 -
-(#2, #4, #9) - -49.33 - -(#2, #4, #10) - -54.33 - -(#2, #4, #11) - -43.67 - -(#2, #4, #12) - -50.67 -
-(#2, #4, #13) - -47.33 - -(#2, #4, #14) - -49.00 - -(#2, #4, #15) - -55.00 - -(#2, #4, #16) - -49.00 -
-(#2, #4, #17) - -47.00 - -(#2, #4, #18) - -47.00 - -(#2, #4, #19) - -55.33 - -(#2, #4, #20) - -47.33 -
-(#2, #5, #6) - -38.00 - -(#2, #5, #7) - -37.00 - -(#2, #5, #8) - -36.67 - -(#2, #5, #9) - -37.67 -
-(#2, #5, #10) - -42.67 - -(#2, #5, #11) - -32.00 - -(#2, #5, #12) - -39.00 - -(#2, #5, #13) - -35.67 -
-(#2, #5, #14) - -37.33 - -(#2, #5, #15) - -43.33 - -(#2, #5, #16) - -37.33 - -(#2, #5, #17) - -35.33 -
-(#2, #5, #18) - -35.33 - -(#2, #5, #19) - -43.67 - -(#2, #5, #20) - -35.67 - -(#2, #6, #7) - -43.67 -
-(#2, #6, #8) - -43.33 - -(#2, #6, #9) - -44.33 - -(#2, #6, #10) - -49.33 - -(#2, #6, #11) - -38.67 -
-(#2, #6, #12) - -45.67 - -(#2, #6, #13) - -42.33 - -(#2, #6, #14) - -44.00 - -(#2, #6, #15) - -50.00 -
-(#2, #6, #16) - -44.00 - -(#2, #6, #17) - -42.00 - -(#2, #6, #18) - -42.00 - -(#2, #6, #19) - -50.33 -
-(#2, #6, #20) - -42.33 - -(#2, #7, #8) - -42.33 - -(#2, #7, #9) - -43.33 - -(#2, #7, #10) - -48.33 -
-(#2, #7, #11) - -37.67 - -(#2, #7, #12) - -44.67 - -(#2, #7, #13) - -41.33 - -(#2, #7, #14) - -43.00 -
-(#2, #7, #15) - -49.00 - -(#2, #7, #16) - -43.00 - -(#2, #7, #17) - -41.00 - -(#2, #7, #18) - -41.00 -
-(#2, #7, #19) - -49.33 - -(#2, #7, #20) - -41.33 - -(#2, #8, #9) - -43.00 - -(#2, #8, #10) - -48.00 -
-(#2, #8, #11) - -37.33 - -(#2, #8, #12) - -44.33 - -(#2, #8, #13) - -41.00 - -(#2, #8, #14) - -42.67 -
-(#2, #8, #15) - -48.67 - -(#2, #8, #16) - -42.67 - -(#2, #8, #17) - -40.67 - -(#2, #8, #18) - -40.67 -
-(#2, #8, #19) - -49.00 - -(#2, #8, #20) - -41.00 - -(#2, #9, #10) - -49.00 - -(#2, #9, #11) - -38.33 -
-(#2, #9, #12) - -45.33 - -(#2, #9, #13) - -42.00 - -(#2, #9, #14) - -43.67 - -(#2, #9, #15) - -49.67 -
-(#2, #9, #16) - -43.67 - -(#2, #9, #17) - -41.67 - -(#2, #9, #18) - -41.67 - -(#2, #9, #19) - -50.00 -
-(#2, #9, #20) - -42.00 - -(#2, #10, #11) - -43.33 - -(#2, #10, #12) - -50.33 - -(#2, #10, #13) - -47.00 -
-(#2, #10, #14) - -48.67 - -(#2, #10, #15) - -54.67 - -(#2, #10, #16) - -48.67 - -(#2, #10, #17) - -46.67 -
-(#2, #10, #18) - -46.67 - -(#2, #10, #19) - -55.00 - -(#2, #10, #20) - -47.00 - -(#2, #11, #12) - -39.67 -
-(#2, #11, #13) - -36.33 - -(#2, #11, #14) - -38.00 - -(#2, #11, #15) - -44.00 - -(#2, #11, #16) - -38.00 -
-(#2, #11, #17) - -36.00 - -(#2, #11, #18) - -36.00 - -(#2, #11, #19) - -44.33 - -(#2, #11, #20) - -36.33 -
-(#2, #12, #13) - -43.33 - -(#2, #12, #14) - -45.00 - -(#2, #12, #15) - -51.00 - -(#2, #12, #16) - -45.00 -
-(#2, #12, #17) - -43.00 - -(#2, #12, #18) - -43.00 - -(#2, #12, #19) - -51.33 - -(#2, #12, #20) - -43.33 -
-(#2, #13, #14) - -41.67 - -(#2, #13, #15) - -47.67 - -(#2, #13, #16) - -41.67 - -(#2, #13, #17) - -39.67 -
-(#2, #13, #18) - -39.67 - -(#2, #13, #19) - -48.00 - -(#2, #13, #20) - -40.00 - -(#2, #14, #15) - -49.33 -
-(#2, #14, #16) - -43.33 - -(#2, #14, #17) - -41.33 - -(#2, #14, #18) - -41.33 - -(#2, #14, #19) - -49.67 -
-(#2, #14, #20) - -41.67 - -(#2, #15, #16) - -49.33 - -(#2, #15, #17) - -47.33 - -(#2, #15, #18) - -47.33 -
-(#2, #15, #19) - -55.67 - -(#2, #15, #20) - -47.67 - -(#2, #16, #17) - -41.33 - -(#2, #16, #18) - -41.33 -
-(#2, #16, #19) - -49.67 - -(#2, #16, #20) - -41.67 - -(#2, #17, #18) - -39.33 - -(#2, #17, #19) - -47.67 -
-(#2, #17, #20) - -39.67 - -(#2, #18, #19) - -47.67 - -(#2, #18, #20) - -39.67 - -(#2, #19, #20) - -48.00 -
-(#3, #4, #5) - -43.33 - -(#3, #4, #6) - -50.00 - -(#3, #4, #7) - -49.00 - -(#3, #4, #8) - -48.67 -
-(#3, #4, #9) - -49.67 - -(#3, #4, #10) - -54.67 - -(#3, #4, #11) - -44.00 - -(#3, #4, #12) - -51.00 -
-(#3, #4, #13) - -47.67 - -(#3, #4, #14) - -49.33 - -(#3, #4, #15) - -55.33 - -(#3, #4, #16) - -49.33 -
-(#3, #4, #17) - -47.33 - -(#3, #4, #18) - -47.33 - -(#3, #4, #19) - -55.67 - -(#3, #4, #20) - -47.67 -
-(#3, #5, #6) - -38.33 - -(#3, #5, #7) - -37.33 - -(#3, #5, #8) - -37.00 - -(#3, #5, #9) - -38.00 -
-(#3, #5, #10) - -43.00 - -(#3, #5, #11) - -32.33 - -(#3, #5, #12) - -39.33 - -(#3, #5, #13) - -36.00 -
-(#3, #5, #14) - -37.67 - -(#3, #5, #15) - -43.67 - -(#3, #5, #16) - -37.67 - -(#3, #5, #17) - -35.67 -
-(#3, #5, #18) - -35.67 - -(#3, #5, #19) - -44.00 - -(#3, #5, #20) - -36.00 - -(#3, #6, #7) - -44.00 -
-(#3, #6, #8) - -43.67 - -(#3, #6, #9) - -44.67 - -(#3, #6, #10) - -49.67 - -(#3, #6, #11) - -39.00 -
-(#3, #6, #12) - -46.00 - -(#3, #6, #13) - -42.67 - -(#3, #6, #14) - -44.33 - -(#3, #6, #15) - -50.33 -
-(#3, #6, #16) - -44.33 - -(#3, #6, #17) - -42.33 - -(#3, #6, #18) - -42.33 - -(#3, #6, #19) - -50.67 -
-(#3, #6, #20) - -42.67 - -(#3, #7, #8) - -42.67 - -(#3, #7, #9) - -43.67 - -(#3, #7, #10) - -48.67 -
-(#3, #7, #11) - -38.00 - -(#3, #7, #12) - -45.00 - -(#3, #7, #13) - -41.67 - -(#3, #7, #14) - -43.33 -
-(#3, #7, #15) - -49.33 - -(#3, #7, #16) - -43.33 - -(#3, #7, #17) - -41.33 - -(#3, #7, #18) - -41.33 -
-(#3, #7, #19) - -49.67 - -(#3, #7, #20) - -41.67 - -(#3, #8, #9) - -43.33 - -(#3, #8, #10) - -48.33 -
-(#3, #8, #11) - -37.67 - -(#3, #8, #12) - -44.67 - -(#3, #8, #13) - -41.33 - -(#3, #8, #14) - -43.00 -
-(#3, #8, #15) - -49.00 - -(#3, #8, #16) - -43.00 - -(#3, #8, #17) - -41.00 - -(#3, #8, #18) - -41.00 -
-(#3, #8, #19) - -49.33 - -(#3, #8, #20) - -41.33 - -(#3, #9, #10) - -49.33 - -(#3, #9, #11) - -38.67 -
-(#3, #9, #12) - -45.67 - -(#3, #9, #13) - -42.33 - -(#3, #9, #14) - -44.00 - -(#3, #9, #15) - -50.00 -
-(#3, #9, #16) - -44.00 - -(#3, #9, #17) - -42.00 - -(#3, #9, #18) - -42.00 - -(#3, #9, #19) - -50.33 -
-(#3, #9, #20) - -42.33 - -(#3, #10, #11) - -43.67 - -(#3, #10, #12) - -50.67 - -(#3, #10, #13) - -47.33 -
-(#3, #10, #14) - -49.00 - -(#3, #10, #15) - -55.00 - -(#3, #10, #16) - -49.00 - -(#3, #10, #17) - -47.00 -
-(#3, #10, #18) - -47.00 - -(#3, #10, #19) - -55.33 - -(#3, #10, #20) - -47.33 - -(#3, #11, #12) - -40.00 -
-(#3, #11, #13) - -36.67 - -(#3, #11, #14) - -38.33 - -(#3, #11, #15) - -44.33 - -(#3, #11, #16) - -38.33 -
-(#3, #11, #17) - -36.33 - -(#3, #11, #18) - -36.33 - -(#3, #11, #19) - -44.67 - -(#3, #11, #20) - -36.67 -
-(#3, #12, #13) - -43.67 - -(#3, #12, #14) - -45.33 - -(#3, #12, #15) - -51.33 - -(#3, #12, #16) - -45.33 -
-(#3, #12, #17) - -43.33 - -(#3, #12, #18) - -43.33 - -(#3, #12, #19) - -51.67 - -(#3, #12, #20) - -43.67 -
-(#3, #13, #14) - -42.00 - -(#3, #13, #15) - -48.00 - -(#3, #13, #16) - -42.00 - -(#3, #13, #17) - -40.00 -
-(#3, #13, #18) - -40.00 - -(#3, #13, #19) - -48.33 - -(#3, #13, #20) - -40.33 - -(#3, #14, #15) - -49.67 -
-(#3, #14, #16) - -43.67 - -(#3, #14, #17) - -41.67 - -(#3, #14, #18) - -41.67 - -(#3, #14, #19) - -50.00 -
-(#3, #14, #20) - -42.00 - -(#3, #15, #16) - -49.67 - -(#3, #15, #17) - -47.67 - -(#3, #15, #18) - -47.67 -
-(#3, #15, #19) - -56.00 - -(#3, #15, #20) - -48.00 - -(#3, #16, #17) - -41.67 - -(#3, #16, #18) - -41.67 -
-(#3, #16, #19) - -50.00 - -(#3, #16, #20) - -42.00 - -(#3, #17, #18) - -39.67 - -(#3, #17, #19) - -48.00 -
-(#3, #17, #20) - -40.00 - -(#3, #18, #19) - -48.00 - -(#3, #18, #20) - -40.00 - -(#3, #19, #20) - -48.33 -
-(#4, #5, #6) - -42.33 - -(#4, #5, #7) - -41.33 - -(#4, #5, #8) - -41.00 - -(#4, #5, #9) - -42.00 -
-(#4, #5, #10) - -47.00 - -(#4, #5, #11) - -36.33 - -(#4, #5, #12) - -43.33 - -(#4, #5, #13) - -40.00 -
-(#4, #5, #14) - -41.67 - -(#4, #5, #15) - -47.67 - -(#4, #5, #16) - -41.67 - -(#4, #5, #17) - -39.67 -
-(#4, #5, #18) - -39.67 - -(#4, #5, #19) - -48.00 - -(#4, #5, #20) - -40.00 - -(#4, #6, #7) - -48.00 -
-(#4, #6, #8) - -47.67 - -(#4, #6, #9) - -48.67 - -(#4, #6, #10) - -53.67 - -(#4, #6, #11) - -43.00 -
-(#4, #6, #12) - -50.00 - -(#4, #6, #13) - -46.67 - -(#4, #6, #14) - -48.33 - -(#4, #6, #15) - -54.33 -
-(#4, #6, #16) - -48.33 - -(#4, #6, #17) - -46.33 - -(#4, #6, #18) - -46.33 - -(#4, #6, #19) - -54.67 -
-(#4, #6, #20) - -46.67 - -(#4, #7, #8) - -46.67 - -(#4, #7, #9) - -47.67 - -(#4, #7, #10) - -52.67 -
-(#4, #7, #11) - -42.00 - -(#4, #7, #12) - -49.00 - -(#4, #7, #13) - -45.67 - -(#4, #7, #14) - -47.33 -
-(#4, #7, #15) - -53.33 - -(#4, #7, #16) - -47.33 - -(#4, #7, #17) - -45.33 - -(#4, #7, #18) - -45.33 -
-(#4, #7, #19) - -53.67 - -(#4, #7, #20) - -45.67 - -(#4, #8, #9) - -47.33 - -(#4, #8, #10) - -52.33 -
-(#4, #8, #11) - -41.67 - -(#4, #8, #12) - -48.67 - -(#4, #8, #13) - -45.33 - -(#4, #8, #14) - -47.00 -
-(#4, #8, #15) - -53.00 - -(#4, #8, #16) - -47.00 - -(#4, #8, #17) - -45.00 - -(#4, #8, #18) - -45.00 -
-(#4, #8, #19) - -53.33 - -(#4, #8, #20) - -45.33 - -(#4, #9, #10) - -53.33 - -(#4, #9, #11) - -42.67 -
-(#4, #9, #12) - -49.67 - -(#4, #9, #13) - -46.33 - -(#4, #9, #14) - -48.00 - -(#4, #9, #15) - -54.00 -
-(#4, #9, #16) - -48.00 - -(#4, #9, #17) - -46.00 - -(#4, #9, #18) - -46.00 - -(#4, #9, #19) - -54.33 -
-(#4, #9, #20) - -46.33 - -(#4, #10, #11) - -47.67 - -(#4, #10, #12) - -54.67 - -(#4, #10, #13) - -51.33 -
-(#4, #10, #14) - -53.00 - -(#4, #10, #15) - -59.00 - -(#4, #10, #16) - -53.00 - -(#4, #10, #17) - -51.00 -
-(#4, #10, #18) - -51.00 - -(#4, #10, #19) - -59.33 - -(#4, #10, #20) - -51.33 - -(#4, #11, #12) - -44.00 -
-(#4, #11, #13) - -40.67 - -(#4, #11, #14) - -42.33 - -(#4, #11, #15) - -48.33 - -(#4, #11, #16) - -42.33 -
-(#4, #11, #17) - -40.33 - -(#4, #11, #18) - -40.33 - -(#4, #11, #19) - -48.67 - -(#4, #11, #20) - -40.67 -
-(#4, #12, #13) - -47.67 - -(#4, #12, #14) - -49.33 - -(#4, #12, #15) - -55.33 - -(#4, #12, #16) - -49.33 -
-(#4, #12, #17) - -47.33 - -(#4, #12, #18) - -47.33 - -(#4, #12, #19) - -55.67 - -(#4, #12, #20) - -47.67 -
-(#4, #13, #14) - -46.00 - -(#4, #13, #15) - -52.00 - -(#4, #13, #16) - -46.00 - -(#4, #13, #17) - -44.00 -
-(#4, #13, #18) - -44.00 - -(#4, #13, #19) - -52.33 - -(#4, #13, #20) - -44.33 - -(#4, #14, #15) - -53.67 -
-(#4, #14, #16) - -47.67 - -(#4, #14, #17) - -45.67 - -(#4, #14, #18) - -45.67 - -(#4, #14, #19) - -54.00 -
-(#4, #14, #20) - -46.00 - -(#4, #15, #16) - -53.67 - -(#4, #15, #17) - -51.67 - -(#4, #15, #18) - -51.67 -
-(#4, #15, #19) - -60.00 - -(#4, #15, #20) - -52.00 - -(#4, #16, #17) - -45.67 - -(#4, #16, #18) - -45.67 -
-(#4, #16, #19) - -54.00 - -(#4, #16, #20) - -46.00 - -(#4, #17, #18) - -43.67 - -(#4, #17, #19) - -52.00 -
-(#4, #17, #20) - -44.00 - -(#4, #18, #19) - -52.00 - -(#4, #18, #20) - -44.00 - -(#4, #19, #20) - -52.33 -
-(#5, #6, #7) - -36.33 - -(#5, #6, #8) - -36.00 - -(#5, #6, #9) - -37.00 - -(#5, #6, #10) - -42.00 -
-(#5, #6, #11) - -31.33 - -(#5, #6, #12) - -38.33 - -(#5, #6, #13) - -35.00 - -(#5, #6, #14) - -36.67 -
-(#5, #6, #15) - -42.67 - -(#5, #6, #16) - -36.67 - -(#5, #6, #17) - -34.67 - -(#5, #6, #18) - -34.67 -
-(#5, #6, #19) - -43.00 - -(#5, #6, #20) - -35.00 - -(#5, #7, #8) - -35.00 - -(#5, #7, #9) - -36.00 -
-(#5, #7, #10) - -41.00 - -(#5, #7, #11) - -30.33 - -(#5, #7, #12) - -37.33 - -(#5, #7, #13) - -34.00 -
-(#5, #7, #14) - -35.67 - -(#5, #7, #15) - -41.67 - -(#5, #7, #16) - -35.67 - -(#5, #7, #17) - -33.67 -
-(#5, #7, #18) - -33.67 - -(#5, #7, #19) - -42.00 - -(#5, #7, #20) - -34.00 - -(#5, #8, #9) - -35.67 -
-(#5, #8, #10) - -40.67 - -(#5, #8, #11) - -30.00 - -(#5, #8, #12) - -37.00 - -(#5, #8, #13) - -33.67 -
-(#5, #8, #14) - -35.33 - -(#5, #8, #15) - -41.33 - -(#5, #8, #16) - -35.33 - -(#5, #8, #17) - -33.33 -
-(#5, #8, #18) - -33.33 - -(#5, #8, #19) - -41.67 - -(#5, #8, #20) - -33.67 - -(#5, #9, #10) - -41.67 -
-(#5, #9, #11) - -31.00 - -(#5, #9, #12) - -38.00 - -(#5, #9, #13) - -34.67 - -(#5, #9, #14) - -36.33 -
-(#5, #9, #15) - -42.33 - -(#5, #9, #16) - -36.33 - -(#5, #9, #17) - -34.33 - -(#5, #9, #18) - -34.33 -
-(#5, #9, #19) - -42.67 - -(#5, #9, #20) - -34.67 - -(#5, #10, #11) - -36.00 - -(#5, #10, #12) - -43.00 -
-(#5, #10, #13) - -39.67 - -(#5, #10, #14) - -41.33 - -(#5, #10, #15) - -47.33 - -(#5, #10, #16) - -41.33 -
-(#5, #10, #17) - -39.33 - -(#5, #10, #18) - -39.33 - -(#5, #10, #19) - -47.67 - -(#5, #10, #20) - -39.67 -
-(#5, #11, #12) - -32.33 - -(#5, #11, #13) - -29.00 - -(#5, #11, #14) - -30.67 - -(#5, #11, #15) - -36.67 -
-(#5, #11, #16) - -30.67 - -(#5, #11, #17) - -28.67 - -(#5, #11, #18) - -28.67 - -(#5, #11, #19) - -37.00 -
-(#5, #11, #20) - -29.00 - -(#5, #12, #13) - -36.00 - -(#5, #12, #14) - -37.67 - -(#5, #12, #15) - -43.67 -
-(#5, #12, #16) - -37.67 - -(#5, #12, #17) - -35.67 - -(#5, #12, #18) - -35.67 - -(#5, #12, #19) - -44.00 -
-(#5, #12, #20) - -36.00 - -(#5, #13, #14) - -34.33 - -(#5, #13, #15) - -40.33 - -(#5, #13, #16) - -34.33 -
-(#5, #13, #17) - -32.33 - -(#5, #13, #18) - -32.33 - -(#5, #13, #19) - -40.67 - -(#5, #13, #20) - -32.67 -
-(#5, #14, #15) - -42.00 - -(#5, #14, #16) - -36.00 - -(#5, #14, #17) - -34.00 - -(#5, #14, #18) - -34.00 -
-(#5, #14, #19) - -42.33 - -(#5, #14, #20) - -34.33 - -(#5, #15, #16) - -42.00 - -(#5, #15, #17) - -40.00 -
-(#5, #15, #18) - -40.00 - -(#5, #15, #19) - -48.33 - -(#5, #15, #20) - -40.33 - -(#5, #16, #17) - -34.00 -
-(#5, #16, #18) - -34.00 - -(#5, #16, #19) - -42.33 - -(#5, #16, #20) - -34.33 - -(#5, #17, #18) - -32.00 -
-(#5, #17, #19) - -40.33 - -(#5, #17, #20) - -32.33 - -(#5, #18, #19) - -40.33 - -(#5, #18, #20) - -32.33 -
-(#5, #19, #20) - -40.67 - -(#6, #7, #8) - -41.67 - -(#6, #7, #9) - -42.67 - -(#6, #7, #10) - -47.67 -
-(#6, #7, #11) - -37.00 - -(#6, #7, #12) - -44.00 - -(#6, #7, #13) - -40.67 - -(#6, #7, #14) - -42.33 -
-(#6, #7, #15) - -48.33 - -(#6, #7, #16) - -42.33 - -(#6, #7, #17) - -40.33 - -(#6, #7, #18) - -40.33 -
-(#6, #7, #19) - -48.67 - -(#6, #7, #20) - -40.67 - -(#6, #8, #9) - -42.33 - -(#6, #8, #10) - -47.33 -
-(#6, #8, #11) - -36.67 - -(#6, #8, #12) - -43.67 - -(#6, #8, #13) - -40.33 - -(#6, #8, #14) - -42.00 -
-(#6, #8, #15) - -48.00 - -(#6, #8, #16) - -42.00 - -(#6, #8, #17) - -40.00 - -(#6, #8, #18) - -40.00 -
-(#6, #8, #19) - -48.33 - -(#6, #8, #20) - -40.33 - -(#6, #9, #10) - -48.33 - -(#6, #9, #11) - -37.67 -
-(#6, #9, #12) - -44.67 - -(#6, #9, #13) - -41.33 - -(#6, #9, #14) - -43.00 - -(#6, #9, #15) - -49.00 -
-(#6, #9, #16) - -43.00 - -(#6, #9, #17) - -41.00 - -(#6, #9, #18) - -41.00 - -(#6, #9, #19) - -49.33 -
-(#6, #9, #20) - -41.33 - -(#6, #10, #11) - -42.67 - -(#6, #10, #12) - -49.67 - -(#6, #10, #13) - -46.33 -
-(#6, #10, #14) - -48.00 - -(#6, #10, #15) - -54.00 - -(#6, #10, #16) - -48.00 - -(#6, #10, #17) - -46.00 -
-(#6, #10, #18) - -46.00 - -(#6, #10, #19) - -54.33 - -(#6, #10, #20) - -46.33 - -(#6, #11, #12) - -39.00 -
-(#6, #11, #13) - -35.67 - -(#6, #11, #14) - -37.33 - -(#6, #11, #15) - -43.33 - -(#6, #11, #16) - -37.33 -
-(#6, #11, #17) - -35.33 - -(#6, #11, #18) - -35.33 - -(#6, #11, #19) - -43.67 - -(#6, #11, #20) - -35.67 -
-(#6, #12, #13) - -42.67 - -(#6, #12, #14) - -44.33 - -(#6, #12, #15) - -50.33 - -(#6, #12, #16) - -44.33 -
-(#6, #12, #17) - -42.33 - -(#6, #12, #18) - -42.33 - -(#6, #12, #19) - -50.67 - -(#6, #12, #20) - -42.67 -
-(#6, #13, #14) - -41.00 - -(#6, #13, #15) - -47.00 - -(#6, #13, #16) - -41.00 - -(#6, #13, #17) - -39.00 -
-(#6, #13, #18) - -39.00 - -(#6, #13, #19) - -47.33 - -(#6, #13, #20) - -39.33 - -(#6, #14, #15) - -48.67 -
-(#6, #14, #16) - -42.67 - -(#6, #14, #17) - -40.67 - -(#6, #14, #18) - -40.67 - -(#6, #14, #19) - -49.00 -
-(#6, #14, #20) - -41.00 - -(#6, #15, #16) - -48.67 - -(#6, #15, #17) - -46.67 - -(#6, #15, #18) - -46.67 -
-(#6, #15, #19) - -55.00 - -(#6, #15, #20) - -47.00 - -(#6, #16, #17) - -40.67 - -(#6, #16, #18) - -40.67 -
-(#6, #16, #19) - -49.00 - -(#6, #16, #20) - -41.00 - -(#6, #17, #18) - -38.67 - -(#6, #17, #19) - -47.00 -
-(#6, #17, #20) - -39.00 - -(#6, #18, #19) - -47.00 - -(#6, #18, #20) - -39.00 - -(#6, #19, #20) - -47.33 -
-(#7, #8, #9) - -41.33 - -(#7, #8, #10) - -46.33 - -(#7, #8, #11) - -35.67 - -(#7, #8, #12) - -42.67 -
-(#7, #8, #13) - -39.33 - -(#7, #8, #14) - -41.00 - -(#7, #8, #15) - -47.00 - -(#7, #8, #16) - -41.00 -
-(#7, #8, #17) - -39.00 - -(#7, #8, #18) - -39.00 - -(#7, #8, #19) - -47.33 - -(#7, #8, #20) - -39.33 -
-(#7, #9, #10) - -47.33 - -(#7, #9, #11) - -36.67 - -(#7, #9, #12) - -43.67 - -(#7, #9, #13) - -40.33 -
-(#7, #9, #14) - -42.00 - -(#7, #9, #15) - -48.00 - -(#7, #9, #16) - -42.00 - -(#7, #9, #17) - -40.00 -
-(#7, #9, #18) - -40.00 - -(#7, #9, #19) - -48.33 - -(#7, #9, #20) - -40.33 - -(#7, #10, #11) - -41.67 -
-(#7, #10, #12) - -48.67 - -(#7, #10, #13) - -45.33 - -(#7, #10, #14) - -47.00 - -(#7, #10, #15) - -53.00 -
-(#7, #10, #16) - -47.00 - -(#7, #10, #17) - -45.00 - -(#7, #10, #18) - -45.00 - -(#7, #10, #19) - -53.33 -
-(#7, #10, #20) - -45.33 - -(#7, #11, #12) - -38.00 - -(#7, #11, #13) - -34.67 - -(#7, #11, #14) - -36.33 -
-(#7, #11, #15) - -42.33 - -(#7, #11, #16) - -36.33 - -(#7, #11, #17) - -34.33 - -(#7, #11, #18) - -34.33 -
-(#7, #11, #19) - -42.67 - -(#7, #11, #20) - -34.67 - -(#7, #12, #13) - -41.67 - -(#7, #12, #14) - -43.33 -
-(#7, #12, #15) - -49.33 - -(#7, #12, #16) - -43.33 - -(#7, #12, #17) - -41.33 - -(#7, #12, #18) - -41.33 -
-(#7, #12, #19) - -49.67 - -(#7, #12, #20) - -41.67 - -(#7, #13, #14) - -40.00 - -(#7, #13, #15) - -46.00 -
-(#7, #13, #16) - -40.00 - -(#7, #13, #17) - -38.00 - -(#7, #13, #18) - -38.00 - -(#7, #13, #19) - -46.33 -
-(#7, #13, #20) - -38.33 - -(#7, #14, #15) - -47.67 - -(#7, #14, #16) - -41.67 - -(#7, #14, #17) - -39.67 -
-(#7, #14, #18) - -39.67 - -(#7, #14, #19) - -48.00 - -(#7, #14, #20) - -40.00 - -(#7, #15, #16) - -47.67 -
-(#7, #15, #17) - -45.67 - -(#7, #15, #18) - -45.67 - -(#7, #15, #19) - -54.00 - -(#7, #15, #20) - -46.00 -
-(#7, #16, #17) - -39.67 - -(#7, #16, #18) - -39.67 - -(#7, #16, #19) - -48.00 - -(#7, #16, #20) - -40.00 -
-(#7, #17, #18) - -37.67 - -(#7, #17, #19) - -46.00 - -(#7, #17, #20) - -38.00 - -(#7, #18, #19) - -46.00 -
-(#7, #18, #20) - -38.00 - -(#7, #19, #20) - -46.33 - -(#8, #9, #10) - -47.00 - -(#8, #9, #11) - -36.33 -
-(#8, #9, #12) - -43.33 - -(#8, #9, #13) - -40.00 - -(#8, #9, #14) - -41.67 - -(#8, #9, #15) - -47.67 -
-(#8, #9, #16) - -41.67 - -(#8, #9, #17) - -39.67 - -(#8, #9, #18) - -39.67 - -(#8, #9, #19) - -48.00 -
-(#8, #9, #20) - -40.00 - -(#8, #10, #11) - -41.33 - -(#8, #10, #12) - -48.33 - -(#8, #10, #13) - -45.00 -
-(#8, #10, #14) - -46.67 - -(#8, #10, #15) - -52.67 - -(#8, #10, #16) - -46.67 - -(#8, #10, #17) - -44.67 -
-(#8, #10, #18) - -44.67 - -(#8, #10, #19) - -53.00 - -(#8, #10, #20) - -45.00 - -(#8, #11, #12) - -37.67 -
-(#8, #11, #13) - -34.33 - -(#8, #11, #14) - -36.00 - -(#8, #11, #15) - -42.00 - -(#8, #11, #16) - -36.00 -
-(#8, #11, #17) - -34.00 - -(#8, #11, #18) - -34.00 - -(#8, #11, #19) - -42.33 - -(#8, #11, #20) - -34.33 -
-(#8, #12, #13) - -41.33 - -(#8, #12, #14) - -43.00 - -(#8, #12, #15) - -49.00 - -(#8, #12, #16) - -43.00 -
-(#8, #12, #17) - -41.00 - -(#8, #12, #18) - -41.00 - -(#8, #12, #19) - -49.33 - -(#8, #12, #20) - -41.33 -
-(#8, #13, #14) - -39.67 - -(#8, #13, #15) - -45.67 - -(#8, #13, #16) - -39.67 - -(#8, #13, #17) - -37.67 -
-(#8, #13, #18) - -37.67 - -(#8, #13, #19) - -46.00 - -(#8, #13, #20) - -38.00 - -(#8, #14, #15) - -47.33 -
-(#8, #14, #16) - -41.33 - -(#8, #14, #17) - -39.33 - -(#8, #14, #18) - -39.33 - -(#8, #14, #19) - -47.67 -
-(#8, #14, #20) - -39.67 - -(#8, #15, #16) - -47.33 - -(#8, #15, #17) - -45.33 - -(#8, #15, #18) - -45.33 -
-(#8, #15, #19) - -53.67 - -(#8, #15, #20) - -45.67 - -(#8, #16, #17) - -39.33 - -(#8, #16, #18) - -39.33 -
-(#8, #16, #19) - -47.67 - -(#8, #16, #20) - -39.67 - -(#8, #17, #18) - -37.33 - -(#8, #17, #19) - -45.67 -
-(#8, #17, #20) - -37.67 - -(#8, #18, #19) - -45.67 - -(#8, #18, #20) - -37.67 - -(#8, #19, #20) - -46.00 -
-(#9, #10, #11) - -42.33 - -(#9, #10, #12) - -49.33 - -(#9, #10, #13) - -46.00 - -(#9, #10, #14) - -47.67 -
-(#9, #10, #15) - -53.67 - -(#9, #10, #16) - -47.67 - -(#9, #10, #17) - -45.67 - -(#9, #10, #18) - -45.67 -
-(#9, #10, #19) - -54.00 - -(#9, #10, #20) - -46.00 - -(#9, #11, #12) - -38.67 - -(#9, #11, #13) - -35.33 -
-(#9, #11, #14) - -37.00 - -(#9, #11, #15) - -43.00 - -(#9, #11, #16) - -37.00 - -(#9, #11, #17) - -35.00 -
-(#9, #11, #18) - -35.00 - -(#9, #11, #19) - -43.33 - -(#9, #11, #20) - -35.33 - -(#9, #12, #13) - -42.33 -
-(#9, #12, #14) - -44.00 - -(#9, #12, #15) - -50.00 - -(#9, #12, #16) - -44.00 - -(#9, #12, #17) - -42.00 -
-(#9, #12, #18) - -42.00 - -(#9, #12, #19) - -50.33 - -(#9, #12, #20) - -42.33 - -(#9, #13, #14) - -40.67 -
-(#9, #13, #15) - -46.67 - -(#9, #13, #16) - -40.67 - -(#9, #13, #17) - -38.67 - -(#9, #13, #18) - -38.67 -
-(#9, #13, #19) - -47.00 - -(#9, #13, #20) - -39.00 - -(#9, #14, #15) - -48.33 - -(#9, #14, #16) - -42.33 -
-(#9, #14, #17) - -40.33 - -(#9, #14, #18) - -40.33 - -(#9, #14, #19) - -48.67 - -(#9, #14, #20) - -40.67 -
-(#9, #15, #16) - -48.33 - -(#9, #15, #17) - -46.33 - -(#9, #15, #18) - -46.33 - -(#9, #15, #19) - -54.67 -
-(#9, #15, #20) - -46.67 - -(#9, #16, #17) - -40.33 - -(#9, #16, #18) - -40.33 - -(#9, #16, #19) - -48.67 -
-(#9, #16, #20) - -40.67 - -(#9, #17, #18) - -38.33 - -(#9, #17, #19) - -46.67 - -(#9, #17, #20) - -38.67 -
-(#9, #18, #19) - -46.67 - -(#9, #18, #20) - -38.67 - -(#9, #19, #20) - -47.00 - -(#10, #11, #12) - -43.67 -
-(#10, #11, #13) - -40.33 - -(#10, #11, #14) - -42.00 - -(#10, #11, #15) - -48.00 - -(#10, #11, #16) - -42.00 -
-(#10, #11, #17) - -40.00 - -(#10, #11, #18) - -40.00 - -(#10, #11, #19) - -48.33 - -(#10, #11, #20) - -40.33 -
-(#10, #12, #13) - -47.33 - -(#10, #12, #14) - -49.00 - -(#10, #12, #15) - -55.00 - -(#10, #12, #16) - -49.00 -
-(#10, #12, #17) - -47.00 - -(#10, #12, #18) - -47.00 - -(#10, #12, #19) - -55.33 - -(#10, #12, #20) - -47.33 -
-(#10, #13, #14) - -45.67 - -(#10, #13, #15) - -51.67 - -(#10, #13, #16) - -45.67 - -(#10, #13, #17) - -43.67 -
-(#10, #13, #18) - -43.67 - -(#10, #13, #19) - -52.00 - -(#10, #13, #20) - -44.00 - -(#10, #14, #15) - -53.33 -
-(#10, #14, #16) - -47.33 - -(#10, #14, #17) - -45.33 - -(#10, #14, #18) - -45.33 - -(#10, #14, #19) - -53.67 -
-(#10, #14, #20) - -45.67 - -(#10, #15, #16) - -53.33 - -(#10, #15, #17) - -51.33 - -(#10, #15, #18) - -51.33 -
-(#10, #15, #19) - -59.67 - -(#10, #15, #20) - -51.67 - -(#10, #16, #17) - -45.33 - -(#10, #16, #18) - -45.33 -
-(#10, #16, #19) - -53.67 - -(#10, #16, #20) - -45.67 - -(#10, #17, #18) - -43.33 - -(#10, #17, #19) - -51.67 -
-(#10, #17, #20) - -43.67 - -(#10, #18, #19) - -51.67 - -(#10, #18, #20) - -43.67 - -(#10, #19, #20) - -52.00 -
-(#11, #12, #13) - -36.67 - -(#11, #12, #14) - -38.33 - -(#11, #12, #15) - -44.33 - -(#11, #12, #16) - -38.33 -
-(#11, #12, #17) - -36.33 - -(#11, #12, #18) - -36.33 - -(#11, #12, #19) - -44.67 - -(#11, #12, #20) - -36.67 -
-(#11, #13, #14) - -35.00 - -(#11, #13, #15) - -41.00 - -(#11, #13, #16) - -35.00 - -(#11, #13, #17) - -33.00 -
-(#11, #13, #18) - -33.00 - -(#11, #13, #19) - -41.33 - -(#11, #13, #20) - -33.33 - -(#11, #14, #15) - -42.67 -
-(#11, #14, #16) - -36.67 - -(#11, #14, #17) - -34.67 - -(#11, #14, #18) - -34.67 - -(#11, #14, #19) - -43.00 -
-(#11, #14, #20) - -35.00 - -(#11, #15, #16) - -42.67 - -(#11, #15, #17) - -40.67 - -(#11, #15, #18) - -40.67 -
-(#11, #15, #19) - -49.00 - -(#11, #15, #20) - -41.00 - -(#11, #16, #17) - -34.67 - -(#11, #16, #18) - -34.67 -
-(#11, #16, #19) - -43.00 - -(#11, #16, #20) - -35.00 - -(#11, #17, #18) - -32.67 - -(#11, #17, #19) - -41.00 -
-(#11, #17, #20) - -33.00 - -(#11, #18, #19) - -41.00 - -(#11, #18, #20) - -33.00 - -(#11, #19, #20) - -41.33 -
-(#12, #13, #14) - -42.00 - -(#12, #13, #15) - -48.00 - -(#12, #13, #16) - -42.00 - -(#12, #13, #17) - -40.00 -
-(#12, #13, #18) - -40.00 - -(#12, #13, #19) - -48.33 - -(#12, #13, #20) - -40.33 - -(#12, #14, #15) - -49.67 -
-(#12, #14, #16) - -43.67 - -(#12, #14, #17) - -41.67 - -(#12, #14, #18) - -41.67 - -(#12, #14, #19) - -50.00 -
-(#12, #14, #20) - -42.00 - -(#12, #15, #16) - -49.67 - -(#12, #15, #17) - -47.67 - -(#12, #15, #18) - -47.67 -
-(#12, #15, #19) - -56.00 - -(#12, #15, #20) - -48.00 - -(#12, #16, #17) - -41.67 - -(#12, #16, #18) - -41.67 -
-(#12, #16, #19) - -50.00 - -(#12, #16, #20) - -42.00 - -(#12, #17, #18) - -39.67 - -(#12, #17, #19) - -48.00 -
-(#12, #17, #20) - -40.00 - -(#12, #18, #19) - -48.00 - -(#12, #18, #20) - -40.00 - -(#12, #19, #20) - -48.33 -
-(#13, #14, #15) - -46.33 - -(#13, #14, #16) - -40.33 - -(#13, #14, #17) - -38.33 - -(#13, #14, #18) - -38.33 -
-(#13, #14, #19) - -46.67 - -(#13, #14, #20) - -38.67 - -(#13, #15, #16) - -46.33 - -(#13, #15, #17) - -44.33 -
-(#13, #15, #18) - -44.33 - -(#13, #15, #19) - -52.67 - -(#13, #15, #20) - -44.67 - -(#13, #16, #17) - -38.33 -
-(#13, #16, #18) - -38.33 - -(#13, #16, #19) - -46.67 - -(#13, #16, #20) - -38.67 - -(#13, #17, #18) - -36.33 -
-(#13, #17, #19) - -44.67 - -(#13, #17, #20) - -36.67 - -(#13, #18, #19) - -44.67 - -(#13, #18, #20) - -36.67 -
-(#13, #19, #20) - -45.00 - -(#14, #15, #16) - -48.00 - -(#14, #15, #17) - -46.00 - -(#14, #15, #18) - -46.00 -
-(#14, #15, #19) - -54.33 - -(#14, #15, #20) - -46.33 - -(#14, #16, #17) - -40.00 - -(#14, #16, #18) - -40.00 -
-(#14, #16, #19) - -48.33 - -(#14, #16, #20) - -40.33 - -(#14, #17, #18) - -38.00 - -(#14, #17, #19) - -46.33 -
-(#14, #17, #20) - -38.33 - -(#14, #18, #19) - -46.33 - -(#14, #18, #20) - -38.33 - -(#14, #19, #20) - -46.67 -
-(#15, #16, #17) - -46.00 - -(#15, #16, #18) - -46.00 - -(#15, #16, #19) - -54.33 - -(#15, #16, #20) - -46.33 -
-(#15, #17, #18) - -44.00 - -(#15, #17, #19) - -52.33 - -(#15, #17, #20) - -44.33 - -(#15, #18, #19) - -52.33 -
-(#15, #18, #20) - -44.33 - -(#15, #19, #20) - -52.67 - -(#16, #17, #18) - -38.00 - -(#16, #17, #19) - -46.33 -
-(#16, #17, #20) - -38.33 - -(#16, #18, #19) - -46.33 - -(#16, #18, #20) - -38.33 - -(#16, #19, #20) - -46.67 -
-(#17, #18, #19) - -44.33 - -(#17, #18, #20) - -36.33 - -(#17, #19, #20) - -44.67 - -(#18, #19, #20) - -44.67 -
-
- - -
-Figure 1: Sampling distribution of the sample average of weight (dkg) for samples of size 3 fish from the aquarium. -
-
- -
-
    -
  • Exercise: If you take a sample at random, what would be the probability that the mean of your sample is fairly close to the true mean, say between 40 and 46?

  • -
  • Exercise: True or False: Each time we take a random sample we will have a different sampling distribution.

  • -
-
-
-
-

Sampling Distribution

-

The sampling distribution of a statistic, like \(\overline{y}\) and \(\hat{p}\), is the distribution of the value of the statistic across all possible random samples of size \(n\) that could be selected from a given population.

-
-
-

Sampling Distribution

-
    -
  • Some key questions: -
      -
    • What is the centre of the sampling distribution?
    • -
    • How spread is the sampling distribution?
    • -
    • What is the shape of the sampling distribution?
    • -
  • -
-
-
-

Sampling Distribution

-
    -
  • As you can see, the sampling distribution tells us a lot about our statistic. -
      -
    • We could, for example, calculate the probability that our statistic would be to a certain range around the parameter.
    • -
  • -
-
-
-

Sampling Distribution

-
    -
  • But how is this useful if we need to have access to all possible samples? -
      -
    • In this case, we would be better off just checking out the entire population.
    • -
  • -
-
-
-

Sampling Distribution

-
    -
  • Luckily, we do not need to have access to all possible samples to know the sampling distribution.

  • -
  • All we need is a sample! The same sample you use to calculate the statistic will also give you information on the uncertainty of your estimate.

  • -
-
- -
-
-
-

Sampling distribution of \(\overline{Y}\)

-
-

This Applet was developed by Mike Whitlock.

-
- -
-
    -
  • Exercise: Using the applet above, study what happens to the spread of the sampling distribution when the sample size increases.
  • -
-
-
-
-

References

- -
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/lecs-quarto/lecture01_files/libs/clipboard/clipboard.min.js b/docs/lecs-quarto/lecture01_files/libs/clipboard/clipboard.min.js deleted file mode 100644 index 1103f81..0000000 --- a/docs/lecs-quarto/lecture01_files/libs/clipboard/clipboard.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * clipboard.js v2.0.11 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light-border]>.tippy-arrow:after,.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=light-border]>.tippy-arrow:after{border-color:transparent;border-style:solid}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:after{border-top-color:rgba(0,8,16,.2);border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:rgba(0,8,16,.2);border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:after{border-left-color:rgba(0,8,16,.2);border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:rgba(0,8,16,.2)}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow{fill:#fff}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px} \ No newline at end of file diff --git a/docs/lecs-quarto/lecture01_files/libs/quarto-html/popper.min.js b/docs/lecs-quarto/lecture01_files/libs/quarto-html/popper.min.js deleted file mode 100644 index e3726d7..0000000 --- a/docs/lecs-quarto/lecture01_files/libs/quarto-html/popper.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @popperjs/core v2.11.7 - MIT License - */ - -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(){var e=navigator.userAgentData;return null!=e&&e.brands&&Array.isArray(e.brands)?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function c(){return!/^((?!chrome|android).)*safari/i.test(f())}function p(e,o,i){void 0===o&&(o=!1),void 0===i&&(i=!1);var a=e.getBoundingClientRect(),f=1,p=1;o&&r(e)&&(f=e.offsetWidth>0&&s(a.width)/e.offsetWidth||1,p=e.offsetHeight>0&&s(a.height)/e.offsetHeight||1);var u=(n(e)?t(e):window).visualViewport,l=!c()&&i,d=(a.left+(l&&u?u.offsetLeft:0))/f,h=(a.top+(l&&u?u.offsetTop:0))/p,m=a.width/f,v=a.height/p;return{width:m,height:v,top:h,right:d+m,bottom:h+v,left:d,x:d,y:h}}function u(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function l(e){return e?(e.nodeName||"").toLowerCase():null}function d(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function h(e){return p(d(e)).left+u(e).scrollLeft}function m(e){return t(e).getComputedStyle(e)}function v(e){var t=m(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function y(e,n,o){void 0===o&&(o=!1);var i,a,f=r(n),c=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),m=d(n),y=p(e,c,o),g={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(f||!f&&!o)&&(("body"!==l(n)||v(m))&&(g=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:u(i)),r(n)?((b=p(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):m&&(b.x=h(m))),{x:y.left+g.scrollLeft-b.x,y:y.top+g.scrollTop-b.y,width:y.width,height:y.height}}function g(e){var t=p(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function b(e){return"html"===l(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||d(e)}function x(e){return["html","body","#document"].indexOf(l(e))>=0?e.ownerDocument.body:r(e)&&v(e)?e:x(b(e))}function w(e,n){var r;void 0===n&&(n=[]);var o=x(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],v(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(w(b(s)))}function O(e){return["table","td","th"].indexOf(l(e))>=0}function j(e){return r(e)&&"fixed"!==m(e).position?e.offsetParent:null}function E(e){for(var n=t(e),i=j(e);i&&O(i)&&"static"===m(i).position;)i=j(i);return i&&("html"===l(i)||"body"===l(i)&&"static"===m(i).position)?n:i||function(e){var t=/firefox/i.test(f());if(/Trident/i.test(f())&&r(e)&&"fixed"===m(e).position)return null;var n=b(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(l(n))<0;){var i=m(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var D="top",A="bottom",L="right",P="left",M="auto",k=[D,A,L,P],W="start",B="end",H="viewport",T="popper",R=k.reduce((function(e,t){return e.concat([t+"-"+W,t+"-"+B])}),[]),S=[].concat(k,[M]).reduce((function(e,t){return e.concat([t,t+"-"+W,t+"-"+B])}),[]),V=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function q(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function N(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function I(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function _(e,r,o){return r===H?I(function(e,n){var r=t(e),o=d(e),i=r.visualViewport,a=o.clientWidth,s=o.clientHeight,f=0,p=0;if(i){a=i.width,s=i.height;var u=c();(u||!u&&"fixed"===n)&&(f=i.offsetLeft,p=i.offsetTop)}return{width:a,height:s,x:f+h(e),y:p}}(e,o)):n(r)?function(e,t){var n=p(e,!1,"fixed"===t);return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}(r,o):I(function(e){var t,n=d(e),r=u(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+h(e),c=-r.scrollTop;return"rtl"===m(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:c}}(d(e)))}function F(e,t,o,s){var f="clippingParents"===t?function(e){var t=w(b(e)),o=["absolute","fixed"].indexOf(m(e).position)>=0&&r(e)?E(e):e;return n(o)?t.filter((function(e){return n(e)&&N(e,o)&&"body"!==l(e)})):[]}(e):[].concat(t),c=[].concat(f,[o]),p=c[0],u=c.reduce((function(t,n){var r=_(e,n,s);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),_(e,p,s));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function U(e){return e.split("-")[1]}function z(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function X(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?U(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case D:t={x:s,y:n.y-r.height};break;case A:t={x:s,y:n.y+n.height};break;case L:t={x:n.x+n.width,y:f};break;case P:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?z(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case W:t[c]=t[c]-(n[p]/2-r[p]/2);break;case B:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function Y(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function G(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function J(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.strategy,s=void 0===a?e.strategy:a,f=r.boundary,c=void 0===f?"clippingParents":f,u=r.rootBoundary,l=void 0===u?H:u,h=r.elementContext,m=void 0===h?T:h,v=r.altBoundary,y=void 0!==v&&v,g=r.padding,b=void 0===g?0:g,x=Y("number"!=typeof b?b:G(b,k)),w=m===T?"reference":T,O=e.rects.popper,j=e.elements[y?w:m],E=F(n(j)?j:j.contextElement||d(e.elements.popper),c,l,s),P=p(e.elements.reference),M=X({reference:P,element:O,strategy:"absolute",placement:i}),W=I(Object.assign({},O,M)),B=m===T?W:P,R={top:E.top-B.top+x.top,bottom:B.bottom-E.bottom+x.bottom,left:E.left-B.left+x.left,right:B.right-E.right+x.right},S=e.modifiersData.offset;if(m===T&&S){var V=S[i];Object.keys(R).forEach((function(e){var t=[L,A].indexOf(e)>=0?1:-1,n=[D,A].indexOf(e)>=0?"y":"x";R[e]+=V[n]*t}))}return R}var K={placement:"bottom",modifiers:[],strategy:"absolute"};function Q(){for(var e=arguments.length,t=new Array(e),n=0;n=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[P,L].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},se={left:"right",right:"left",bottom:"top",top:"bottom"};function fe(e){return e.replace(/left|right|bottom|top/g,(function(e){return se[e]}))}var ce={start:"end",end:"start"};function pe(e){return e.replace(/start|end/g,(function(e){return ce[e]}))}function ue(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?S:f,p=U(r),u=p?s?R:R.filter((function(e){return U(e)===p})):k,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=J(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var le={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,y=C(v),g=f||(y===v||!h?[fe(v)]:function(e){if(C(e)===M)return[];var t=fe(e);return[pe(e),t,pe(t)]}(v)),b=[v].concat(g).reduce((function(e,n){return e.concat(C(n)===M?ue(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,j=!0,E=b[0],k=0;k=0,S=R?"width":"height",V=J(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),q=R?T?L:P:T?A:D;x[S]>w[S]&&(q=fe(q));var N=fe(q),I=[];if(i&&I.push(V[H]<=0),s&&I.push(V[q]<=0,V[N]<=0),I.every((function(e){return e}))){E=B,j=!1;break}O.set(B,I)}if(j)for(var _=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return E=t,"break"},F=h?3:1;F>0;F--){if("break"===_(F))break}t.placement!==E&&(t.modifiersData[r]._skip=!0,t.placement=E,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function de(e,t,n){return i(e,a(t,n))}var he={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,v=n.tetherOffset,y=void 0===v?0:v,b=J(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=U(t.placement),O=!w,j=z(x),M="x"===j?"y":"x",k=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,V={x:0,y:0};if(k){if(s){var q,N="y"===j?D:P,I="y"===j?A:L,_="y"===j?"height":"width",F=k[j],X=F+b[N],Y=F-b[I],G=m?-H[_]/2:0,K=w===W?B[_]:H[_],Q=w===W?-H[_]:-B[_],Z=t.elements.arrow,$=m&&Z?g(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=de(0,B[_],$[_]),oe=O?B[_]/2-G-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=O?-B[_]/2+G+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&E(t.elements.arrow),se=ae?"y"===j?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(q=null==S?void 0:S[j])?q:0,ce=F+ie-fe,pe=de(m?a(X,F+oe-fe-se):X,F,m?i(Y,ce):Y);k[j]=pe,V[j]=pe-F}if(c){var ue,le="x"===j?D:P,he="x"===j?A:L,me=k[M],ve="y"===M?"height":"width",ye=me+b[le],ge=me-b[he],be=-1!==[D,P].indexOf(x),xe=null!=(ue=null==S?void 0:S[M])?ue:0,we=be?ye:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ge,je=m&&be?function(e,t,n){var r=de(e,t,n);return r>n?n:r}(we,me,Oe):de(m?we:ye,me,m?Oe:ge);k[M]=je,V[M]=je-me}t.modifiersData[r]=V}},requiresIfExists:["offset"]};var me={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=z(s),c=[P,L].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return Y("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:G(e,k))}(o.padding,n),u=g(i),l="y"===f?D:P,d="y"===f?A:L,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],v=E(i),y=v?"y"===f?v.clientHeight||0:v.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],O=y/2-u[c]/2+b,j=de(x,O,w),M=f;n.modifiersData[r]=((t={})[M]=j,t.centerOffset=j-O,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&N(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ve(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function ye(e){return[D,L,A,P].some((function(t){return e[t]>=0}))}var ge={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=J(t,{elementContext:"reference"}),s=J(t,{altBoundary:!0}),f=ve(a,r),c=ve(s,o,i),p=ye(f),u=ye(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},be=Z({defaultModifiers:[ee,te,oe,ie]}),xe=[ee,te,oe,ie,ae,le,he,me,ge],we=Z({defaultModifiers:xe});e.applyStyles=ie,e.arrow=me,e.computeStyles=oe,e.createPopper=we,e.createPopperLite=be,e.defaultModifiers=xe,e.detectOverflow=J,e.eventListeners=ee,e.flip=le,e.hide=ge,e.offset=ae,e.popperGenerator=Z,e.popperOffsets=te,e.preventOverflow=he,Object.defineProperty(e,"__esModule",{value:!0})})); - diff --git a/docs/lecs-quarto/lecture01_files/libs/quarto-html/quarto-html.min.css b/docs/lecs-quarto/lecture01_files/libs/quarto-html/quarto-html.min.css deleted file mode 100644 index 8b13789..0000000 --- a/docs/lecs-quarto/lecture01_files/libs/quarto-html/quarto-html.min.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/lecs-quarto/lecture01_files/libs/quarto-html/quarto-syntax-highlighting.css b/docs/lecs-quarto/lecture01_files/libs/quarto-html/quarto-syntax-highlighting.css deleted file mode 100644 index b30ce57..0000000 --- a/docs/lecs-quarto/lecture01_files/libs/quarto-html/quarto-syntax-highlighting.css +++ /dev/null @@ -1,205 +0,0 @@ -/* quarto syntax highlight colors */ -:root { - --quarto-hl-ot-color: #003B4F; - --quarto-hl-at-color: #657422; - --quarto-hl-ss-color: #20794D; - --quarto-hl-an-color: #5E5E5E; - --quarto-hl-fu-color: #4758AB; - --quarto-hl-st-color: #20794D; - --quarto-hl-cf-color: #003B4F; - --quarto-hl-op-color: #5E5E5E; - --quarto-hl-er-color: #AD0000; - --quarto-hl-bn-color: #AD0000; - --quarto-hl-al-color: #AD0000; - --quarto-hl-va-color: #111111; - --quarto-hl-bu-color: inherit; - --quarto-hl-ex-color: inherit; - --quarto-hl-pp-color: #AD0000; - --quarto-hl-in-color: #5E5E5E; - --quarto-hl-vs-color: #20794D; - --quarto-hl-wa-color: #5E5E5E; - --quarto-hl-do-color: #5E5E5E; - --quarto-hl-im-color: #00769E; - --quarto-hl-ch-color: #20794D; - --quarto-hl-dt-color: #AD0000; - --quarto-hl-fl-color: #AD0000; - --quarto-hl-co-color: #5E5E5E; - --quarto-hl-cv-color: #5E5E5E; - --quarto-hl-cn-color: #8f5902; - --quarto-hl-sc-color: #5E5E5E; - --quarto-hl-dv-color: #AD0000; - --quarto-hl-kw-color: #003B4F; -} - -/* other quarto variables */ -:root { - --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; -} - -pre > code.sourceCode > span { - color: #003B4F; -} - -code span { - color: #003B4F; -} - -code.sourceCode > span { - color: #003B4F; -} - -div.sourceCode, -div.sourceCode pre.sourceCode { - color: #003B4F; -} - -code span.ot { - color: #003B4F; - font-style: inherit; -} - -code span.at { - color: #657422; - font-style: inherit; -} - -code span.ss { - color: #20794D; - font-style: inherit; -} - -code span.an { - color: #5E5E5E; - font-style: inherit; -} - -code span.fu { - color: #4758AB; - font-style: inherit; -} - -code span.st { - color: #20794D; - font-style: inherit; -} - -code span.cf { - color: #003B4F; - font-weight: bold; - font-style: inherit; -} - -code span.op { - color: #5E5E5E; - font-style: inherit; -} - -code span.er { - color: #AD0000; - font-style: inherit; -} - -code span.bn { - color: #AD0000; - font-style: inherit; -} - -code span.al { - color: #AD0000; - font-style: inherit; -} - -code span.va { - color: #111111; - font-style: inherit; -} - -code span.bu { - font-style: inherit; -} - -code span.ex { - font-style: inherit; -} - -code span.pp { - color: #AD0000; - font-style: inherit; -} - -code span.in { - color: #5E5E5E; - font-style: inherit; -} - -code span.vs { - color: #20794D; - font-style: inherit; -} - -code span.wa { - color: #5E5E5E; - font-style: italic; -} - -code span.do { - color: #5E5E5E; - font-style: italic; -} - -code span.im { - color: #00769E; - font-style: inherit; -} - -code span.ch { - color: #20794D; - font-style: inherit; -} - -code span.dt { - color: #AD0000; - font-style: inherit; -} - -code span.fl { - color: #AD0000; - font-style: inherit; -} - -code span.co { - color: #5E5E5E; - font-style: inherit; -} - -code span.cv { - color: #5E5E5E; - font-style: italic; -} - -code span.cn { - color: #8f5902; - font-style: inherit; -} - -code span.sc { - color: #5E5E5E; - font-style: inherit; -} - -code span.dv { - color: #AD0000; - font-style: inherit; -} - -code span.kw { - color: #003B4F; - font-weight: bold; - font-style: inherit; -} - -.prevent-inlining { - content: " !el.hasAttribute("disabled") && !el.getAttribute("aria-hidden") - ); - }; - - /** - * Remove roles and attributes from a tab and its content - * @param {Node} tab The tab - * @param {Node} content The tab content - * @param {Object} settings User settings and options - */ - var destroyTab = function (tab, content, settings) { - // Remove the generated ID - if (tab.id.slice(0, settings.idPrefix.length) === settings.idPrefix) { - tab.id = ""; - } - - // remove event listener - tab.removeEventListener("focus", focusHandler, true); - - // Remove roles - tab.removeAttribute("role"); - tab.removeAttribute("aria-controls"); - tab.removeAttribute("aria-selected"); - tab.removeAttribute("tabindex"); - tab.closest("li").removeAttribute("role"); - content.removeAttribute("role"); - content.removeAttribute("aria-labelledby"); - content.removeAttribute("hidden"); - }; - - /** - * Add the required roles and attributes to a tab and its content - * @param {Node} tab The tab - * @param {Node} content The tab content - * @param {Object} settings User settings and options - */ - var setupTab = function (tab, content, settings) { - // Give tab an ID if it doesn't already have one - if (!tab.id) { - tab.id = settings.idPrefix + content.id; - } - - // Add roles - tab.setAttribute("role", "tab"); - tab.setAttribute("aria-controls", content.id); - tab.closest("li").setAttribute("role", "presentation"); - content.setAttribute("role", "tabpanel"); - content.setAttribute("aria-labelledby", tab.id); - - // Add selected state - if (tab.matches(settings.default)) { - tab.setAttribute("aria-selected", "true"); - } else { - tab.setAttribute("aria-selected", "false"); - content.setAttribute("hidden", "hidden"); - } - - // add focus event listender - tab.addEventListener("focus", focusHandler); - }; - - /** - * Hide a tab and its content - * @param {Node} newTab The new tab that's replacing it - */ - var hide = function (newTab) { - // Variables - var tabGroup = newTab.closest('[role="tablist"]'); - if (!tabGroup) return {}; - var tab = tabGroup.querySelector('[role="tab"][aria-selected="true"]'); - if (!tab) return {}; - var content = document.querySelector(tab.hash); - - // Hide the tab - tab.setAttribute("aria-selected", "false"); - - // Hide the content - if (!content) return { previousTab: tab }; - content.setAttribute("hidden", "hidden"); - - // Return the hidden tab and content - return { - previousTab: tab, - previousContent: content, - }; - }; - - /** - * Show a tab and its content - * @param {Node} tab The tab - * @param {Node} content The tab content - */ - var show = function (tab, content) { - tab.setAttribute("aria-selected", "true"); - content.removeAttribute("hidden"); - tab.focus(); - }; - - /** - * Toggle a new tab - * @param {Node} tab The tab to show - */ - var toggle = function (tab) { - // Make sure there's a tab to toggle and it's not already active - if (!tab || tab.getAttribute("aria-selected") == "true") return; - - // Variables - var content = document.querySelector(tab.hash); - if (!content) return; - - // Hide active tab and content - var details = hide(tab); - - // Show new tab and content - show(tab, content); - - // Add event details - details.tab = tab; - details.content = content; - - // Emit a custom event - emitEvent(tab, details); - }; - - /** - * Get all of the tabs in a tablist - * @param {Node} tab A tab from the list - * @return {Object} The tabs and the index of the currently active one - */ - var getTabsMap = function (tab) { - var tabGroup = tab.closest('[role="tablist"]'); - var tabs = tabGroup ? tabGroup.querySelectorAll('[role="tab"]') : null; - if (!tabs) return; - return { - tabs: tabs, - index: Array.prototype.indexOf.call(tabs, tab), - }; - }; - - /** - * Switch the active tab based on keyboard activity - * @param {Node} tab The currently active tab - * @param {Key} key The key that was pressed - */ - var switchTabs = function (tab, key) { - // Get a map of tabs - var map = getTabsMap(tab); - if (!map) return; - var length = map.tabs.length - 1; - var index; - - // Go to previous tab - if (["ArrowUp", "ArrowLeft", "Up", "Left"].indexOf(key) > -1) { - index = map.index < 1 ? length : map.index - 1; - } - - // Go to next tab - else if (["ArrowDown", "ArrowRight", "Down", "Right"].indexOf(key) > -1) { - index = map.index === length ? 0 : map.index + 1; - } - - // Go to home - else if (key === "Home") { - index = 0; - } - - // Go to end - else if (key === "End") { - index = length; - } - - // Toggle the tab - toggle(map.tabs[index]); - }; - - /** - * Create the Constructor object - */ - var Constructor = function (selector, options) { - // - // Variables - // - - var publicAPIs = {}; - var settings, tabWrapper; - - // - // Methods - // - - publicAPIs.destroy = function () { - // Get all tabs - var tabs = tabWrapper.querySelectorAll("a"); - - // Add roles to tabs - Array.prototype.forEach.call(tabs, function (tab) { - // Get the tab content - var content = document.querySelector(tab.hash); - if (!content) return; - - // Setup the tab - destroyTab(tab, content, settings); - }); - - // Remove role from wrapper - tabWrapper.removeAttribute("role"); - - // Remove event listeners - document.documentElement.removeEventListener( - "click", - clickHandler, - true - ); - tabWrapper.removeEventListener("keydown", keyHandler, true); - - // Reset variables - settings = null; - tabWrapper = null; - }; - - /** - * Setup the DOM with the proper attributes - */ - publicAPIs.setup = function () { - // Variables - tabWrapper = document.querySelector(selector); - if (!tabWrapper) return; - var tabs = tabWrapper.querySelectorAll("a"); - - // Add role to wrapper - tabWrapper.setAttribute("role", "tablist"); - - // Add roles to tabs. provide dynanmic tab indexes if we are within reveal - var contentTabindexes = - window.document.body.classList.contains("reveal-viewport"); - var nextTabindex = 1; - Array.prototype.forEach.call(tabs, function (tab) { - if (contentTabindexes) { - tab.setAttribute("tabindex", "" + nextTabindex++); - } else { - tab.setAttribute("tabindex", "0"); - } - - // Get the tab content - var content = document.querySelector(tab.hash); - if (!content) return; - - // set tab indexes for content - if (contentTabindexes) { - getKeyboardFocusableElements(content).forEach(function (el) { - el.setAttribute("tabindex", "" + nextTabindex++); - }); - } - - // Setup the tab - setupTab(tab, content, settings); - }); - }; - - /** - * Toggle a tab based on an ID - * @param {String|Node} id The tab to toggle - */ - publicAPIs.toggle = function (id) { - // Get the tab - var tab = id; - if (typeof id === "string") { - tab = document.querySelector( - selector + ' [role="tab"][href*="' + id + '"]' - ); - } - - // Toggle the tab - toggle(tab); - }; - - /** - * Handle click events - */ - var clickHandler = function (event) { - // Only run on toggles - var tab = event.target.closest(selector + ' [role="tab"]'); - if (!tab) return; - - // Prevent link behavior - event.preventDefault(); - - // Toggle the tab - toggle(tab); - }; - - /** - * Handle keydown events - */ - var keyHandler = function (event) { - // Only run if a tab is in focus - var tab = document.activeElement; - if (!tab.matches(selector + ' [role="tab"]')) return; - - // Only run for specific keys - if (["Home", "End"].indexOf(event.key) < 0) return; - - // Switch tabs - switchTabs(tab, event.key); - }; - - /** - * Initialize the instance - */ - var init = function () { - // Merge user options with defaults - settings = extend(defaults, options || {}); - - // Setup the DOM - publicAPIs.setup(); - - // Add event listeners - document.documentElement.addEventListener("click", clickHandler, true); - tabWrapper.addEventListener("keydown", keyHandler, true); - }; - - // - // Initialize and return the Public APIs - // - - init(); - return publicAPIs; - }; - - // - // Return the Constructor - // - - return Constructor; - } -); diff --git a/docs/lecs-quarto/lecture01_files/libs/quarto-html/tippy.css b/docs/lecs-quarto/lecture01_files/libs/quarto-html/tippy.css deleted file mode 100644 index e6ae635..0000000 --- a/docs/lecs-quarto/lecture01_files/libs/quarto-html/tippy.css +++ /dev/null @@ -1 +0,0 @@ -.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} \ No newline at end of file diff --git a/docs/lecs-quarto/lecture01_files/libs/quarto-html/tippy.umd.min.js b/docs/lecs-quarto/lecture01_files/libs/quarto-html/tippy.umd.min.js deleted file mode 100644 index ca292be..0000000 --- a/docs/lecs-quarto/lecture01_files/libs/quarto-html/tippy.umd.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],t):(e=e||self).tippy=t(e.Popper)}(this,(function(e){"use strict";var t={passive:!0,capture:!0},n=function(){return document.body};function r(e,t,n){if(Array.isArray(e)){var r=e[t];return null==r?Array.isArray(n)?n[t]:n:r}return e}function o(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function i(e,t){return"function"==typeof e?e.apply(void 0,t):e}function a(e,t){return 0===t?e:function(r){clearTimeout(n),n=setTimeout((function(){e(r)}),t)};var n}function s(e,t){var n=Object.assign({},e);return t.forEach((function(e){delete n[e]})),n}function u(e){return[].concat(e)}function c(e,t){-1===e.indexOf(t)&&e.push(t)}function p(e){return e.split("-")[0]}function f(e){return[].slice.call(e)}function l(e){return Object.keys(e).reduce((function(t,n){return void 0!==e[n]&&(t[n]=e[n]),t}),{})}function d(){return document.createElement("div")}function v(e){return["Element","Fragment"].some((function(t){return o(e,t)}))}function m(e){return o(e,"MouseEvent")}function g(e){return!(!e||!e._tippy||e._tippy.reference!==e)}function h(e){return v(e)?[e]:function(e){return o(e,"NodeList")}(e)?f(e):Array.isArray(e)?e:f(document.querySelectorAll(e))}function b(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function y(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function w(e){var t,n=u(e)[0];return null!=n&&null!=(t=n.ownerDocument)&&t.body?n.ownerDocument:document}function E(e,t,n){var r=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[r](t,n)}))}function O(e,t){for(var n=t;n;){var r;if(e.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var x={isTouch:!1},C=0;function T(){x.isTouch||(x.isTouch=!0,window.performance&&document.addEventListener("mousemove",A))}function A(){var e=performance.now();e-C<20&&(x.isTouch=!1,document.removeEventListener("mousemove",A)),C=e}function L(){var e=document.activeElement;if(g(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}var D=!!("undefined"!=typeof window&&"undefined"!=typeof document)&&!!window.msCrypto,R=Object.assign({appendTo:n,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(R);function P(e){var t=(e.plugins||[]).reduce((function(t,n){var r,o=n.name,i=n.defaultValue;o&&(t[o]=void 0!==e[o]?e[o]:null!=(r=R[o])?r:i);return t}),{});return Object.assign({},e,t)}function j(e,t){var n=Object.assign({},t,{content:i(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(P(Object.assign({},R,{plugins:t}))):k).reduce((function(t,n){var r=(e.getAttribute("data-tippy-"+n)||"").trim();if(!r)return t;if("content"===n)t[n]=r;else try{t[n]=JSON.parse(r)}catch(e){t[n]=r}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function M(e,t){e.innerHTML=t}function V(e){var t=d();return!0===e?t.className="tippy-arrow":(t.className="tippy-svg-arrow",v(e)?t.appendChild(e):M(t,e)),t}function I(e,t){v(t.content)?(M(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?M(e,t.content):e.textContent=t.content)}function S(e){var t=e.firstElementChild,n=f(t.children);return{box:t,content:n.find((function(e){return e.classList.contains("tippy-content")})),arrow:n.find((function(e){return e.classList.contains("tippy-arrow")||e.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function N(e){var t=d(),n=d();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=d();function o(n,r){var o=S(t),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||I(a,e.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(V(r.arrow))):i.appendChild(V(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),I(r,e.props),t.appendChild(n),n.appendChild(r),o(e.props,e.props),{popper:t,onUpdate:o}}N.$$tippy=!0;var B=1,H=[],U=[];function _(o,s){var v,g,h,C,T,A,L,k,M=j(o,Object.assign({},R,P(l(s)))),V=!1,I=!1,N=!1,_=!1,F=[],W=a(we,M.interactiveDebounce),X=B++,Y=(k=M.plugins).filter((function(e,t){return k.indexOf(e)===t})),$={id:X,reference:o,popper:d(),popperInstance:null,props:M,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:Y,clearDelayTimeouts:function(){clearTimeout(v),clearTimeout(g),cancelAnimationFrame(h)},setProps:function(e){if($.state.isDestroyed)return;ae("onBeforeUpdate",[$,e]),be();var t=$.props,n=j(o,Object.assign({},t,l(e),{ignoreAttributes:!0}));$.props=n,he(),t.interactiveDebounce!==n.interactiveDebounce&&(ce(),W=a(we,n.interactiveDebounce));t.triggerTarget&&!n.triggerTarget?u(t.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):n.triggerTarget&&o.removeAttribute("aria-expanded");ue(),ie(),J&&J(t,n);$.popperInstance&&(Ce(),Ae().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)})));ae("onAfterUpdate",[$,e])},setContent:function(e){$.setProps({content:e})},show:function(){var e=$.state.isVisible,t=$.state.isDestroyed,o=!$.state.isEnabled,a=x.isTouch&&!$.props.touch,s=r($.props.duration,0,R.duration);if(e||t||o||a)return;if(te().hasAttribute("disabled"))return;if(ae("onShow",[$],!1),!1===$.props.onShow($))return;$.state.isVisible=!0,ee()&&(z.style.visibility="visible");ie(),de(),$.state.isMounted||(z.style.transition="none");if(ee()){var u=re(),p=u.box,f=u.content;b([p,f],0)}A=function(){var e;if($.state.isVisible&&!_){if(_=!0,z.offsetHeight,z.style.transition=$.props.moveTransition,ee()&&$.props.animation){var t=re(),n=t.box,r=t.content;b([n,r],s),y([n,r],"visible")}se(),ue(),c(U,$),null==(e=$.popperInstance)||e.forceUpdate(),ae("onMount",[$]),$.props.animation&&ee()&&function(e,t){me(e,t)}(s,(function(){$.state.isShown=!0,ae("onShown",[$])}))}},function(){var e,t=$.props.appendTo,r=te();e=$.props.interactive&&t===n||"parent"===t?r.parentNode:i(t,[r]);e.contains(z)||e.appendChild(z);$.state.isMounted=!0,Ce()}()},hide:function(){var e=!$.state.isVisible,t=$.state.isDestroyed,n=!$.state.isEnabled,o=r($.props.duration,1,R.duration);if(e||t||n)return;if(ae("onHide",[$],!1),!1===$.props.onHide($))return;$.state.isVisible=!1,$.state.isShown=!1,_=!1,V=!1,ee()&&(z.style.visibility="hidden");if(ce(),ve(),ie(!0),ee()){var i=re(),a=i.box,s=i.content;$.props.animation&&(b([a,s],o),y([a,s],"hidden"))}se(),ue(),$.props.animation?ee()&&function(e,t){me(e,(function(){!$.state.isVisible&&z.parentNode&&z.parentNode.contains(z)&&t()}))}(o,$.unmount):$.unmount()},hideWithInteractivity:function(e){ne().addEventListener("mousemove",W),c(H,W),W(e)},enable:function(){$.state.isEnabled=!0},disable:function(){$.hide(),$.state.isEnabled=!1},unmount:function(){$.state.isVisible&&$.hide();if(!$.state.isMounted)return;Te(),Ae().forEach((function(e){e._tippy.unmount()})),z.parentNode&&z.parentNode.removeChild(z);U=U.filter((function(e){return e!==$})),$.state.isMounted=!1,ae("onHidden",[$])},destroy:function(){if($.state.isDestroyed)return;$.clearDelayTimeouts(),$.unmount(),be(),delete o._tippy,$.state.isDestroyed=!0,ae("onDestroy",[$])}};if(!M.render)return $;var q=M.render($),z=q.popper,J=q.onUpdate;z.setAttribute("data-tippy-root",""),z.id="tippy-"+$.id,$.popper=z,o._tippy=$,z._tippy=$;var G=Y.map((function(e){return e.fn($)})),K=o.hasAttribute("aria-expanded");return he(),ue(),ie(),ae("onCreate",[$]),M.showOnCreate&&Le(),z.addEventListener("mouseenter",(function(){$.props.interactive&&$.state.isVisible&&$.clearDelayTimeouts()})),z.addEventListener("mouseleave",(function(){$.props.interactive&&$.props.trigger.indexOf("mouseenter")>=0&&ne().addEventListener("mousemove",W)})),$;function Q(){var e=$.props.touch;return Array.isArray(e)?e:[e,0]}function Z(){return"hold"===Q()[0]}function ee(){var e;return!(null==(e=$.props.render)||!e.$$tippy)}function te(){return L||o}function ne(){var e=te().parentNode;return e?w(e):document}function re(){return S(z)}function oe(e){return $.state.isMounted&&!$.state.isVisible||x.isTouch||C&&"focus"===C.type?0:r($.props.delay,e?0:1,R.delay)}function ie(e){void 0===e&&(e=!1),z.style.pointerEvents=$.props.interactive&&!e?"":"none",z.style.zIndex=""+$.props.zIndex}function ae(e,t,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[e]&&n[e].apply(n,t)})),n)&&(r=$.props)[e].apply(r,t)}function se(){var e=$.props.aria;if(e.content){var t="aria-"+e.content,n=z.id;u($.props.triggerTarget||o).forEach((function(e){var r=e.getAttribute(t);if($.state.isVisible)e.setAttribute(t,r?r+" "+n:n);else{var o=r&&r.replace(n,"").trim();o?e.setAttribute(t,o):e.removeAttribute(t)}}))}}function ue(){!K&&$.props.aria.expanded&&u($.props.triggerTarget||o).forEach((function(e){$.props.interactive?e.setAttribute("aria-expanded",$.state.isVisible&&e===te()?"true":"false"):e.removeAttribute("aria-expanded")}))}function ce(){ne().removeEventListener("mousemove",W),H=H.filter((function(e){return e!==W}))}function pe(e){if(!x.isTouch||!N&&"mousedown"!==e.type){var t=e.composedPath&&e.composedPath()[0]||e.target;if(!$.props.interactive||!O(z,t)){if(u($.props.triggerTarget||o).some((function(e){return O(e,t)}))){if(x.isTouch)return;if($.state.isVisible&&$.props.trigger.indexOf("click")>=0)return}else ae("onClickOutside",[$,e]);!0===$.props.hideOnClick&&($.clearDelayTimeouts(),$.hide(),I=!0,setTimeout((function(){I=!1})),$.state.isMounted||ve())}}}function fe(){N=!0}function le(){N=!1}function de(){var e=ne();e.addEventListener("mousedown",pe,!0),e.addEventListener("touchend",pe,t),e.addEventListener("touchstart",le,t),e.addEventListener("touchmove",fe,t)}function ve(){var e=ne();e.removeEventListener("mousedown",pe,!0),e.removeEventListener("touchend",pe,t),e.removeEventListener("touchstart",le,t),e.removeEventListener("touchmove",fe,t)}function me(e,t){var n=re().box;function r(e){e.target===n&&(E(n,"remove",r),t())}if(0===e)return t();E(n,"remove",T),E(n,"add",r),T=r}function ge(e,t,n){void 0===n&&(n=!1),u($.props.triggerTarget||o).forEach((function(r){r.addEventListener(e,t,n),F.push({node:r,eventType:e,handler:t,options:n})}))}function he(){var e;Z()&&(ge("touchstart",ye,{passive:!0}),ge("touchend",Ee,{passive:!0})),(e=$.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(ge(e,ye),e){case"mouseenter":ge("mouseleave",Ee);break;case"focus":ge(D?"focusout":"blur",Oe);break;case"focusin":ge("focusout",Oe)}}))}function be(){F.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),F=[]}function ye(e){var t,n=!1;if($.state.isEnabled&&!xe(e)&&!I){var r="focus"===(null==(t=C)?void 0:t.type);C=e,L=e.currentTarget,ue(),!$.state.isVisible&&m(e)&&H.forEach((function(t){return t(e)})),"click"===e.type&&($.props.trigger.indexOf("mouseenter")<0||V)&&!1!==$.props.hideOnClick&&$.state.isVisible?n=!0:Le(e),"click"===e.type&&(V=!n),n&&!r&&De(e)}}function we(e){var t=e.target,n=te().contains(t)||z.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,r=t.clientY;return e.every((function(e){var t=e.popperRect,o=e.popperState,i=e.props.interactiveBorder,a=p(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,f="right"===a?s.left.x:0,l="left"===a?s.right.x:0,d=t.top-r+u>i,v=r-t.bottom-c>i,m=t.left-n+f>i,g=n-t.right-l>i;return d||v||m||g}))}(Ae().concat(z).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:M}:null})).filter(Boolean),e)&&(ce(),De(e))}function Ee(e){xe(e)||$.props.trigger.indexOf("click")>=0&&V||($.props.interactive?$.hideWithInteractivity(e):De(e))}function Oe(e){$.props.trigger.indexOf("focusin")<0&&e.target!==te()||$.props.interactive&&e.relatedTarget&&z.contains(e.relatedTarget)||De(e)}function xe(e){return!!x.isTouch&&Z()!==e.type.indexOf("touch")>=0}function Ce(){Te();var t=$.props,n=t.popperOptions,r=t.placement,i=t.offset,a=t.getReferenceClientRect,s=t.moveTransition,u=ee()?S(z).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||te()}:o,p=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(ee()){var n=re().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];ee()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==n?void 0:n.modifiers)||[]),$.popperInstance=e.createPopper(c,z,Object.assign({},n,{placement:r,onFirstUpdate:A,modifiers:p}))}function Te(){$.popperInstance&&($.popperInstance.destroy(),$.popperInstance=null)}function Ae(){return f(z.querySelectorAll("[data-tippy-root]"))}function Le(e){$.clearDelayTimeouts(),e&&ae("onTrigger",[$,e]),de();var t=oe(!0),n=Q(),r=n[0],o=n[1];x.isTouch&&"hold"===r&&o&&(t=o),t?v=setTimeout((function(){$.show()}),t):$.show()}function De(e){if($.clearDelayTimeouts(),ae("onUntrigger",[$,e]),$.state.isVisible){if(!($.props.trigger.indexOf("mouseenter")>=0&&$.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&V)){var t=oe(!1);t?g=setTimeout((function(){$.state.isVisible&&$.hide()}),t):h=requestAnimationFrame((function(){$.hide()}))}}else ve()}}function F(e,n){void 0===n&&(n={});var r=R.plugins.concat(n.plugins||[]);document.addEventListener("touchstart",T,t),window.addEventListener("blur",L);var o=Object.assign({},n,{plugins:r}),i=h(e).reduce((function(e,t){var n=t&&_(t,o);return n&&e.push(n),e}),[]);return v(e)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(e){Object.keys(e).forEach((function(t){R[t]=e[t]}))},F.currentInput=x;var W=Object.assign({},e.applyStyles,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(e){var t;if(null==(t=e.props.render)||!t.$$tippy)return{};var n=S(e.popper),r=n.box,o=n.content,i=e.props.animateFill?function(){var e=d();return e.className="tippy-backdrop",y([e],"hidden"),e}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",e.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var e=r.style.transitionDuration,t=Number(e.replace("ms",""));o.style.transitionDelay=Math.round(t/10)+"ms",i.style.transitionDuration=e,y([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&y([i],"hidden")}}}};var $={clientX:0,clientY:0},q=[];function z(e){var t=e.clientX,n=e.clientY;$={clientX:t,clientY:n}}var J={name:"followCursor",defaultValue:!1,fn:function(e){var t=e.reference,n=w(e.props.triggerTarget||t),r=!1,o=!1,i=!0,a=e.props;function s(){return"initial"===e.props.followCursor&&e.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,e.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||t.contains(n.target),o=e.props.followCursor,i=n.clientX,a=n.clientY,s=t.getBoundingClientRect(),u=i-s.left,c=a-s.top;!r&&e.props.interactive||e.setProps({getReferenceClientRect:function(){var e=t.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=e.left+u,r=e.top+c);var s="horizontal"===o?e.top:r,p="vertical"===o?e.right:n,f="horizontal"===o?e.bottom:r,l="vertical"===o?e.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){e.props.followCursor&&(q.push({instance:e,doc:n}),function(e){e.addEventListener("mousemove",z)}(n))}function d(){0===(q=q.filter((function(t){return t.instance!==e}))).filter((function(e){return e.doc===n})).length&&function(e){e.removeEventListener("mousemove",z)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=e.props},onAfterUpdate:function(t,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!e.state.isMounted||o||s()||u()):(c(),p()))},onMount:function(){e.props.followCursor&&!o&&(i&&(f($),i=!1),s()||u())},onTrigger:function(e,t){m(t)&&($={clientX:t.clientX,clientY:t.clientY}),o="focus"===t.type},onHidden:function(){e.props.followCursor&&(p(),c(),i=!0)}}}};var G={name:"inlinePositioning",defaultValue:!1,fn:function(e){var t,n=e.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;e.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),t!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),e.setProps({getReferenceClientRect:function(){return function(e){return function(e,t,n,r){if(n.length<2||null===e)return t;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||t;switch(e){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===e,s=o.top,u=i.bottom,c=a?o.left:i.left,p=a?o.right:i.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(e){return e.left}))),l=Math.max.apply(Math,n.map((function(e){return e.right}))),d=n.filter((function(t){return"left"===e?t.left===f:t.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return t}}(p(e),n.getBoundingClientRect(),f(n.getClientRects()),r)}(a.placement)}})),t=a.placement)}};function s(){var t;o||(t=function(e,t){var n;return{popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat(((null==(n=e.popperOptions)?void 0:n.modifiers)||[]).filter((function(e){return e.name!==t.name})),[t])})}}(e.props,a),o=!0,e.setProps(t),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(t,n){if(m(n)){var o=f(e.reference.getClientRects()),i=o.find((function(e){return e.left-2<=n.clientX&&e.right+2>=n.clientX&&e.top-2<=n.clientY&&e.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var K={name:"sticky",defaultValue:!1,fn:function(e){var t=e.reference,n=e.popper;function r(t){return!0===e.props.sticky||e.props.sticky===t}var o=null,i=null;function a(){var s=r("reference")?(e.popperInstance?e.popperInstance.state.elements.reference:t).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Q(o,s)||u&&Q(i,u))&&e.popperInstance&&e.popperInstance.update(),o=s,i=u,e.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){e.props.sticky&&a()}}}};function Q(e,t){return!e||!t||(e.top!==t.top||e.right!==t.right||e.bottom!==t.bottom||e.left!==t.left)}return F.setDefaultProps({plugins:[Y,J,G,K],render:N}),F.createSingleton=function(e,t){var n;void 0===t&&(t={});var r,o=e,i=[],a=[],c=t.overrides,p=[],f=!1;function l(){a=o.map((function(e){return u(e.props.triggerTarget||e.reference)})).reduce((function(e,t){return e.concat(t)}),[])}function v(){i=o.map((function(e){return e.reference}))}function m(e){o.forEach((function(t){e?t.enable():t.disable()}))}function g(e){return o.map((function(t){var n=t.setProps;return t.setProps=function(o){n(o),t.reference===r&&e.setProps(o)},function(){t.setProps=n}}))}function h(e,t){var n=a.indexOf(t);if(t!==r){r=t;var s=(c||[]).concat("content").reduce((function(e,t){return e[t]=o[n].props[t],e}),{});e.setProps(Object.assign({},s,{getReferenceClientRect:"function"==typeof s.getReferenceClientRect?s.getReferenceClientRect:function(){var e;return null==(e=i[n])?void 0:e.getBoundingClientRect()}}))}}m(!1),v(),l();var b={fn:function(){return{onDestroy:function(){m(!0)},onHidden:function(){r=null},onClickOutside:function(e){e.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(e){e.props.showOnCreate&&!f&&(f=!0,h(e,i[0]))},onTrigger:function(e,t){h(e,t.currentTarget)}}}},y=F(d(),Object.assign({},s(t,["overrides"]),{plugins:[b].concat(t.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat((null==(n=t.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(e){if(w(),!r&&null==e)return h(y,i[0]);if(!r||null!=e){if("number"==typeof e)return i[e]&&h(y,i[e]);if(o.indexOf(e)>=0){var t=e.reference;return h(y,t)}return i.indexOf(e)>=0?h(y,e):void 0}},y.showNext=function(){var e=i[0];if(!r)return y.show(0);var t=i.indexOf(r);y.show(i[t+1]||e)},y.showPrevious=function(){var e=i[i.length-1];if(!r)return y.show(e);var t=i.indexOf(r),n=i[t-1]||e;y.show(n)};var E=y.setProps;return y.setProps=function(e){c=e.overrides||c,E(e)},y.setInstances=function(e){m(!0),p.forEach((function(e){return e()})),o=e,m(!1),v(),l(),p=g(y),y.setProps({triggerTarget:a})},p=g(y),y},F.delegate=function(e,n){var r=[],o=[],i=!1,a=n.target,c=s(n,["target"]),p=Object.assign({},c,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},c,{showOnCreate:!0}),l=F(e,p);function d(e){if(e.target&&!i){var t=e.target.closest(a);if(t){var r=t.getAttribute("data-tippy-trigger")||n.trigger||R.trigger;if(!t._tippy&&!("touchstart"===e.type&&"boolean"==typeof f.touch||"touchstart"!==e.type&&r.indexOf(X[e.type])<0)){var s=F(t,f);s&&(o=o.concat(s))}}}}function v(e,t,n,o){void 0===o&&(o=!1),e.addEventListener(t,n,o),r.push({node:e,eventType:t,handler:n,options:o})}return u(l).forEach((function(e){var n=e.destroy,a=e.enable,s=e.disable;e.destroy=function(e){void 0===e&&(e=!0),e&&o.forEach((function(e){e.destroy()})),o=[],r.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),r=[],n()},e.enable=function(){a(),o.forEach((function(e){return e.enable()})),i=!1},e.disable=function(){s(),o.forEach((function(e){return e.disable()})),i=!0},function(e){var n=e.reference;v(n,"touchstart",d,t),v(n,"mouseover",d),v(n,"focusin",d),v(n,"click",d)}(e)})),l},F.hideAll=function(e){var t=void 0===e?{}:e,n=t.exclude,r=t.duration;U.forEach((function(e){var t=!1;if(n&&(t=g(n)?e.reference===n:e.popper===n.popper),!t){var o=e.props.duration;e.setProps({duration:r}),e.hide(),e.state.isDestroyed||e.setProps({duration:o})}}))},F.roundArrow='',F})); - diff --git a/docs/lecs-quarto/lecture01_files/libs/quarto-ojs/quarto-ojs-runtime.js b/docs/lecs-quarto/lecture01_files/libs/quarto-ojs/quarto-ojs-runtime.js deleted file mode 100644 index 7d21a9f..0000000 --- a/docs/lecs-quarto/lecture01_files/libs/quarto-ojs/quarto-ojs-runtime.js +++ /dev/null @@ -1,24005 +0,0 @@ -// quarto-ojs-runtime v0.0.18 Copyright 2024 undefined -var EOL = {}, - EOF = {}, - QUOTE = 34, - NEWLINE = 10, - RETURN = 13; - -function objectConverter(columns) { - return new Function("d", "return {" + columns.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "] || \"\""; - }).join(",") + "}"); -} - -function customConverter(columns, f) { - var object = objectConverter(columns); - return function(row, i) { - return f(object(row), i, columns); - }; -} - -// Compute unique columns in order of discovery. -function inferColumns(rows) { - var columnSet = Object.create(null), - columns = []; - - rows.forEach(function(row) { - for (var column in row) { - if (!(column in columnSet)) { - columns.push(columnSet[column] = column); - } - } - }); - - return columns; -} - -function pad$1(value, width) { - var s = value + "", length = s.length; - return length < width ? new Array(width - length + 1).join(0) + s : s; -} - -function formatYear$1(year) { - return year < 0 ? "-" + pad$1(-year, 6) - : year > 9999 ? "+" + pad$1(year, 6) - : pad$1(year, 4); -} - -function formatDate$2(date) { - var hours = date.getUTCHours(), - minutes = date.getUTCMinutes(), - seconds = date.getUTCSeconds(), - milliseconds = date.getUTCMilliseconds(); - return isNaN(date) ? "Invalid Date" - : formatYear$1(date.getUTCFullYear()) + "-" + pad$1(date.getUTCMonth() + 1, 2) + "-" + pad$1(date.getUTCDate(), 2) - + (milliseconds ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + ":" + pad$1(seconds, 2) + "." + pad$1(milliseconds, 3) + "Z" - : seconds ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + ":" + pad$1(seconds, 2) + "Z" - : minutes || hours ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + "Z" - : ""); -} - -function dsv$1(delimiter) { - var reFormat = new RegExp("[\"" + delimiter + "\n\r]"), - DELIMITER = delimiter.charCodeAt(0); - - function parse(text, f) { - var convert, columns, rows = parseRows(text, function(row, i) { - if (convert) return convert(row, i - 1); - columns = row, convert = f ? customConverter(row, f) : objectConverter(row); - }); - rows.columns = columns || []; - return rows; - } - - function parseRows(text, f) { - var rows = [], // output rows - N = text.length, - I = 0, // current character index - n = 0, // current line number - t, // current token - eof = N <= 0, // current token followed by EOF? - eol = false; // current token followed by EOL? - - // Strip the trailing newline. - if (text.charCodeAt(N - 1) === NEWLINE) --N; - if (text.charCodeAt(N - 1) === RETURN) --N; - - function token() { - if (eof) return EOF; - if (eol) return eol = false, EOL; - - // Unescape quotes. - var i, j = I, c; - if (text.charCodeAt(j) === QUOTE) { - while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE); - if ((i = I) >= N) eof = true; - else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true; - else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } - return text.slice(j + 1, i - 1).replace(/""/g, "\""); - } - - // Find next delimiter or newline. - while (I < N) { - if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true; - else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } - else if (c !== DELIMITER) continue; - return text.slice(j, i); - } - - // Return last token before EOF. - return eof = true, text.slice(j, N); - } - - while ((t = token()) !== EOF) { - var row = []; - while (t !== EOL && t !== EOF) row.push(t), t = token(); - if (f && (row = f(row, n++)) == null) continue; - rows.push(row); - } - - return rows; - } - - function preformatBody(rows, columns) { - return rows.map(function(row) { - return columns.map(function(column) { - return formatValue(row[column]); - }).join(delimiter); - }); - } - - function format(rows, columns) { - if (columns == null) columns = inferColumns(rows); - return [columns.map(formatValue).join(delimiter)].concat(preformatBody(rows, columns)).join("\n"); - } - - function formatBody(rows, columns) { - if (columns == null) columns = inferColumns(rows); - return preformatBody(rows, columns).join("\n"); - } - - function formatRows(rows) { - return rows.map(formatRow).join("\n"); - } - - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - - function formatValue(value) { - return value == null ? "" - : value instanceof Date ? formatDate$2(value) - : reFormat.test(value += "") ? "\"" + value.replace(/"/g, "\"\"") + "\"" - : value; - } - - return { - parse: parse, - parseRows: parseRows, - format: format, - formatBody: formatBody, - formatRows: formatRows, - formatRow: formatRow, - formatValue: formatValue - }; -} - -var csv = dsv$1(","); - -var csvParse = csv.parse; -var csvParseRows = csv.parseRows; - -var tsv = dsv$1("\t"); - -var tsvParse = tsv.parse; -var tsvParseRows = tsv.parseRows; - -function autoType(object) { - for (var key in object) { - var value = object[key].trim(), number, m; - if (!value) value = null; - else if (value === "true") value = true; - else if (value === "false") value = false; - else if (value === "NaN") value = NaN; - else if (!isNaN(number = +value)) value = number; - else if (m = value.match(/^([-+]\d{2})?\d{4}(-\d{2}(-\d{2})?)?(T\d{2}:\d{2}(:\d{2}(\.\d{3})?)?(Z|[-+]\d{2}:\d{2})?)?$/)) { - if (fixtz && !!m[4] && !m[7]) value = value.replace(/-/g, "/").replace(/T/, " "); - value = new Date(value); - } - else continue; - object[key] = value; - } - return object; -} - -// https://github.com/d3/d3-dsv/issues/45 -const fixtz = new Date("2019-01-01T00:00").getHours() || new Date("2019-07-01T00:00").getHours(); - -function dependency(name, version, main) { - return { - resolve(path = main) { - return `${name}@${version}/${path}`; - } - }; -} - -const d3 = dependency("d3", "7.8.5", "dist/d3.min.js"); -const inputs = dependency("@observablehq/inputs", "0.10.6", "dist/inputs.min.js"); -const plot = dependency("@observablehq/plot", "0.6.11", "dist/plot.umd.min.js"); -const graphviz = dependency("@observablehq/graphviz", "0.2.1", "dist/graphviz.min.js"); -const highlight = dependency("@observablehq/highlight.js", "2.0.0", "highlight.min.js"); -const katex = dependency("@observablehq/katex", "0.11.1", "dist/katex.min.js"); -const lodash = dependency("lodash", "4.17.21", "lodash.min.js"); -const htl = dependency("htl", "0.3.1", "dist/htl.min.js"); -const jszip = dependency("jszip", "3.10.1", "dist/jszip.min.js"); -const marked = dependency("marked", "0.3.12", "marked.min.js"); -const sql = dependency("sql.js", "1.8.0", "dist/sql-wasm.js"); -const vega = dependency("vega", "5.22.1", "build/vega.min.js"); -const vegalite = dependency("vega-lite", "5.6.0", "build/vega-lite.min.js"); -const vegaliteApi = dependency("vega-lite-api", "5.0.0", "build/vega-lite-api.min.js"); -const arrow4 = dependency("apache-arrow", "4.0.1", "Arrow.es2015.min.js"); -const arrow9 = dependency("apache-arrow", "9.0.0", "+esm"); -const arrow11 = dependency("apache-arrow", "11.0.0", "+esm"); -const arquero = dependency("arquero", "4.8.8", "dist/arquero.min.js"); -const topojson = dependency("topojson-client", "3.1.0", "dist/topojson-client.min.js"); -const exceljs = dependency("exceljs", "4.3.0", "dist/exceljs.min.js"); -const mermaid$1 = dependency("mermaid", "9.2.2", "dist/mermaid.min.js"); -const leaflet$1 = dependency("leaflet", "1.9.3", "dist/leaflet.js"); -const duckdb = dependency("@duckdb/duckdb-wasm", "1.24.0", "+esm"); - -const metas = new Map; -const queue$1 = []; -const map$2 = queue$1.map; -const some = queue$1.some; -const hasOwnProperty$2 = queue$1.hasOwnProperty; -const identifierRe = /^((?:@[^/@]+\/)?[^/@]+)(?:@([^/]+))?(?:\/(.*))?$/; -const versionRe = /^\d+\.\d+\.\d+(-[\w-.+]+)?$/; -const extensionRe = /(?:\.[^/]*|\/)$/; - -class RequireError extends Error { - constructor(message) { - super(message); - } -} - -RequireError.prototype.name = RequireError.name; - -function parseIdentifier(identifier) { - const match = identifierRe.exec(identifier); - return match && { - name: match[1], - version: match[2], - path: match[3] - }; -} - -function resolveFrom(origin = "https://cdn.jsdelivr.net/npm/", mains = ["unpkg", "jsdelivr", "browser", "main"]) { - if (!/\/$/.test(origin)) throw new Error("origin lacks trailing slash"); - - function main(meta) { - for (const key of mains) { - let value = meta[key]; - if (typeof value === "string") { - if (value.startsWith("./")) value = value.slice(2); - return extensionRe.test(value) ? value : `${value}.js`; - } - } - } - - function resolveMeta(target) { - const url = `${origin}${target.name}${target.version ? `@${target.version}` : ""}/package.json`; - let meta = metas.get(url); - if (!meta) metas.set(url, meta = fetch(url).then(response => { - if (!response.ok) throw new RequireError("unable to load package.json"); - if (response.redirected && !metas.has(response.url)) metas.set(response.url, meta); - return response.json(); - })); - return meta; - } - - return async function resolve(name, base) { - if (name.startsWith(origin)) name = name.substring(origin.length); - if (/^(\w+:)|\/\//i.test(name)) return name; - if (/^[.]{0,2}\//i.test(name)) return new URL(name, base == null ? location : base).href; - if (!name.length || /^[\s._]/.test(name) || /\s$/.test(name)) throw new RequireError("illegal name"); - const target = parseIdentifier(name); - if (!target) return `${origin}${name}`; - if (!target.version && base != null && base.startsWith(origin)) { - const meta = await resolveMeta(parseIdentifier(base.substring(origin.length))); - target.version = meta.dependencies && meta.dependencies[target.name] || meta.peerDependencies && meta.peerDependencies[target.name]; - } - if (target.path && !extensionRe.test(target.path)) target.path += ".js"; - if (target.path && target.version && versionRe.test(target.version)) return `${origin}${target.name}@${target.version}/${target.path}`; - const meta = await resolveMeta(target); - return `${origin}${meta.name}@${meta.version}/${target.path || main(meta) || "index.js"}`; - }; -} - -var require = requireFrom(resolveFrom()); -let requestsInFlight = 0; -let prevDefine = undefined; - -function requireFrom(resolver) { - const cache = new Map; - const requireBase = requireRelative(null); - - function requireAbsolute(url) { - if (typeof url !== "string") return url; - let module = cache.get(url); - if (!module) cache.set(url, module = new Promise((resolve, reject) => { - const script = document.createElement("script"); - script.onload = () => { - try { resolve(queue$1.pop()(requireRelative(url))); } - catch (error) { reject(new RequireError("invalid module")); } - script.remove(); - requestsInFlight--; - if (requestsInFlight === 0) { - window.define = prevDefine; - } - }; - script.onerror = () => { - reject(new RequireError("unable to load module")); - script.remove(); - requestsInFlight--; - if (requestsInFlight === 0) { - window.define = prevDefine; - } - }; - script.async = true; - script.src = url; - if (requestsInFlight === 0) { - prevDefine = window.define; - window.define = define; - } - requestsInFlight++; - - document.head.appendChild(script); - })); - return module; - } - - function requireRelative(base) { - return name => Promise.resolve(resolver(name, base)).then(requireAbsolute); - } - - function requireAlias(aliases) { - return requireFrom((name, base) => { - if (name in aliases) { - name = aliases[name], base = null; - if (typeof name !== "string") return name; - } - return resolver(name, base); - }); - } - - function require(name) { - return arguments.length > 1 - ? Promise.all(map$2.call(arguments, requireBase)).then(merge$1) - : requireBase(name); - } - - require.alias = requireAlias; - require.resolve = resolver; - - return require; -} - -function merge$1(modules) { - const o = {}; - for (const m of modules) { - for (const k in m) { - if (hasOwnProperty$2.call(m, k)) { - if (m[k] == null) Object.defineProperty(o, k, {get: getter(m, k)}); - else o[k] = m[k]; - } - } - } - return o; -} - -function getter(object, name) { - return () => object[name]; -} - -function isbuiltin(name) { - name = name + ""; - return name === "exports" || name === "module"; -} - -function define(name, dependencies, factory) { - const n = arguments.length; - if (n < 2) factory = name, dependencies = []; - else if (n < 3) factory = dependencies, dependencies = typeof name === "string" ? [] : name; - queue$1.push(some.call(dependencies, isbuiltin) ? require => { - const exports = {}; - const module = {exports}; - return Promise.all(map$2.call(dependencies, name => { - name = name + ""; - return name === "exports" ? exports : name === "module" ? module : require(name); - })).then(dependencies => { - factory.apply(null, dependencies); - return module.exports; - }); - } : require => { - return Promise.all(map$2.call(dependencies, require)).then(dependencies => { - return typeof factory === "function" ? factory.apply(null, dependencies) : factory; - }); - }); -} - -define.amd = {}; - -// TODO Allow this to be overridden using the Library’s resolver. -const cdn = "https://cdn.observableusercontent.com/npm/"; - -let requireDefault = require; - -function setDefaultRequire(require) { - requireDefault = require; -} - -function requirer(resolver) { - return resolver == null ? requireDefault : requireFrom(resolver); -} - -function fromEntries(obj) { - const result = {}; - for (const [key, value] of obj) { - result[key] = value; - } - return result; -} - -async function SQLite(require) { - const [init, dist] = await Promise.all([require(sql.resolve()), require.resolve(sql.resolve("dist/"))]); - return init({locateFile: file => `${dist}${file}`}); -} - -class SQLiteDatabaseClient { - constructor(db) { - Object.defineProperties(this, { - _db: {value: db} - }); - } - static async open(source) { - const [SQL, buffer] = await Promise.all([SQLite(requireDefault), Promise.resolve(source).then(load$1)]); - return new SQLiteDatabaseClient(new SQL.Database(buffer)); - } - async query(query, params) { - return await exec(this._db, query, params); - } - async queryRow(query, params) { - return (await this.query(query, params))[0] || null; - } - async explain(query, params) { - const rows = await this.query(`EXPLAIN QUERY PLAN ${query}`, params); - return element$1("pre", {className: "observablehq--inspect"}, [ - text$2(rows.map(row => row.detail).join("\n")) - ]); - } - async describeTables({schema} = {}) { - return this.query(`SELECT NULLIF(schema, 'main') AS schema, name FROM pragma_table_list() WHERE type = 'table'${schema == null ? "" : ` AND schema = ?`} AND name NOT LIKE 'sqlite_%' ORDER BY schema, name`, schema == null ? [] : [schema]); - } - async describeColumns({schema, table} = {}) { - if (table == null) throw new Error(`missing table`); - const rows = await this.query(`SELECT name, type, "notnull" FROM pragma_table_info(?${schema == null ? "" : `, ?`}) ORDER BY cid`, schema == null ? [table] : [table, schema]); - if (!rows.length) throw new Error(`table not found: ${table}`); - return rows.map(({name, type, notnull}) => ({name, type: sqliteType(type), databaseType: type, nullable: !notnull})); - } - async describe(object) { - const rows = await (object === undefined - ? this.query(`SELECT name FROM sqlite_master WHERE type = 'table'`) - : this.query(`SELECT * FROM pragma_table_info(?)`, [object])); - if (!rows.length) throw new Error("Not found"); - const {columns} = rows; - return element$1("table", {value: rows}, [ - element$1("thead", [element$1("tr", columns.map(c => element$1("th", [text$2(c)])))]), - element$1("tbody", rows.map(r => element$1("tr", columns.map(c => element$1("td", [text$2(r[c])]))))) - ]); - } - async sql() { - return this.query(...this.queryTag.apply(this, arguments)); - } - queryTag(strings, ...params) { - return [strings.join("?"), params]; - } -} - -Object.defineProperty(SQLiteDatabaseClient.prototype, "dialect", { - value: "sqlite" -}); - -// https://www.sqlite.org/datatype3.html -function sqliteType(type) { - switch (type) { - case "NULL": - return "null"; - case "INT": - case "INTEGER": - case "TINYINT": - case "SMALLINT": - case "MEDIUMINT": - case "BIGINT": - case "UNSIGNED BIG INT": - case "INT2": - case "INT8": - return "integer"; - case "TEXT": - case "CLOB": - return "string"; - case "REAL": - case "DOUBLE": - case "DOUBLE PRECISION": - case "FLOAT": - case "NUMERIC": - return "number"; - case "BLOB": - return "buffer"; - case "DATE": - case "DATETIME": - return "string"; // TODO convert strings to Date instances in sql.js - default: - return /^(?:(?:(?:VARYING|NATIVE) )?CHARACTER|(?:N|VAR|NVAR)CHAR)\(/.test(type) ? "string" - : /^(?:DECIMAL|NUMERIC)\(/.test(type) ? "number" - : "other"; - } -} - -function load$1(source) { - return typeof source === "string" ? fetch(source).then(load$1) - : source instanceof Response || source instanceof Blob ? source.arrayBuffer().then(load$1) - : source instanceof ArrayBuffer ? new Uint8Array(source) - : source; -} - -async function exec(db, query, params) { - const [result] = await db.exec(query, params); - if (!result) return []; - const {columns, values} = result; - const rows = values.map(row => fromEntries(row.map((value, i) => [columns[i], value]))); - rows.columns = columns; - return rows; -} - -function element$1(name, props, children) { - if (arguments.length === 2) children = props, props = undefined; - const element = document.createElement(name); - if (props !== undefined) for (const p in props) element[p] = props[p]; - if (children !== undefined) for (const c of children) element.appendChild(c); - return element; -} - -function text$2(value) { - return document.createTextNode(value); -} - -function ascending(a, b) { - return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; -} - -function descending(a, b) { - return a == null || b == null ? NaN - : b < a ? -1 - : b > a ? 1 - : b >= a ? 0 - : NaN; -} - -function bisector(f) { - let compare1, compare2, delta; - - // If an accessor is specified, promote it to a comparator. In this case we - // can test whether the search value is (self-) comparable. We can’t do this - // for a comparator (except for specific, known comparators) because we can’t - // tell if the comparator is symmetric, and an asymmetric comparator can’t be - // used to test whether a single value is comparable. - if (f.length !== 2) { - compare1 = ascending; - compare2 = (d, x) => ascending(f(d), x); - delta = (d, x) => f(d) - x; - } else { - compare1 = f === ascending || f === descending ? f : zero; - compare2 = f; - delta = f; - } - - function left(a, x, lo = 0, hi = a.length) { - if (lo < hi) { - if (compare1(x, x) !== 0) return hi; - do { - const mid = (lo + hi) >>> 1; - if (compare2(a[mid], x) < 0) lo = mid + 1; - else hi = mid; - } while (lo < hi); - } - return lo; - } - - function right(a, x, lo = 0, hi = a.length) { - if (lo < hi) { - if (compare1(x, x) !== 0) return hi; - do { - const mid = (lo + hi) >>> 1; - if (compare2(a[mid], x) <= 0) lo = mid + 1; - else hi = mid; - } while (lo < hi); - } - return lo; - } - - function center(a, x, lo = 0, hi = a.length) { - const i = left(a, x, lo, hi - 1); - return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; - } - - return {left, center, right}; -} - -function zero() { - return 0; -} - -function number(x) { - return x === null ? NaN : +x; -} - -bisector(ascending); -bisector(number).center; - -function greatest(values, compare = ascending) { - let max; - let defined = false; - if (compare.length === 1) { - let maxValue; - for (const element of values) { - const value = compare(element); - if (defined - ? ascending(value, maxValue) > 0 - : ascending(value, value) === 0) { - max = element; - maxValue = value; - defined = true; - } - } - } else { - for (const value of values) { - if (defined - ? compare(value, max) > 0 - : compare(value, value) === 0) { - max = value; - defined = true; - } - } - } - return max; -} - -function reverse(values) { - if (typeof values[Symbol.iterator] !== "function") throw new TypeError("values is not iterable"); - return Array.from(values).reverse(); -} - -function isArqueroTable(value) { - // Arquero tables have a `toArrowBuffer` function - return value && typeof value.toArrowBuffer === "function"; -} - -// Returns true if the vaue is an Apache Arrow table. This uses a “duck” test -// (instead of strict instanceof) because we want it to work with a range of -// Apache Arrow versions at least 7.0.0 or above. -// https://arrow.apache.org/docs/7.0/js/classes/Arrow_dom.Table.html -function isArrowTable(value) { - return ( - value && - typeof value.getChild === "function" && - typeof value.toArray === "function" && - value.schema && - Array.isArray(value.schema.fields) - ); -} - -function getArrowTableSchema(table) { - return table.schema.fields.map(getArrowFieldSchema); -} - -function getArrowFieldSchema(field) { - return { - name: field.name, - type: getArrowType(field.type), - nullable: field.nullable, - databaseType: String(field.type) - }; -} - -// https://github.com/apache/arrow/blob/89f9a0948961f6e94f1ef5e4f310b707d22a3c11/js/src/enum.ts#L140-L141 -function getArrowType(type) { - switch (type.typeId) { - case 2: // Int - return "integer"; - case 3: // Float - case 7: // Decimal - return "number"; - case 4: // Binary - case 15: // FixedSizeBinary - return "buffer"; - case 5: // Utf8 - return "string"; - case 6: // Bool - return "boolean"; - case 8: // Date - case 9: // Time - case 10: // Timestamp - return "date"; - case 12: // List - case 16: // FixedSizeList - return "array"; - case 13: // Struct - case 14: // Union - return "object"; - case 11: // Interval - case 17: // Map - default: - return "other"; - } -} - -async function loadArrow() { - return await import(`${cdn}${arrow11.resolve()}`); -} - -// Adapted from https://observablehq.com/@cmudig/duckdb-client -// Copyright 2021 CMU Data Interaction Group -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -let promise; - -class DuckDBClient { - constructor(db) { - Object.defineProperties(this, { - _db: {value: db} - }); - } - - async queryStream(query, params) { - const connection = await this._db.connect(); - let reader, batch; - try { - if (params?.length > 0) { - const statement = await connection.prepare(query); - reader = await statement.send(...params); - } else { - reader = await connection.send(query); - } - batch = await reader.next(); - if (batch.done) throw new Error("missing first batch"); - } catch (error) { - await connection.close(); - throw error; - } - return { - schema: getArrowTableSchema(batch.value), - async *readRows() { - try { - while (!batch.done) { - yield batch.value.toArray(); - batch = await reader.next(); - } - } finally { - await connection.close(); - } - } - }; - } - - async query(query, params) { - const result = await this.queryStream(query, params); - const results = []; - for await (const rows of result.readRows()) { - for (const row of rows) { - results.push(row); - } - } - results.schema = result.schema; - return results; - } - - async queryRow(query, params) { - const result = await this.queryStream(query, params); - const reader = result.readRows(); - try { - const {done, value} = await reader.next(); - return done || !value.length ? null : value[0]; - } finally { - await reader.return(); - } - } - - async sql(strings, ...args) { - return await this.query(strings.join("?"), args); - } - - queryTag(strings, ...params) { - return [strings.join("?"), params]; - } - - escape(name) { - return `"${name}"`; - } - - async describeTables() { - const tables = await this.query(`SHOW TABLES`); - return tables.map(({name}) => ({name})); - } - - async describeColumns({table} = {}) { - const columns = await this.query(`DESCRIBE ${this.escape(table)}`); - return columns.map(({column_name, column_type, null: nullable}) => ({ - name: column_name, - type: getDuckDBType(column_type), - nullable: nullable !== "NO", - databaseType: column_type - })); - } - - static async of(sources = {}, config = {}) { - const db = await createDuckDB(); - if (config.query?.castTimestampToDate === undefined) { - config = {...config, query: {...config.query, castTimestampToDate: true}}; - } - if (config.query?.castBigIntToDouble === undefined) { - config = {...config, query: {...config.query, castBigIntToDouble: true}}; - } - await db.open(config); - await Promise.all( - Object.entries(sources).map(async ([name, source]) => { - if (source instanceof FileAttachment) { // bare file - await insertFile(db, name, source); - } else if (isArrowTable(source)) { // bare arrow table - await insertArrowTable(db, name, source); - } else if (Array.isArray(source)) { // bare array of objects - await insertArray(db, name, source); - } else if (isArqueroTable(source)) { - await insertArqueroTable(db, name, source); - } else if ("data" in source) { // data + options - const {data, ...options} = source; - if (isArrowTable(data)) { - await insertArrowTable(db, name, data, options); - } else { - await insertArray(db, name, data, options); - } - } else if ("file" in source) { // file + options - const {file, ...options} = source; - await insertFile(db, name, file, options); - } else { - throw new Error(`invalid source: ${source}`); - } - }) - ); - return new DuckDBClient(db); - } -} - -Object.defineProperty(DuckDBClient.prototype, "dialect", { - value: "duckdb" -}); - -async function insertFile(database, name, file, options) { - const url = await file.url(); - if (url.startsWith("blob:")) { - const buffer = await file.arrayBuffer(); - await database.registerFileBuffer(file.name, new Uint8Array(buffer)); - } else { - await database.registerFileURL(file.name, url, 4); // duckdb.DuckDBDataProtocol.HTTP - } - const connection = await database.connect(); - try { - switch (file.mimeType) { - case "text/csv": - case "text/tab-separated-values": { - return await connection.insertCSVFromPath(file.name, { - name, - schema: "main", - ...options - }).catch(async (error) => { - // If initial attempt to insert CSV resulted in a conversion - // error, try again, this time treating all columns as strings. - if (error.toString().includes("Could not convert")) { - return await insertUntypedCSV(connection, file, name); - } - throw error; - }); - } - case "application/json": - return await connection.insertJSONFromPath(file.name, { - name, - schema: "main", - ...options - }); - default: - if (/\.arrow$/i.test(file.name)) { - const buffer = new Uint8Array(await file.arrayBuffer()); - return await connection.insertArrowFromIPCStream(buffer, { - name, - schema: "main", - ...options - }); - } - if (/\.parquet$/i.test(file.name)) { - return await connection.query( - `CREATE VIEW '${name}' AS SELECT * FROM parquet_scan('${file.name}')` - ); - } - throw new Error(`unknown file type: ${file.mimeType}`); - } - } finally { - await connection.close(); - } -} - -async function insertUntypedCSV(connection, file, name) { - const statement = await connection.prepare( - `CREATE TABLE '${name}' AS SELECT * FROM read_csv_auto(?, ALL_VARCHAR=TRUE)` - ); - return await statement.send(file.name); -} - -async function insertArrowTable(database, name, table, options) { - const connection = await database.connect(); - try { - await connection.insertArrowTable(table, { - name, - schema: "main", - ...options - }); - } finally { - await connection.close(); - } -} - -async function insertArqueroTable(database, name, source) { - // TODO When we have stdlib versioning and can upgrade Arquero to version 5, - // we can then call source.toArrow() directly, with insertArrowTable() - const arrow = await loadArrow(); - const table = arrow.tableFromIPC(source.toArrowBuffer()); - return await insertArrowTable(database, name, table); -} - -async function insertArray(database, name, array, options) { - const arrow = await loadArrow(); - const table = arrow.tableFromJSON(array); - return await insertArrowTable(database, name, table, options); -} - -async function loadDuckDB() { - const module = await import(`${cdn}${duckdb.resolve()}`); - const bundle = await module.selectBundle({ - mvp: { - mainModule: `${cdn}${duckdb.resolve("dist/duckdb-mvp.wasm")}`, - mainWorker: `${cdn}${duckdb.resolve("dist/duckdb-browser-mvp.worker.js")}` - }, - eh: { - mainModule: `${cdn}${duckdb.resolve("dist/duckdb-eh.wasm")}`, - mainWorker: `${cdn}${duckdb.resolve("dist/duckdb-browser-eh.worker.js")}` - } - }); - const logger = new module.ConsoleLogger(); - return {module, bundle, logger}; -} - -async function createDuckDB() { - if (promise === undefined) promise = loadDuckDB(); - const {module, bundle, logger} = await promise; - const worker = await module.createWorker(bundle.mainWorker); - const db = new module.AsyncDuckDB(logger, worker); - await db.instantiate(bundle.mainModule); - return db; -} - -// https://duckdb.org/docs/sql/data_types/overview -function getDuckDBType(type) { - switch (type) { - case "BIGINT": - case "HUGEINT": - case "UBIGINT": - return "bigint"; - case "DOUBLE": - case "REAL": - case "FLOAT": - return "number"; - case "INTEGER": - case "SMALLINT": - case "TINYINT": - case "USMALLINT": - case "UINTEGER": - case "UTINYINT": - return "integer"; - case "BOOLEAN": - return "boolean"; - case "DATE": - case "TIMESTAMP": - case "TIMESTAMP WITH TIME ZONE": - return "date"; - case "VARCHAR": - case "UUID": - return "string"; - // case "BLOB": - // case "INTERVAL": - // case "TIME": - default: - if (/^DECIMAL\(/.test(type)) return "integer"; - return "other"; - } -} - -const nChecks = 20; // number of values to check in each array - -// We support two levels of DatabaseClient. The simplest DatabaseClient -// implements only the client.sql tagged template literal. More advanced -// DatabaseClients implement client.query and client.queryStream, which support -// streaming and abort, and the client.queryTag tagged template literal is used -// to translate the contents of a SQL cell or Table cell into the appropriate -// arguments for calling client.query or client.queryStream. For table cells, we -// additionally require client.describeColumns. The client.describeTables method -// is optional. -function isDatabaseClient(value, mode) { - return ( - value && - (typeof value.sql === "function" || - (typeof value.queryTag === "function" && - (typeof value.query === "function" || - typeof value.queryStream === "function"))) && - (mode !== "table" || typeof value.describeColumns === "function") && - value !== __query // don’t match our internal helper - ); -} - -// Returns true if the value is a typed array (for a single-column table), or if -// it’s an array. In the latter case, the elements of the array must be -// consistently typed: either plain objects or primitives or dates. -function isDataArray(value) { - return ( - (Array.isArray(value) && - (isQueryResultSetSchema(value.schema) || - isQueryResultSetColumns(value.columns) || - arrayContainsObjects(value) || - arrayContainsPrimitives(value) || - arrayContainsDates(value))) || - isTypedArray(value) - ); -} - -// Given an array, checks that the given value is an array that does not contain -// any primitive values (at least for the first few values that we check), and -// that the first object contains enumerable keys (see computeSchema for how we -// infer the columns). We assume that the contents of the table are homogenous, -// but we don’t currently enforce this. -// https://observablehq.com/@observablehq/database-client-specification#§1 -function arrayContainsObjects(value) { - const n = Math.min(nChecks, value.length); - for (let i = 0; i < n; ++i) { - const v = value[i]; - if (v === null || typeof v !== "object") return false; - } - return n > 0 && objectHasEnumerableKeys(value[0]); -} - -// Using a for-in loop here means that we can abort after finding at least one -// enumerable key (whereas Object.keys would require materializing the array of -// all keys, which would be considerably slower if the value has many keys!). -// This function assumes that value is an object; see arrayContainsObjects. -function objectHasEnumerableKeys(value) { - for (const _ in value) return true; - return false; -} - -function isQueryResultSetSchema(schemas) { - return ( - Array.isArray(schemas) && - schemas.every(isColumnSchema) - ); -} - -function isQueryResultSetColumns(columns) { - return (Array.isArray(columns) && columns.every((name) => typeof name === "string")); -} - -function isColumnSchema(schema) { - return schema && typeof schema.name === "string" && typeof schema.type === "string"; -} - -// Returns true if the value represents an array of primitives (i.e., a -// single-column table). This should only be passed values for which -// isDataArray returns true. -function arrayIsPrimitive(value) { - return ( - isTypedArray(value) || - arrayContainsPrimitives(value) || - arrayContainsDates(value) - ); -} - -// Given an array, checks that the first n elements are primitives (number, -// string, boolean, bigint) of a consistent type. -function arrayContainsPrimitives(value) { - const n = Math.min(nChecks, value.length); - if (!(n > 0)) return false; - let type; - let hasPrimitive = false; // ensure we encounter 1+ primitives - for (let i = 0; i < n; ++i) { - const v = value[i]; - if (v == null) continue; // ignore null and undefined - const t = typeof v; - if (type === undefined) { - switch (t) { - case "number": - case "boolean": - case "string": - case "bigint": - type = t; - break; - default: - return false; - } - } else if (t !== type) { - return false; - } - hasPrimitive = true; - } - return hasPrimitive; -} - -// Given an array, checks that the first n elements are dates. -function arrayContainsDates(value) { - const n = Math.min(nChecks, value.length); - if (!(n > 0)) return false; - let hasDate = false; // ensure we encounter 1+ dates - for (let i = 0; i < n; ++i) { - const v = value[i]; - if (v == null) continue; // ignore null and undefined - if (!(v instanceof Date)) return false; - hasDate = true; - } - return hasDate; -} - -function isTypedArray(value) { - return ( - value instanceof Int8Array || - value instanceof Int16Array || - value instanceof Int32Array || - value instanceof Uint8Array || - value instanceof Uint8ClampedArray || - value instanceof Uint16Array || - value instanceof Uint32Array || - value instanceof Float32Array || - value instanceof Float64Array - ); -} - -// __query is used by table cells; __query.sql is used by SQL cells. -const __query = Object.assign( - async (source, operations, invalidation, name) => { - source = await loadTableDataSource(await source, name); - if (isDatabaseClient(source)) return evaluateQuery(source, makeQueryTemplate(operations, source), invalidation); - if (isDataArray(source)) return __table(source, operations); - if (!source) throw new Error("missing data source"); - throw new Error("invalid data source"); - }, - { - sql(source, invalidation, name) { - return async function () { - return evaluateQuery(await loadSqlDataSource(await source, name), arguments, invalidation); - }; - } - } -); - -// We use a weak map to cache loaded data sources by key so that we don’t have -// to e.g. create separate SQLiteDatabaseClients every time we’re querying the -// same SQLite file attachment. Since this is a weak map, unused references will -// be garbage collected when they are no longer desired. Note: the name should -// be consistent, as it is not part of the cache key! -function sourceCache(loadSource) { - const cache = new WeakMap(); - return (source, name) => { - if (!source || typeof source !== "object") throw new Error("invalid data source"); - let promise = cache.get(source); - if (!promise || (isDataArray(source) && source.length !== promise._numRows)) { - // Warning: do not await here! We need to populate the cache synchronously. - promise = loadSource(source, name); - promise._numRows = source.length; // This will be undefined for DatabaseClients - cache.set(source, promise); - } - return promise; - }; -} - -const loadTableDataSource = sourceCache(async (source, name) => { - if (source instanceof FileAttachment) { - switch (source.mimeType) { - case "text/csv": return source.csv(); - case "text/tab-separated-values": return source.tsv(); - case "application/json": return source.json(); - case "application/x-sqlite3": return source.sqlite(); - } - if (/\.(arrow|parquet)$/i.test(source.name)) return loadDuckDBClient(source, name); - throw new Error(`unsupported file type: ${source.mimeType}`); - } - if (isArrowTable(source) || isArqueroTable(source)) return loadDuckDBClient(source, name); - if (isDataArray(source) && arrayIsPrimitive(source)) - return Array.from(source, (value) => ({value})); - return source; -}); - -const loadSqlDataSource = sourceCache(async (source, name) => { - if (source instanceof FileAttachment) { - switch (source.mimeType) { - case "text/csv": - case "text/tab-separated-values": - case "application/json": return loadDuckDBClient(source, name); - case "application/x-sqlite3": return source.sqlite(); - } - if (/\.(arrow|parquet)$/i.test(source.name)) return loadDuckDBClient(source, name); - throw new Error(`unsupported file type: ${source.mimeType}`); - } - if (isDataArray(source)) return loadDuckDBClient(await asArrowTable(source, name), name); - if (isArrowTable(source) || isArqueroTable(source)) return loadDuckDBClient(source, name); - return source; -}); - -async function asArrowTable(array, name) { - const arrow = await loadArrow(); - return arrayIsPrimitive(array) - ? arrow.tableFromArrays({[name]: array}) - : arrow.tableFromJSON(array); -} - -function loadDuckDBClient( - source, - name = source instanceof FileAttachment - ? getFileSourceName(source) - : "__table" -) { - return DuckDBClient.of({[name]: source}); -} - -function getFileSourceName(file) { - return file.name - .replace(/@\d+(?=\.|$)/, "") // strip Observable file version number - .replace(/\.\w+$/, ""); // strip file extension -} - -async function evaluateQuery(source, args, invalidation) { - if (!source) throw new Error("missing data source"); - - // If this DatabaseClient supports abort and streaming, use that. - if (typeof source.queryTag === "function") { - const abortController = new AbortController(); - const options = {signal: abortController.signal}; - invalidation.then(() => abortController.abort("invalidated")); - if (typeof source.queryStream === "function") { - return accumulateQuery( - source.queryStream(...source.queryTag.apply(source, args), options) - ); - } - if (typeof source.query === "function") { - return source.query(...source.queryTag.apply(source, args), options); - } - } - - // Otherwise, fallback to the basic sql tagged template literal. - if (typeof source.sql === "function") { - return source.sql.apply(source, args); - } - - // TODO: test if source is a file attachment, and support CSV etc. - throw new Error("source does not implement query, queryStream, or sql"); -} - -// Generator function that yields accumulated query results client.queryStream -async function* accumulateQuery(queryRequest) { - let then = performance.now(); - const queryResponse = await queryRequest; - const values = []; - values.done = false; - values.error = null; - values.schema = queryResponse.schema; - try { - for await (const rows of queryResponse.readRows()) { - if (performance.now() - then > 150 && values.length > 0) { - yield values; - then = performance.now(); - } - for (const value of rows) { - values.push(value); - } - } - values.done = true; - yield values; - } catch (error) { - values.error = error; - yield values; - } -} - -/** - * Returns a SQL query in the form [[parts], ...params] where parts is an array - * of sub-strings and params are the parameter values to be inserted between each - * sub-string. - */ -function makeQueryTemplate(operations, source) { - const escaper = - typeof source.escape === "function" ? source.escape : (i) => i; - const {select, from, filter, sort, slice} = operations; - if (!from.table) - throw new Error("missing from table"); - if (select.columns && select.columns.length === 0) - throw new Error("at least one column must be selected"); - const names = new Map(operations.names?.map(({column, name}) => [column, name])); - const columns = select.columns ? select.columns.map((column) => { - const override = names.get(column); - return override ? `${escaper(column)} AS ${escaper(override)}` : escaper(column); - }).join(", ") : "*"; - const args = [ - [`SELECT ${columns} FROM ${formatTable(from.table, escaper)}`] - ]; - for (let i = 0; i < filter.length; ++i) { - appendSql(i ? `\nAND ` : `\nWHERE `, args); - appendWhereEntry(filter[i], args, escaper); - } - for (let i = 0; i < sort.length; ++i) { - appendSql(i ? `, ` : `\nORDER BY `, args); - appendOrderBy(sort[i], args, escaper); - } - if (source.dialect === "mssql" || source.dialect === "oracle") { - if (slice.to !== null || slice.from !== null) { - if (!sort.length) { - if (!select.columns) - throw new Error( - "at least one column must be explicitly specified. Received '*'." - ); - appendSql(`\nORDER BY `, args); - appendOrderBy( - {column: select.columns[0], direction: "ASC"}, - args, - escaper - ); - } - appendSql(`\nOFFSET ${slice.from || 0} ROWS`, args); - appendSql( - `\nFETCH NEXT ${ - slice.to !== null ? slice.to - (slice.from || 0) : 1e9 - } ROWS ONLY`, - args - ); - } - } else { - if (slice.to !== null || slice.from !== null) { - appendSql( - `\nLIMIT ${slice.to !== null ? slice.to - (slice.from || 0) : 1e9}`, - args - ); - } - if (slice.from !== null) { - appendSql(` OFFSET ${slice.from}`, args); - } - } - return args; -} - -function formatTable(table, escaper) { - if (typeof table === "object") { // i.e., not a bare string specifier - let from = ""; - if (table.database != null) from += escaper(table.database) + "."; - if (table.schema != null) from += escaper(table.schema) + "."; - from += escaper(table.table); - return from; - } else { - return escaper(table); - } -} - -function appendSql(sql, args) { - const strings = args[0]; - strings[strings.length - 1] += sql; -} - -function appendOrderBy({column, direction}, args, escaper) { - appendSql(`${escaper(column)} ${direction.toUpperCase()}`, args); -} - -function appendWhereEntry({type, operands}, args, escaper) { - if (operands.length < 1) throw new Error("Invalid operand length"); - - // Unary operations - // We treat `v` and `nv` as `NULL` and `NOT NULL` unary operations in SQL, - // since the database already validates column types. - if (operands.length === 1 || type === "v" || type === "nv") { - appendOperand(operands[0], args, escaper); - switch (type) { - case "n": - case "nv": - appendSql(` IS NULL`, args); - return; - case "nn": - case "v": - appendSql(` IS NOT NULL`, args); - return; - default: - throw new Error("Invalid filter operation"); - } - } - - // Binary operations - if (operands.length === 2) { - if (["in", "nin"].includes(type)) ; else if (["c", "nc"].includes(type)) { - // TODO: Case (in)sensitive? - appendOperand(operands[0], args, escaper); - switch (type) { - case "c": - appendSql(` LIKE `, args); - break; - case "nc": - appendSql(` NOT LIKE `, args); - break; - } - appendOperand(likeOperand(operands[1]), args, escaper); - return; - } else { - appendOperand(operands[0], args, escaper); - switch (type) { - case "eq": - appendSql(` = `, args); - break; - case "ne": - appendSql(` <> `, args); - break; - case "gt": - appendSql(` > `, args); - break; - case "lt": - appendSql(` < `, args); - break; - case "gte": - appendSql(` >= `, args); - break; - case "lte": - appendSql(` <= `, args); - break; - default: - throw new Error("Invalid filter operation"); - } - appendOperand(operands[1], args, escaper); - return; - } - } - - // List operations - appendOperand(operands[0], args, escaper); - switch (type) { - case "in": - appendSql(` IN (`, args); - break; - case "nin": - appendSql(` NOT IN (`, args); - break; - default: - throw new Error("Invalid filter operation"); - } - appendListOperands(operands.slice(1), args); - appendSql(")", args); -} - -function appendOperand(o, args, escaper) { - if (o.type === "column") { - appendSql(escaper(o.value), args); - } else { - args.push(o.value); - args[0].push(""); - } -} - -// TODO: Support column operands here? -function appendListOperands(ops, args) { - let first = true; - for (const op of ops) { - if (first) first = false; - else appendSql(",", args); - args.push(op.value); - args[0].push(""); - } -} - -function likeOperand(operand) { - return {...operand, value: `%${operand.value}%`}; -} - -// Comparator function that moves null values (undefined, null, NaN) to the -// end of the array. -function defined(a, b) { - return (a == null || !(a >= a)) - (b == null || !(b >= b)); -} - -// Comparator function that sorts values in ascending order, with null values at -// the end. -function ascendingDefined(a, b) { - return defined(a, b) || (a < b ? -1 : a > b ? 1 : 0); -} - -// Comparator function that sorts values in descending order, with null values -// at the end. -function descendingDefined(a, b) { - return defined(a, b) || (a > b ? -1 : a < b ? 1 : 0); -} - -// Functions for checking type validity -const isValidNumber = (value) => typeof value === "number" && !Number.isNaN(value); -const isValidInteger = (value) => Number.isInteger(value) && !Number.isNaN(value); -const isValidString = (value) => typeof value === "string"; -const isValidBoolean = (value) => typeof value === "boolean"; -const isValidBigint = (value) => typeof value === "bigint"; -const isValidDate = (value) => value instanceof Date && !isNaN(value); -const isValidBuffer = (value) => value instanceof ArrayBuffer; -const isValidArray = (value) => Array.isArray(value); -const isValidObject = (value) => typeof value === "object" && value !== null; -const isValidOther = (value) => value != null; - -// Function to get the correct validity checking function based on type -function getTypeValidator(colType) { - switch (colType) { - case "string": - return isValidString; - case "bigint": - return isValidBigint; - case "boolean": - return isValidBoolean; - case "number": - return isValidNumber; - case "integer": - return isValidInteger; - case "date": - return isValidDate; - case "buffer": - return isValidBuffer; - case "array": - return isValidArray; - case "object": - return isValidObject; - case "other": - default: - return isValidOther; - } -} - -// Accepts dates in the form of ISOString and LocaleDateString, with or without time -const DATE_TEST = /^(([-+]\d{2})?\d{4}(-\d{2}(-\d{2}))|(\d{1,2})\/(\d{1,2})\/(\d{2,4}))([T ]\d{2}:\d{2}(:\d{2}(\.\d{3})?)?(Z|[-+]\d{2}:\d{2})?)?$/; - -function coerceToType(value, type) { - switch (type) { - case "string": - return typeof value === "string" || value == null ? value : String(value); - case "boolean": - if (typeof value === "string") { - const trimValue = value.trim().toLowerCase(); - return trimValue === "true" - ? true - : trimValue === "false" - ? false - : null; - } - return typeof value === "boolean" || value == null - ? value - : Boolean(value); - case "bigint": - return typeof value === "bigint" || value == null - ? value - : Number.isInteger(typeof value === "string" && !value.trim() ? NaN : +value) - ? BigInt(value) // eslint-disable-line no-undef - : undefined; - case "integer": // not a target type for coercion, but can be inferred - case "number": { - return typeof value === "number" - ? value - : value == null || (typeof value === "string" && !value.trim()) - ? NaN - : Number(value); - } - case "date": { - if (value instanceof Date || value == null) return value; - if (typeof value === "number") return new Date(value); - const trimValue = String(value).trim(); - if (typeof value === "string" && !trimValue) return null; - return new Date(DATE_TEST.test(trimValue) ? trimValue : NaN); - } - case "array": - case "object": - case "buffer": - case "other": - return value; - default: - throw new Error(`Unable to coerce to type: ${type}`); - } -} - -function getSchema(source) { - const {columns} = source; - let {schema} = source; - if (!isQueryResultSetSchema(schema)) { - schema = inferSchema(source, isQueryResultSetColumns(columns) ? columns : undefined); - return {schema, inferred: true}; - } - return {schema, inferred: false}; -} - -// This function infers a schema from the source data, if one doesn't already -// exist, and merges type assertions into that schema. If the schema was -// inferred or if there are type assertions, it then coerces the rows in the -// source data to the types specified in the schema. -function applyTypes(source, operations) { - const input = source; - let {schema, inferred} = getSchema(source); - const types = new Map(schema.map(({name, type}) => [name, type])); - if (operations.types) { - for (const {name, type} of operations.types) { - types.set(name, type); - // update schema with user-selected type - if (schema === input.schema) schema = schema.slice(); // copy on write - const colIndex = schema.findIndex((col) => col.name === name); - if (colIndex > -1) schema[colIndex] = {...schema[colIndex], type}; - } - source = source.map(d => coerceRow(d, types, schema)); - } else if (inferred) { - // Coerce data according to new schema, unless that happened due to - // operations.types, above. - source = source.map(d => coerceRow(d, types, schema)); - } - return {source, schema}; -} - -function applyNames(source, operations) { - if (!operations.names) return source; - const overridesByName = new Map(operations.names.map((n) => [n.column, n])); - return source.map((d) => - Object.fromEntries(Object.keys(d).map((k) => { - const override = overridesByName.get(k); - return [override?.name ?? k, d[k]]; - })) - ); -} - -// This function applies table cell operations to an in-memory table (array of -// objects); it should be equivalent to the corresponding SQL query. TODO Use -// DuckDBClient for data arrays, too, and then we wouldn’t need our own __table -// function to do table operations on in-memory data? -function __table(source, operations) { - const errors = new Map(); - const input = source; - const typed = applyTypes(source, operations); - source = typed.source; - let schema = typed.schema; - if (operations.derive) { - // Derived columns may depend on coerced values from the original data source, - // so we must evaluate derivations after the initial inference and coercion - // step. - const derivedSource = []; - operations.derive.map(({name, value}) => { - let columnErrors = []; - // Derived column formulas may reference renamed columns, so we must - // compute derivations on the renamed source. However, we don't modify the - // source itself with renamed names until after the other operations are - // applied, because operations like filter and sort reference original - // column names. - // TODO Allow derived columns to reference other derived columns. - applyNames(source, operations).map((row, index) => { - let resolved; - try { - // TODO Support referencing `index` and `rows` in the derive function. - resolved = value(row); - } catch (error) { - columnErrors.push({index, error}); - resolved = undefined; - } - if (derivedSource[index]) { - derivedSource[index] = {...derivedSource[index], [name]: resolved}; - } else { - derivedSource.push({[name]: resolved}); - } - }); - if (columnErrors.length) errors.set(name, columnErrors); - }); - // Since derived columns are untyped by default, we do a pass of type - // inference and coercion after computing the derived values. - const typedDerived = applyTypes(derivedSource, operations); - // Merge derived source and schema with the source dataset. - source = source.map((row, i) => ({...row, ...typedDerived.source[i]})); - schema = [...schema, ...typedDerived.schema]; - } - for (const {type, operands} of operations.filter) { - const [{value: column}] = operands; - const values = operands.slice(1).map(({value}) => value); - switch (type) { - // valid (matches the column type) - case "v": { - const [colType] = values; - const isValid = getTypeValidator(colType); - source = source.filter(d => isValid(d[column])); - break; - } - // not valid (doesn't match the column type) - case "nv": { - const [colType] = values; - const isValid = getTypeValidator(colType); - source = source.filter(d => !isValid(d[column])); - break; - } - case "eq": { - const [value] = values; - if (value instanceof Date) { - const time = +value; // compare as primitive - source = source.filter((d) => +d[column] === time); - } else { - source = source.filter((d) => d[column] === value); - } - break; - } - case "ne": { - const [value] = values; - source = source.filter((d) => d[column] !== value); - break; - } - case "c": { - const [value] = values; - source = source.filter( - (d) => typeof d[column] === "string" && d[column].includes(value) - ); - break; - } - case "nc": { - const [value] = values; - source = source.filter( - (d) => typeof d[column] === "string" && !d[column].includes(value) - ); - break; - } - case "in": { - const set = new Set(values); // TODO support dates? - source = source.filter((d) => set.has(d[column])); - break; - } - case "nin": { - const set = new Set(values); // TODO support dates? - source = source.filter((d) => !set.has(d[column])); - break; - } - case "n": { - source = source.filter((d) => d[column] == null); - break; - } - case "nn": { - source = source.filter((d) => d[column] != null); - break; - } - case "lt": { - const [value] = values; - source = source.filter((d) => d[column] < value); - break; - } - case "lte": { - const [value] = values; - source = source.filter((d) => d[column] <= value); - break; - } - case "gt": { - const [value] = values; - source = source.filter((d) => d[column] > value); - break; - } - case "gte": { - const [value] = values; - source = source.filter((d) => d[column] >= value); - break; - } - default: - throw new Error(`unknown filter type: ${type}`); - } - } - for (const {column, direction} of reverse(operations.sort)) { - const compare = direction === "desc" ? descendingDefined : ascendingDefined; - if (source === input) source = source.slice(); // defensive copy - source.sort((a, b) => compare(a[column], b[column])); - } - let {from, to} = operations.slice; - from = from == null ? 0 : Math.max(0, from); - to = to == null ? Infinity : Math.max(0, to); - if (from > 0 || to < Infinity) { - source = source.slice(Math.max(0, from), Math.max(0, to)); - } - // Preserve the schema for all columns. - let fullSchema = schema.slice(); - if (operations.select.columns) { - if (schema) { - const schemaByName = new Map(schema.map((s) => [s.name, s])); - schema = operations.select.columns.map((c) => schemaByName.get(c)); - } - source = source.map((d) => - Object.fromEntries(operations.select.columns.map((c) => [c, d[c]])) - ); - } - if (operations.names) { - const overridesByName = new Map(operations.names.map((n) => [n.column, n])); - if (schema) { - schema = schema.map((s) => { - const override = overridesByName.get(s.name); - return ({...s, ...(override ? {name: override.name} : null)}); - }); - } - if (fullSchema) { - fullSchema = fullSchema.map((s) => { - const override = overridesByName.get(s.name); - return ({...s, ...(override ? {name: override.name} : null)}); - }); - } - source = applyNames(source, operations); - } - if (source !== input) { - if (schema) source.schema = schema; - } - source.fullSchema = fullSchema; - source.errors = errors; - return source; -} - -function coerceRow(object, types, schema) { - const coerced = {}; - for (const col of schema) { - const type = types.get(col.name); - const value = object[col.name]; - coerced[col.name] = type === "raw" ? value : coerceToType(value, type); - } - return coerced; -} - -function createTypeCount() { - return { - boolean: 0, - integer: 0, - number: 0, - date: 0, - string: 0, - array: 0, - object: 0, - bigint: 0, - buffer: 0, - defined: 0 - }; -} - -// Caution: the order below matters! 🌶️ The first one that passes the ≥90% test -// should be the one that we chose, and therefore these types should be listed -// from most specific to least specific. -const types$2 = [ - "boolean", - "integer", - "number", - "date", - "bigint", - "array", - "object", - "buffer" - // Note: "other" and "string" are intentionally omitted; see below! -]; - -// We need to show *all* keys present in the array of Objects -function getAllKeys(rows) { - const keys = new Set(); - for (const row of rows) { - // avoid crash if row is null or undefined - if (row) { - // only enumerable properties - for (const key in row) { - // only own properties - if (Object.prototype.hasOwnProperty.call(row, key)) { - // unique properties, in the order they appear - keys.add(key); - } - } - } - } - return Array.from(keys); -} - -function inferSchema(source, columns = getAllKeys(source)) { - const schema = []; - const sampleSize = 100; - const sample = source.slice(0, sampleSize); - for (const col of columns) { - const colCount = createTypeCount(); - for (const d of sample) { - let value = d[col]; - if (value == null) continue; - const type = typeof value; - if (type !== "string") { - ++colCount.defined; - if (Array.isArray(value)) ++colCount.array; - else if (value instanceof Date) ++colCount.date; - else if (value instanceof ArrayBuffer) ++colCount.buffer; - else if (type === "number") { - ++colCount.number; - if (Number.isInteger(value)) ++colCount.integer; - } - // bigint, boolean, or object - else if (type in colCount) ++colCount[type]; - } else { - value = value.trim(); - if (!value) continue; - ++colCount.defined; - ++colCount.string; - if (/^(true|false)$/i.test(value)) { - ++colCount.boolean; - } else if (value && !isNaN(value)) { - ++colCount.number; - if (Number.isInteger(+value)) ++colCount.integer; - } else if (DATE_TEST.test(value)) ++colCount.date; - } - } - // Chose the non-string, non-other type with the greatest count that is also - // ≥90%; or if no such type meets that criterion, fallback to string if - // ≥90%; and lastly fallback to other. - const minCount = Math.max(1, colCount.defined * 0.9); - const type = - greatest(types$2, (type) => - colCount[type] >= minCount ? colCount[type] : NaN - ) ?? (colCount.string >= minCount ? "string" : "other"); - schema.push({ - name: col, - type: type, - inferred: type - }); - } - return schema; -} - -class Workbook { - constructor(workbook) { - Object.defineProperties(this, { - _: {value: workbook}, - sheetNames: { - value: workbook.worksheets.map((s) => s.name), - enumerable: true - } - }); - } - sheet(name, options) { - const sname = - typeof name === "number" - ? this.sheetNames[name] - : this.sheetNames.includes((name += "")) - ? name - : null; - if (sname == null) throw new Error(`Sheet not found: ${name}`); - const sheet = this._.getWorksheet(sname); - return extract(sheet, options); - } -} - -function extract(sheet, {range, headers} = {}) { - let [[c0, r0], [c1, r1]] = parseRange(range, sheet); - const headerRow = headers ? sheet._rows[r0++] : null; - let names = new Set(["#"]); - for (let n = c0; n <= c1; n++) { - const value = headerRow ? valueOf(headerRow.findCell(n + 1)) : null; - let name = (value && value + "") || toColumn(n); - while (names.has(name)) name += "_"; - names.add(name); - } - names = new Array(c0).concat(Array.from(names)); - - const output = new Array(r1 - r0 + 1); - for (let r = r0; r <= r1; r++) { - const row = (output[r - r0] = Object.create(null, {"#": {value: r + 1}})); - const _row = sheet.getRow(r + 1); - if (_row.hasValues) - for (let c = c0; c <= c1; c++) { - const value = valueOf(_row.findCell(c + 1)); - if (value != null) row[names[c + 1]] = value; - } - } - - output.columns = names.filter(() => true); // Filter sparse columns - return output; -} - -function valueOf(cell) { - if (!cell) return; - const {value} = cell; - if (value && typeof value === "object" && !(value instanceof Date)) { - if (value.formula || value.sharedFormula) { - return value.result && value.result.error ? NaN : value.result; - } - if (value.richText) { - return richText(value); - } - if (value.text) { - let {text} = value; - if (text.richText) text = richText(text); - return value.hyperlink && value.hyperlink !== text - ? `${value.hyperlink} ${text}` - : text; - } - return value; - } - return value; -} - -function richText(value) { - return value.richText.map((d) => d.text).join(""); -} - -function parseRange(specifier = ":", {columnCount, rowCount}) { - specifier += ""; - if (!specifier.match(/^[A-Z]*\d*:[A-Z]*\d*$/)) - throw new Error("Malformed range specifier"); - const [[c0 = 0, r0 = 0], [c1 = columnCount - 1, r1 = rowCount - 1]] = - specifier.split(":").map(fromCellReference); - return [ - [c0, r0], - [c1, r1] - ]; -} - -// Returns the default column name for a zero-based column index. -// For example: 0 -> "A", 1 -> "B", 25 -> "Z", 26 -> "AA", 27 -> "AB". -function toColumn(c) { - let sc = ""; - c++; - do { - sc = String.fromCharCode(64 + (c % 26 || 26)) + sc; - } while ((c = Math.floor((c - 1) / 26))); - return sc; -} - -// Returns the zero-based indexes from a cell reference. -// For example: "A1" -> [0, 0], "B2" -> [1, 1], "AA10" -> [26, 9]. -function fromCellReference(s) { - const [, sc, sr] = s.match(/^([A-Z]*)(\d*)$/); - let c = 0; - if (sc) - for (let i = 0; i < sc.length; i++) - c += Math.pow(26, sc.length - i - 1) * (sc.charCodeAt(i) - 64); - return [c ? c - 1 : undefined, sr ? +sr - 1 : undefined]; -} - -async function remote_fetch(file) { - const response = await fetch(await file.url()); - if (!response.ok) throw new Error(`Unable to load file: ${file.name}`); - return response; -} - -function enforceSchema(source, schema) { - const types = new Map(schema.map(({name, type}) => [name, type])); - return Object.assign(source.map(d => coerceRow(d, types, schema)), {schema}); -} - -async function dsv(file, delimiter, {array = false, typed = false} = {}) { - const text = await file.text(); - const parse = (delimiter === "\t" - ? (array ? tsvParseRows : tsvParse) - : (array ? csvParseRows : csvParse)); - if (typed === "auto" && !array) { - const source = parse(text); - return enforceSchema(source, inferSchema(source, source.columns)); - } - return parse(text, typed && autoType); -} - -class AbstractFile { - constructor(name, mimeType) { - Object.defineProperty(this, "name", {value: name, enumerable: true}); - if (mimeType !== undefined) Object.defineProperty(this, "mimeType", {value: mimeType + "", enumerable: true}); - } - async blob() { - return (await remote_fetch(this)).blob(); - } - async arrayBuffer() { - return (await remote_fetch(this)).arrayBuffer(); - } - async text() { - return (await remote_fetch(this)).text(); - } - async json() { - return (await remote_fetch(this)).json(); - } - async stream() { - return (await remote_fetch(this)).body; - } - async csv(options) { - return dsv(this, ",", options); - } - async tsv(options) { - return dsv(this, "\t", options); - } - async image(props) { - const url = await this.url(); - return new Promise((resolve, reject) => { - const i = new Image(); - if (new URL(url, document.baseURI).origin !== new URL(location).origin) { - i.crossOrigin = "anonymous"; - } - Object.assign(i, props); - i.onload = () => resolve(i); - i.onerror = () => reject(new Error(`Unable to load file: ${this.name}`)); - i.src = url; - }); - } - async arrow({version = 4} = {}) { - switch (version) { - case 4: { - const [Arrow, response] = await Promise.all([requireDefault(arrow4.resolve()), remote_fetch(this)]); - return Arrow.Table.from(response); - } - case 9: { - const [Arrow, response] = await Promise.all([import(`${cdn}${arrow9.resolve()}`), remote_fetch(this)]); - return Arrow.tableFromIPC(response); - } - case 11: { - const [Arrow, response] = await Promise.all([import(`${cdn}${arrow11.resolve()}`), remote_fetch(this)]); - return Arrow.tableFromIPC(response); - } - default: throw new Error(`unsupported arrow version: ${version}`); - } - } - async sqlite() { - return SQLiteDatabaseClient.open(remote_fetch(this)); - } - async zip() { - const [JSZip, buffer] = await Promise.all([requireDefault(jszip.resolve()), this.arrayBuffer()]); - return new ZipArchive(await JSZip.loadAsync(buffer)); - } - async xml(mimeType = "application/xml") { - return (new DOMParser).parseFromString(await this.text(), mimeType); - } - async html() { - return this.xml("text/html"); - } - async xlsx() { - const [ExcelJS, buffer] = await Promise.all([requireDefault(exceljs.resolve()), this.arrayBuffer()]); - return new Workbook(await new ExcelJS.Workbook().xlsx.load(buffer)); - } -} - -class FileAttachment extends AbstractFile { - constructor(url, name, mimeType) { - super(name, mimeType); - Object.defineProperty(this, "_url", {value: url}); - } - async url() { - return (await this._url) + ""; - } -} - -function NoFileAttachments(name) { - throw new Error(`File not found: ${name}`); -} - -function FileAttachments(resolve) { - return Object.assign( - name => { - const result = resolve(name += ""); - if (result == null) throw new Error(`File not found: ${name}`); - if (typeof result === "object" && "url" in result) { - const {url, mimeType} = result; - return new FileAttachment(url, name, mimeType); - } - return new FileAttachment(result, name); - }, - {prototype: FileAttachment.prototype} // instanceof - ); -} - -class ZipArchive { - constructor(archive) { - Object.defineProperty(this, "_", {value: archive}); - this.filenames = Object.keys(archive.files).filter(name => !archive.files[name].dir); - } - file(path) { - const object = this._.file(path += ""); - if (!object || object.dir) throw new Error(`file not found: ${path}`); - return new ZipArchiveEntry(object); - } -} - -class ZipArchiveEntry extends AbstractFile { - constructor(object) { - super(object.name); - Object.defineProperty(this, "_", {value: object}); - Object.defineProperty(this, "_url", {writable: true}); - } - async url() { - return this._url || (this._url = this.blob().then(URL.createObjectURL)); - } - async blob() { - return this._.async("blob"); - } - async arrayBuffer() { - return this._.async("arraybuffer"); - } - async text() { - return this._.async("text"); - } - async json() { - return JSON.parse(await this.text()); - } -} - -function canvas(width, height) { - var canvas = document.createElement("canvas"); - canvas.width = width; - canvas.height = height; - return canvas; -} - -function context2d(width, height, dpi) { - if (dpi == null) dpi = devicePixelRatio; - var canvas = document.createElement("canvas"); - canvas.width = width * dpi; - canvas.height = height * dpi; - canvas.style.width = width + "px"; - var context = canvas.getContext("2d"); - context.scale(dpi, dpi); - return context; -} - -function download(value, name = "untitled", label = "Save") { - const a = document.createElement("a"); - const b = a.appendChild(document.createElement("button")); - b.textContent = label; - a.download = name; - - async function reset() { - await new Promise(requestAnimationFrame); - URL.revokeObjectURL(a.href); - a.removeAttribute("href"); - b.textContent = label; - b.disabled = false; - } - - a.onclick = async event => { - b.disabled = true; - if (a.href) return reset(); // Already saved. - b.textContent = "Saving…"; - try { - const object = await (typeof value === "function" ? value() : value); - b.textContent = "Download"; - a.href = URL.createObjectURL(object); // eslint-disable-line require-atomic-updates - } catch (ignore) { - b.textContent = label; - } - if (event.eventPhase) return reset(); // Already downloaded. - b.disabled = false; - }; - - return a; -} - -var namespaces = { - math: "http://www.w3.org/1998/Math/MathML", - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" -}; - -function element(name, attributes) { - var prefix = name += "", i = prefix.indexOf(":"), value; - if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); - var element = namespaces.hasOwnProperty(prefix) // eslint-disable-line no-prototype-builtins - ? document.createElementNS(namespaces[prefix], name) - : document.createElement(name); - if (attributes) for (var key in attributes) { - prefix = key, i = prefix.indexOf(":"), value = attributes[key]; - if (i >= 0 && (prefix = key.slice(0, i)) !== "xmlns") key = key.slice(i + 1); - if (namespaces.hasOwnProperty(prefix)) element.setAttributeNS(namespaces[prefix], key, value); // eslint-disable-line no-prototype-builtins - else element.setAttribute(key, value); - } - return element; -} - -function input$1(type) { - var input = document.createElement("input"); - if (type != null) input.type = type; - return input; -} - -function range$1(min, max, step) { - if (arguments.length === 1) max = min, min = null; - var input = document.createElement("input"); - input.min = min = min == null ? 0 : +min; - input.max = max = max == null ? 1 : +max; - input.step = step == null ? "any" : step = +step; - input.type = "range"; - return input; -} - -function select(values) { - var select = document.createElement("select"); - Array.prototype.forEach.call(values, function(value) { - var option = document.createElement("option"); - option.value = option.textContent = value; - select.appendChild(option); - }); - return select; -} - -function svg$1(width, height) { - var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svg.setAttribute("viewBox", [0, 0, width, height]); - svg.setAttribute("width", width); - svg.setAttribute("height", height); - return svg; -} - -function text$1(value) { - return document.createTextNode(value); -} - -var count$1 = 0; - -function uid(name) { - return new Id("O-" + (name == null ? "" : name + "-") + ++count$1); -} - -function Id(id) { - this.id = id; - this.href = new URL(`#${id}`, location) + ""; -} - -Id.prototype.toString = function() { - return "url(" + this.href + ")"; -}; - -var DOM = /*#__PURE__*/Object.freeze({ -__proto__: null, -canvas: canvas, -context2d: context2d, -download: download, -element: element, -input: input$1, -range: range$1, -select: select, -svg: svg$1, -text: text$1, -uid: uid -}); - -function buffer(file) { - return new Promise(function(resolve, reject) { - var reader = new FileReader; - reader.onload = function() { resolve(reader.result); }; - reader.onerror = reject; - reader.readAsArrayBuffer(file); - }); -} - -function text(file) { - return new Promise(function(resolve, reject) { - var reader = new FileReader; - reader.onload = function() { resolve(reader.result); }; - reader.onerror = reject; - reader.readAsText(file); - }); -} - -function url(file) { - return new Promise(function(resolve, reject) { - var reader = new FileReader; - reader.onload = function() { resolve(reader.result); }; - reader.onerror = reject; - reader.readAsDataURL(file); - }); -} - -var Files = /*#__PURE__*/Object.freeze({ -__proto__: null, -buffer: buffer, -text: text, -url: url -}); - -function that() { - return this; -} - -function disposable(value, dispose) { - let done = false; - if (typeof dispose !== "function") { - throw new Error("dispose is not a function"); - } - return { - [Symbol.iterator]: that, - next: () => done ? {done: true} : (done = true, {done: false, value}), - return: () => (done = true, dispose(value), {done: true}), - throw: () => ({done: done = true}) - }; -} - -function* filter(iterator, test) { - var result, index = -1; - while (!(result = iterator.next()).done) { - if (test(result.value, ++index)) { - yield result.value; - } - } -} - -function observe(initialize) { - let stale = false; - let value; - let resolve; - const dispose = initialize(change); - - if (dispose != null && typeof dispose !== "function") { - throw new Error(typeof dispose.then === "function" - ? "async initializers are not supported" - : "initializer returned something, but not a dispose function"); - } - - function change(x) { - if (resolve) resolve(x), resolve = null; - else stale = true; - return value = x; - } - - function next() { - return {done: false, value: stale - ? (stale = false, Promise.resolve(value)) - : new Promise(_ => (resolve = _))}; - } - - return { - [Symbol.iterator]: that, - throw: () => ({done: true}), - return: () => (dispose != null && dispose(), {done: true}), - next - }; -} - -function input(input) { - return observe(function(change) { - var event = eventof(input), value = valueof$1(input); - function inputted() { change(valueof$1(input)); } - input.addEventListener(event, inputted); - if (value !== undefined) change(value); - return function() { input.removeEventListener(event, inputted); }; - }); -} - -function valueof$1(input) { - switch (input.type) { - case "range": - case "number": return input.valueAsNumber; - case "date": return input.valueAsDate; - case "checkbox": return input.checked; - case "file": return input.multiple ? input.files : input.files[0]; - case "select-multiple": return Array.from(input.selectedOptions, o => o.value); - default: return input.value; - } -} - -function eventof(input) { - switch (input.type) { - case "button": - case "submit": - case "checkbox": return "click"; - case "file": return "change"; - default: return "input"; - } -} - -function* map$1(iterator, transform) { - var result, index = -1; - while (!(result = iterator.next()).done) { - yield transform(result.value, ++index); - } -} - -function queue(initialize) { - let resolve; - const queue = []; - const dispose = initialize(push); - - if (dispose != null && typeof dispose !== "function") { - throw new Error(typeof dispose.then === "function" - ? "async initializers are not supported" - : "initializer returned something, but not a dispose function"); - } - - function push(x) { - queue.push(x); - if (resolve) resolve(queue.shift()), resolve = null; - return x; - } - - function next() { - return {done: false, value: queue.length - ? Promise.resolve(queue.shift()) - : new Promise(_ => (resolve = _))}; - } - - return { - [Symbol.iterator]: that, - throw: () => ({done: true}), - return: () => (dispose != null && dispose(), {done: true}), - next - }; -} - -function* range(start, stop, step) { - start = +start; - stop = +stop; - step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; - var i = -1, n = Math.max(0, Math.ceil((stop - start) / step)) | 0; - while (++i < n) { - yield start + i * step; - } -} - -function valueAt(iterator, i) { - if (!isFinite(i = +i) || i < 0 || i !== i | 0) return; - var result, index = -1; - while (!(result = iterator.next()).done) { - if (++index === i) { - return result.value; - } - } -} - -function worker(source) { - const url = URL.createObjectURL(new Blob([source], {type: "text/javascript"})); - const worker = new Worker(url); - return disposable(worker, () => { - worker.terminate(); - URL.revokeObjectURL(url); - }); -} - -var Generators$1 = /*#__PURE__*/Object.freeze({ -__proto__: null, -disposable: disposable, -filter: filter, -input: input, -map: map$1, -observe: observe, -queue: queue, -range: range, -valueAt: valueAt, -worker: worker -}); - -function template(render, wrapper) { - return function(strings) { - var string = strings[0], - parts = [], part, - root = null, - node, nodes, - walker, - i, n, j, m, k = -1; - - // Concatenate the text using comments as placeholders. - for (i = 1, n = arguments.length; i < n; ++i) { - part = arguments[i]; - if (part instanceof Node) { - parts[++k] = part; - string += ""; - } else if (Array.isArray(part)) { - for (j = 0, m = part.length; j < m; ++j) { - node = part[j]; - if (node instanceof Node) { - if (root === null) { - parts[++k] = root = document.createDocumentFragment(); - string += ""; - } - root.appendChild(node); - } else { - root = null; - string += node; - } - } - root = null; - } else { - string += part; - } - string += strings[i]; - } - - // Render the text. - root = render(string); - - // Walk the rendered content to replace comment placeholders. - if (++k > 0) { - nodes = new Array(k); - walker = document.createTreeWalker(root, NodeFilter.SHOW_COMMENT, null, false); - while (walker.nextNode()) { - node = walker.currentNode; - if (/^o:/.test(node.nodeValue)) { - nodes[+node.nodeValue.slice(2)] = node; - } - } - for (i = 0; i < k; ++i) { - if (node = nodes[i]) { - node.parentNode.replaceChild(parts[i], node); - } - } - } - - // Is the rendered content - // … a parent of a single child? Detach and return the child. - // … a document fragment? Replace the fragment with an element. - // … some other node? Return it. - return root.childNodes.length === 1 ? root.removeChild(root.firstChild) - : root.nodeType === 11 ? ((node = wrapper()).appendChild(root), node) - : root; - }; -} - -const html$1 = template(function(string) { - var template = document.createElement("template"); - template.innerHTML = string.trim(); - return document.importNode(template.content, true); -}, function() { - return document.createElement("span"); -}); - -async function leaflet(require) { - const L = await require(leaflet$1.resolve()); - if (!L._style) { - const link = document.createElement("link"); - link.rel = "stylesheet"; - link.href = await require.resolve(leaflet$1.resolve("dist/leaflet.css")); - L._style = document.head.appendChild(link); - } - return L; -} - -function md(require) { - return require(marked.resolve()).then(function(marked) { - return template( - function(string) { - var root = document.createElement("div"); - root.innerHTML = marked(string, {langPrefix: ""}).trim(); - var code = root.querySelectorAll("pre code[class]"); - if (code.length > 0) { - require(highlight.resolve()).then(function(hl) { - code.forEach(function(block) { - function done() { - hl.highlightBlock(block); - block.parentNode.classList.add("observablehq--md-pre"); - } - if (hl.getLanguage(block.className)) { - done(); - } else { - require(highlight.resolve("async-languages/index.js")) - .then(index => { - if (index.has(block.className)) { - return require(highlight.resolve("async-languages/" + index.get(block.className))).then(language => { - hl.registerLanguage(block.className, language); - }); - } - }) - .then(done, done); - } - }); - }); - } - return root; - }, - function() { - return document.createElement("div"); - } - ); - }); -} - -async function mermaid(require) { - const mer = await require(mermaid$1.resolve()); - mer.initialize({securityLevel: "loose", theme: "neutral"}); - return function mermaid() { - const root = document.createElement("div"); - root.innerHTML = mer.render(uid().id, String.raw.apply(String, arguments)); - return root.removeChild(root.firstChild); - }; -} - -function Mutable(value) { - let change; - Object.defineProperties(this, { - generator: {value: observe(_ => void (change = _))}, - value: {get: () => value, set: x => change(value = x)} // eslint-disable-line no-setter-return - }); - if (value !== undefined) change(value); -} - -function* now() { - while (true) { - yield Date.now(); - } -} - -function delay(duration, value) { - return new Promise(function(resolve) { - setTimeout(function() { - resolve(value); - }, duration); - }); -} - -var timeouts = new Map; - -function timeout(now, time) { - var t = new Promise(function(resolve) { - timeouts.delete(time); - var delay = time - now; - if (!(delay > 0)) throw new Error("invalid time"); - if (delay > 0x7fffffff) throw new Error("too long to wait"); - setTimeout(resolve, delay); - }); - timeouts.set(time, t); - return t; -} - -function when(time, value) { - var now; - return (now = timeouts.get(time = +time)) ? now.then(() => value) - : (now = Date.now()) >= time ? Promise.resolve(value) - : timeout(now, time).then(() => value); -} - -function tick(duration, value) { - return when(Math.ceil((Date.now() + 1) / duration) * duration, value); -} - -var Promises = /*#__PURE__*/Object.freeze({ -__proto__: null, -delay: delay, -tick: tick, -when: when -}); - -function resolve(name, base) { - if (/^(\w+:)|\/\//i.test(name)) return name; - if (/^[.]{0,2}\//i.test(name)) return new URL(name, base == null ? location : base).href; - if (!name.length || /^[\s._]/.test(name) || /\s$/.test(name)) throw new Error("illegal name"); - return "https://unpkg.com/" + name; -} - -const svg = template(function(string) { - var root = document.createElementNS("http://www.w3.org/2000/svg", "g"); - root.innerHTML = string.trim(); - return root; -}, function() { - return document.createElementNS("http://www.w3.org/2000/svg", "g"); -}); - -var raw = String.raw; - -function style(href) { - return new Promise(function(resolve, reject) { - var link = document.createElement("link"); - link.rel = "stylesheet"; - link.href = href; - link.onerror = reject; - link.onload = resolve; - document.head.appendChild(link); - }); -} - -function tex(require) { - return Promise.all([ - require(katex.resolve()), - require.resolve(katex.resolve("dist/katex.min.css")).then(style) - ]).then(function(values) { - var katex = values[0], tex = renderer(); - - function renderer(options) { - return function() { - var root = document.createElement("div"); - katex.render(raw.apply(String, arguments), root, options); - return root.removeChild(root.firstChild); - }; - } - - tex.options = renderer; - tex.block = renderer({displayMode: true}); - return tex; - }); -} - -async function vl(require) { - const [v, vl, api] = await Promise.all([vega, vegalite, vegaliteApi].map(d => require(d.resolve()))); - return api.register(v, vl); -} - -function width() { - return observe(function(change) { - var width = change(document.body.clientWidth); - function resized() { - var w = document.body.clientWidth; - if (w !== width) change(width = w); - } - window.addEventListener("resize", resized); - return function() { - window.removeEventListener("resize", resized); - }; - }); -} - -const Library = Object.assign(Object.defineProperties(function Library(resolver) { - const require = requirer(resolver); - Object.defineProperties(this, properties({ - FileAttachment: () => NoFileAttachments, - Mutable: () => Mutable, - now, - width, - - // Tagged template literals - dot: () => require(graphviz.resolve()), - htl: () => require(htl.resolve()), - html: () => html$1, - md: () => md(require), - svg: () => svg, - tex: () => tex(require), - - // Recommended libraries - // https://observablehq.com/@observablehq/recommended-libraries - _: () => require(lodash.resolve()), - aq: () => require.alias({"apache-arrow": arrow4.resolve()})(arquero.resolve()), // TODO upgrade to apache-arrow@9 - Arrow: () => require(arrow4.resolve()), // TODO upgrade to apache-arrow@9 - d3: () => require(d3.resolve()), - DuckDBClient: () => DuckDBClient, - Inputs: () => require(inputs.resolve()).then(Inputs => ({...Inputs, file: Inputs.fileOf(AbstractFile)})), - L: () => leaflet(require), - mermaid: () => mermaid(require), - Plot: () => require(plot.resolve()), - __query: () => __query, - require: () => require, - resolve: () => resolve, // deprecated; use async require.resolve instead - SQLite: () => SQLite(require), - SQLiteDatabaseClient: () => SQLiteDatabaseClient, - topojson: () => require(topojson.resolve()), - vl: () => vl(require), - - // Sample datasets - // https://observablehq.com/@observablehq/sample-datasets - aapl: () => new FileAttachment("https://static.observableusercontent.com/files/3ccff97fd2d93da734e76829b2b066eafdaac6a1fafdec0faf6ebc443271cfc109d29e80dd217468fcb2aff1e6bffdc73f356cc48feb657f35378e6abbbb63b9").csv({typed: true}), - alphabet: () => new FileAttachment("https://static.observableusercontent.com/files/75d52e6c3130b1cae83cda89305e17b50f33e7420ef205587a135e8562bcfd22e483cf4fa2fb5df6dff66f9c5d19740be1cfaf47406286e2eb6574b49ffc685d").csv({typed: true}), - cars: () => new FileAttachment("https://static.observableusercontent.com/files/048ec3dfd528110c0665dfa363dd28bc516ffb7247231f3ab25005036717f5c4c232a5efc7bb74bc03037155cb72b1abe85a33d86eb9f1a336196030443be4f6").csv({typed: true}), - citywages: () => new FileAttachment("https://static.observableusercontent.com/files/39837ec5121fcc163131dbc2fe8c1a2e0b3423a5d1e96b5ce371e2ac2e20a290d78b71a4fb08b9fa6a0107776e17fb78af313b8ea70f4cc6648fad68ddf06f7a").csv({typed: true}), - diamonds: () => new FileAttachment("https://static.observableusercontent.com/files/87942b1f5d061a21fa4bb8f2162db44e3ef0f7391301f867ab5ba718b225a63091af20675f0bfe7f922db097b217b377135203a7eab34651e21a8d09f4e37252").csv({typed: true}), - flare: () => new FileAttachment("https://static.observableusercontent.com/files/a6b0d94a7f5828fd133765a934f4c9746d2010e2f342d335923991f31b14120de96b5cb4f160d509d8dc627f0107d7f5b5070d2516f01e4c862b5b4867533000").csv({typed: true}), - industries: () => new FileAttachment("https://static.observableusercontent.com/files/76f13741128340cc88798c0a0b7fa5a2df8370f57554000774ab8ee9ae785ffa2903010cad670d4939af3e9c17e5e18e7e05ed2b38b848ac2fc1a0066aa0005f").csv({typed: true}), - miserables: () => new FileAttachment("https://static.observableusercontent.com/files/31d904f6e21d42d4963ece9c8cc4fbd75efcbdc404bf511bc79906f0a1be68b5a01e935f65123670ed04e35ca8cae3c2b943f82bf8db49c5a67c85cbb58db052").json(), - olympians: () => new FileAttachment("https://static.observableusercontent.com/files/31ca24545a0603dce099d10ee89ee5ae72d29fa55e8fc7c9ffb5ded87ac83060d80f1d9e21f4ae8eb04c1e8940b7287d179fe8060d887fb1f055f430e210007c").csv({typed: true}), - penguins: () => new FileAttachment("https://static.observableusercontent.com/files/715db1223e067f00500780077febc6cebbdd90c151d3d78317c802732252052ab0e367039872ab9c77d6ef99e5f55a0724b35ddc898a1c99cb14c31a379af80a").csv({typed: true}), - pizza: () => new FileAttachment("https://static.observableusercontent.com/files/c653108ab176088cacbb338eaf2344c4f5781681702bd6afb55697a3f91b511c6686ff469f3e3a27c75400001a2334dbd39a4499fe46b50a8b3c278b7d2f7fb5").csv({typed: true}), - weather: () => new FileAttachment("https://static.observableusercontent.com/files/693a46b22b33db0f042728700e0c73e836fa13d55446df89120682d55339c6db7cc9e574d3d73f24ecc9bc7eb9ac9a1e7e104a1ee52c00aab1e77eb102913c1f").csv({typed: true}), - - // Note: these are namespace objects, and thus exposed directly rather than - // being wrapped in a function. This allows library.Generators to resolve, - // rather than needing module.value. - DOM, - Files, - Generators: Generators$1, - Promises - })); -}, { - resolve: { - get: () => requireDefault.resolve, - enumerable: true, - configurable: true - }, - require: { - get: () => requireDefault, - set: setDefaultRequire, - enumerable: true, - configurable: true - } -}), { - resolveFrom, - requireFrom -}); - -function properties(values) { - return Object.fromEntries(Object.entries(values).map(property)); -} - -function property([key, value]) { - return [key, ({value, writable: true, enumerable: true})]; -} - -// src/main.js -class PandocCodeDecorator { - constructor(node) { - this._node = node; - this._spans = []; - this.normalizeCodeRange(); - this.initializeEntryPoints(); - } - normalizeCodeRange() { - const n = this._node; - const lines = n.querySelectorAll("code > span"); - for (const line of lines) { - Array.from(line.childNodes).filter((n2) => n2.nodeType === n2.TEXT_NODE).forEach((n2) => { - const newSpan = document.createElement("span"); - newSpan.textContent = n2.wholeText; - n2.replaceWith(newSpan); - }); - } - } - initializeEntryPoints() { - const lines = this._node.querySelectorAll("code > span"); - let result = []; - let offset = this._node.parentElement.dataset.sourceOffset && -Number(this._node.parentElement.dataset.sourceOffset) || 0; - for (const line of lines) { - let lineNumber = Number(line.id.split("-").pop()); - let column = 1; - Array.from(line.childNodes).filter((n) => n.nodeType === n.ELEMENT_NODE && n.nodeName === "SPAN").forEach((n) => { - result.push({ - offset, - line: lineNumber, - column, - node: n - }); - offset += n.textContent.length; - column += n.textContent.length; - }); - offset += 1; - } - this._elementEntryPoints = result; - } - locateEntry(offset) { - let candidate; - if (offset === Infinity) - return void 0; - for (let i = 0; i < this._elementEntryPoints.length; ++i) { - const entry = this._elementEntryPoints[i]; - if (entry.offset > offset) { - return { entry: candidate, index: i - 1 }; - } - candidate = entry; - } - if (offset < candidate.offset + candidate.node.textContent.length) { - return { entry: candidate, index: this._elementEntryPoints.length - 1 }; - } else { - return void 0; - } - } - offsetToLineColumn(offset) { - let entry = this.locateEntry(offset); - if (entry === void 0) { - const entries = this._elementEntryPoints; - const last = entries[entries.length - 1]; - return { - line: last.line, - column: last.column + Math.min(last.node.textContent.length, offset - last.offset) - }; - } - return { - line: entry.entry.line, - column: entry.entry.column + offset - entry.entry.offset - }; - } - *spanSelection(start, end) { - this.ensureExactSpan(start, end); - const startEntry = this.locateEntry(start); - const endEntry = this.locateEntry(end); - if (startEntry === void 0) { - return; - } - const startIndex = startEntry.index; - const endIndex = endEntry && endEntry.index || this._elementEntryPoints.length; - for (let i = startIndex; i < endIndex; ++i) { - if (this._elementEntryPoints[i] !== void 0) { - yield this._elementEntryPoints[i]; - } - } - } - decorateSpan(start, end, classes) { - for (const entryPoint of this.spanSelection(start, end)) { - for (const cssClass of classes) { - entryPoint.node.classList.add(cssClass); - } - } - } - clearSpan(start, end, classes) { - for (const entryPoint of this.spanSelection(start, end)) { - for (const cssClass of classes) { - entryPoint.node.classList.remove(cssClass); - } - } - } - ensureExactSpan(start, end) { - const splitEntry = (entry, offset) => { - const newSpan = document.createElement("span"); - for (const cssClass of entry.node.classList) { - newSpan.classList.add(cssClass); - } - const beforeText = entry.node.textContent.slice(0, offset - entry.offset); - const afterText = entry.node.textContent.slice(offset - entry.offset); - entry.node.textContent = beforeText; - newSpan.textContent = afterText; - entry.node.after(newSpan); - this._elementEntryPoints.push({ - column: entry.column + offset - entry.offset, - line: entry.line, - node: newSpan, - offset - }); - this._elementEntryPoints.sort((a, b) => a.offset - b.offset); - }; - const startEntry = this.locateEntry(start); - if (startEntry !== void 0 && startEntry.entry !== void 0 && startEntry.entry.offset != start) { - splitEntry(startEntry.entry, start); - } - const endEntry = this.locateEntry(end); - if (endEntry !== void 0 && startEntry.entry !== void 0 && endEntry.entry.offset !== end) { - splitEntry(endEntry.entry, end); - } - } - clearSpan(start, end, classes) { - this.ensureExactSpan(start, end); - const startEntry = this.locateEntry(start); - const endEntry = this.locateEntry(end); - if (startEntry === void 0) { - return; - } - const startIndex = startEntry.index; - const endIndex = endEntry && endEntry.index || this._elementEntryPoints.length; - for (let i = startIndex; i < endIndex; ++i) { - for (const cssClass of classes) { - this._elementEntryPoints[i].node.classList.remove(cssClass); - } - } - } -} - -function dispatch(node, type, detail) { - detail = detail || {}; - var document = node.ownerDocument, event = document.defaultView.CustomEvent; - if (typeof event === "function") { - event = new event(type, {detail: detail}); - } else { - event = document.createEvent("Event"); - event.initEvent(type, false, false); - event.detail = detail; - } - node.dispatchEvent(event); -} - -// TODO https://twitter.com/mbostock/status/702737065121742848 -function isarray(value) { - return Array.isArray(value) - || value instanceof Int8Array - || value instanceof Int16Array - || value instanceof Int32Array - || value instanceof Uint8Array - || value instanceof Uint8ClampedArray - || value instanceof Uint16Array - || value instanceof Uint32Array - || value instanceof Float32Array - || value instanceof Float64Array; -} - -// Non-integer keys in arrays, e.g. [1, 2, 0.5: "value"]. -function isindex(key) { - return key === (key | 0) + ""; -} - -function inspectName(name) { - const n = document.createElement("span"); - n.className = "observablehq--cellname"; - n.textContent = `${name} = `; - return n; -} - -const symbolToString = Symbol.prototype.toString; - -// Symbols do not coerce to strings; they must be explicitly converted. -function formatSymbol(symbol) { - return symbolToString.call(symbol); -} - -const {getOwnPropertySymbols, prototype: {hasOwnProperty: hasOwnProperty$1}} = Object; -const {toStringTag} = Symbol; - -const FORBIDDEN = {}; - -const symbolsof = getOwnPropertySymbols; - -function isown(object, key) { - return hasOwnProperty$1.call(object, key); -} - -function tagof(object) { - return object[toStringTag] - || (object.constructor && object.constructor.name) - || "Object"; -} - -function valueof(object, key) { - try { - const value = object[key]; - if (value) value.constructor; // Test for SecurityError. - return value; - } catch (ignore) { - return FORBIDDEN; - } -} - -const SYMBOLS = [ - { symbol: "@@__IMMUTABLE_INDEXED__@@", name: "Indexed", modifier: true }, - { symbol: "@@__IMMUTABLE_KEYED__@@", name: "Keyed", modifier: true }, - { symbol: "@@__IMMUTABLE_LIST__@@", name: "List", arrayish: true }, - { symbol: "@@__IMMUTABLE_MAP__@@", name: "Map" }, - { - symbol: "@@__IMMUTABLE_ORDERED__@@", - name: "Ordered", - modifier: true, - prefix: true - }, - { symbol: "@@__IMMUTABLE_RECORD__@@", name: "Record" }, - { - symbol: "@@__IMMUTABLE_SET__@@", - name: "Set", - arrayish: true, - setish: true - }, - { symbol: "@@__IMMUTABLE_STACK__@@", name: "Stack", arrayish: true } -]; - -function immutableName(obj) { - try { - let symbols = SYMBOLS.filter(({ symbol }) => obj[symbol] === true); - if (!symbols.length) return; - - const name = symbols.find(s => !s.modifier); - const prefix = - name.name === "Map" && symbols.find(s => s.modifier && s.prefix); - - const arrayish = symbols.some(s => s.arrayish); - const setish = symbols.some(s => s.setish); - - return { - name: `${prefix ? prefix.name : ""}${name.name}`, - symbols, - arrayish: arrayish && !setish, - setish - }; - } catch (e) { - return null; - } -} - -const {getPrototypeOf, getOwnPropertyDescriptors} = Object; -const objectPrototype = getPrototypeOf({}); - -function inspectExpanded(object, _, name, proto) { - let arrayish = isarray(object); - let tag, fields, next, n; - - if (object instanceof Map) { - if (object instanceof object.constructor) { - tag = `Map(${object.size})`; - fields = iterateMap$1; - } else { // avoid incompatible receiver error for prototype - tag = "Map()"; - fields = iterateObject$1; - } - } else if (object instanceof Set) { - if (object instanceof object.constructor) { - tag = `Set(${object.size})`; - fields = iterateSet$1; - } else { // avoid incompatible receiver error for prototype - tag = "Set()"; - fields = iterateObject$1; - } - } else if (arrayish) { - tag = `${object.constructor.name}(${object.length})`; - fields = iterateArray$1; - } else if ((n = immutableName(object))) { - tag = `Immutable.${n.name}${n.name === "Record" ? "" : `(${object.size})`}`; - arrayish = n.arrayish; - fields = n.arrayish - ? iterateImArray$1 - : n.setish - ? iterateImSet$1 - : iterateImObject$1; - } else if (proto) { - tag = tagof(object); - fields = iterateProto; - } else { - tag = tagof(object); - fields = iterateObject$1; - } - - const span = document.createElement("span"); - span.className = "observablehq--expanded"; - if (name) { - span.appendChild(inspectName(name)); - } - const a = span.appendChild(document.createElement("a")); - a.innerHTML = ` - - `; - a.appendChild(document.createTextNode(`${tag}${arrayish ? " [" : " {"}`)); - a.addEventListener("mouseup", function(event) { - event.stopPropagation(); - replace(span, inspectCollapsed(object, null, name, proto)); - }); - - fields = fields(object); - for (let i = 0; !(next = fields.next()).done && i < 20; ++i) { - span.appendChild(next.value); - } - - if (!next.done) { - const a = span.appendChild(document.createElement("a")); - a.className = "observablehq--field"; - a.style.display = "block"; - a.appendChild(document.createTextNode(` … more`)); - a.addEventListener("mouseup", function(event) { - event.stopPropagation(); - span.insertBefore(next.value, span.lastChild.previousSibling); - for (let i = 0; !(next = fields.next()).done && i < 19; ++i) { - span.insertBefore(next.value, span.lastChild.previousSibling); - } - if (next.done) span.removeChild(span.lastChild.previousSibling); - dispatch(span, "load"); - }); - } - - span.appendChild(document.createTextNode(arrayish ? "]" : "}")); - - return span; -} - -function* iterateMap$1(map) { - for (const [key, value] of map) { - yield formatMapField$1(key, value); - } - yield* iterateObject$1(map); -} - -function* iterateSet$1(set) { - for (const value of set) { - yield formatSetField(value); - } - yield* iterateObject$1(set); -} - -function* iterateImSet$1(set) { - for (const value of set) { - yield formatSetField(value); - } -} - -function* iterateArray$1(array) { - for (let i = 0, n = array.length; i < n; ++i) { - if (i in array) { - yield formatField$1(i, valueof(array, i), "observablehq--index"); - } - } - for (const key in array) { - if (!isindex(key) && isown(array, key)) { - yield formatField$1(key, valueof(array, key), "observablehq--key"); - } - } - for (const symbol of symbolsof(array)) { - yield formatField$1( - formatSymbol(symbol), - valueof(array, symbol), - "observablehq--symbol" - ); - } -} - -function* iterateImArray$1(array) { - let i1 = 0; - for (const n = array.size; i1 < n; ++i1) { - yield formatField$1(i1, array.get(i1), true); - } -} - -function* iterateProto(object) { - for (const key in getOwnPropertyDescriptors(object)) { - yield formatField$1(key, valueof(object, key), "observablehq--key"); - } - for (const symbol of symbolsof(object)) { - yield formatField$1( - formatSymbol(symbol), - valueof(object, symbol), - "observablehq--symbol" - ); - } - - const proto = getPrototypeOf(object); - if (proto && proto !== objectPrototype) { - yield formatPrototype(proto); - } -} - -function* iterateObject$1(object) { - for (const key in object) { - if (isown(object, key)) { - yield formatField$1(key, valueof(object, key), "observablehq--key"); - } - } - for (const symbol of symbolsof(object)) { - yield formatField$1( - formatSymbol(symbol), - valueof(object, symbol), - "observablehq--symbol" - ); - } - - const proto = getPrototypeOf(object); - if (proto && proto !== objectPrototype) { - yield formatPrototype(proto); - } -} - -function* iterateImObject$1(object) { - for (const [key, value] of object) { - yield formatField$1(key, value, "observablehq--key"); - } -} - -function formatPrototype(value) { - const item = document.createElement("div"); - const span = item.appendChild(document.createElement("span")); - item.className = "observablehq--field"; - span.className = "observablehq--prototype-key"; - span.textContent = ` `; - item.appendChild(document.createTextNode(": ")); - item.appendChild(inspect(value, undefined, undefined, undefined, true)); - return item; -} - -function formatField$1(key, value, className) { - const item = document.createElement("div"); - const span = item.appendChild(document.createElement("span")); - item.className = "observablehq--field"; - span.className = className; - span.textContent = ` ${key}`; - item.appendChild(document.createTextNode(": ")); - item.appendChild(inspect(value)); - return item; -} - -function formatMapField$1(key, value) { - const item = document.createElement("div"); - item.className = "observablehq--field"; - item.appendChild(document.createTextNode(" ")); - item.appendChild(inspect(key)); - item.appendChild(document.createTextNode(" => ")); - item.appendChild(inspect(value)); - return item; -} - -function formatSetField(value) { - const item = document.createElement("div"); - item.className = "observablehq--field"; - item.appendChild(document.createTextNode(" ")); - item.appendChild(inspect(value)); - return item; -} - -function hasSelection(elem) { - const sel = window.getSelection(); - return ( - sel.type === "Range" && - (sel.containsNode(elem, true) || - sel.anchorNode.isSelfOrDescendant(elem) || - sel.focusNode.isSelfOrDescendant(elem)) - ); -} - -function inspectCollapsed(object, shallow, name, proto) { - let arrayish = isarray(object); - let tag, fields, next, n; - - if (object instanceof Map) { - if (object instanceof object.constructor) { - tag = `Map(${object.size})`; - fields = iterateMap; - } else { // avoid incompatible receiver error for prototype - tag = "Map()"; - fields = iterateObject; - } - } else if (object instanceof Set) { - if (object instanceof object.constructor) { - tag = `Set(${object.size})`; - fields = iterateSet; - } else { // avoid incompatible receiver error for prototype - tag = "Set()"; - fields = iterateObject; - } - } else if (arrayish) { - tag = `${object.constructor.name}(${object.length})`; - fields = iterateArray; - } else if ((n = immutableName(object))) { - tag = `Immutable.${n.name}${n.name === 'Record' ? '' : `(${object.size})`}`; - arrayish = n.arrayish; - fields = n.arrayish ? iterateImArray : n.setish ? iterateImSet : iterateImObject; - } else { - tag = tagof(object); - fields = iterateObject; - } - - if (shallow) { - const span = document.createElement("span"); - span.className = "observablehq--shallow"; - if (name) { - span.appendChild(inspectName(name)); - } - span.appendChild(document.createTextNode(tag)); - span.addEventListener("mouseup", function(event) { - if (hasSelection(span)) return; - event.stopPropagation(); - replace(span, inspectCollapsed(object)); - }); - return span; - } - - const span = document.createElement("span"); - span.className = "observablehq--collapsed"; - if (name) { - span.appendChild(inspectName(name)); - } - const a = span.appendChild(document.createElement("a")); - a.innerHTML = ` - - `; - a.appendChild(document.createTextNode(`${tag}${arrayish ? " [" : " {"}`)); - span.addEventListener("mouseup", function(event) { - if (hasSelection(span)) return; - event.stopPropagation(); - replace(span, inspectExpanded(object, null, name, proto)); - }, true); - - fields = fields(object); - for (let i = 0; !(next = fields.next()).done && i < 20; ++i) { - if (i > 0) span.appendChild(document.createTextNode(", ")); - span.appendChild(next.value); - } - - if (!next.done) span.appendChild(document.createTextNode(", …")); - span.appendChild(document.createTextNode(arrayish ? "]" : "}")); - - return span; -} - -function* iterateMap(map) { - for (const [key, value] of map) { - yield formatMapField(key, value); - } - yield* iterateObject(map); -} - -function* iterateSet(set) { - for (const value of set) { - yield inspect(value, true); - } - yield* iterateObject(set); -} - -function* iterateImSet(set) { - for (const value of set) { - yield inspect(value, true); - } -} - -function* iterateImArray(array) { - let i0 = -1, i1 = 0; - for (const n = array.size; i1 < n; ++i1) { - if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1); - yield inspect(array.get(i1), true); - i0 = i1; - } - if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1); -} - -function* iterateArray(array) { - let i0 = -1, i1 = 0; - for (const n = array.length; i1 < n; ++i1) { - if (i1 in array) { - if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1); - yield inspect(valueof(array, i1), true); - i0 = i1; - } - } - if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1); - for (const key in array) { - if (!isindex(key) && isown(array, key)) { - yield formatField(key, valueof(array, key), "observablehq--key"); - } - } - for (const symbol of symbolsof(array)) { - yield formatField(formatSymbol(symbol), valueof(array, symbol), "observablehq--symbol"); - } -} - -function* iterateObject(object) { - for (const key in object) { - if (isown(object, key)) { - yield formatField(key, valueof(object, key), "observablehq--key"); - } - } - for (const symbol of symbolsof(object)) { - yield formatField(formatSymbol(symbol), valueof(object, symbol), "observablehq--symbol"); - } -} - -function* iterateImObject(object) { - for (const [key, value] of object) { - yield formatField(key, value, "observablehq--key"); - } -} - -function formatEmpty(e) { - const span = document.createElement("span"); - span.className = "observablehq--empty"; - span.textContent = e === 1 ? "empty" : `empty × ${e}`; - return span; -} - -function formatField(key, value, className) { - const fragment = document.createDocumentFragment(); - const span = fragment.appendChild(document.createElement("span")); - span.className = className; - span.textContent = key; - fragment.appendChild(document.createTextNode(": ")); - fragment.appendChild(inspect(value, true)); - return fragment; -} - -function formatMapField(key, value) { - const fragment = document.createDocumentFragment(); - fragment.appendChild(inspect(key, true)); - fragment.appendChild(document.createTextNode(" => ")); - fragment.appendChild(inspect(value, true)); - return fragment; -} - -function format(date, fallback) { - if (!(date instanceof Date)) date = new Date(+date); - if (isNaN(date)) return typeof fallback === "function" ? fallback(date) : fallback; - const hours = date.getUTCHours(); - const minutes = date.getUTCMinutes(); - const seconds = date.getUTCSeconds(); - const milliseconds = date.getUTCMilliseconds(); - return `${formatYear(date.getUTCFullYear())}-${pad(date.getUTCMonth() + 1, 2)}-${pad(date.getUTCDate(), 2)}${ - hours || minutes || seconds || milliseconds ? `T${pad(hours, 2)}:${pad(minutes, 2)}${ - seconds || milliseconds ? `:${pad(seconds, 2)}${ - milliseconds ? `.${pad(milliseconds, 3)}` : `` - }` : `` - }Z` : `` - }`; -} - -function formatYear(year) { - return year < 0 ? `-${pad(-year, 6)}` - : year > 9999 ? `+${pad(year, 6)}` - : pad(year, 4); -} - -function pad(value, width) { - return `${value}`.padStart(width, "0"); -} - -function formatDate$1(date) { - return format(date, "Invalid Date"); -} - -var errorToString = Error.prototype.toString; - -function formatError(value) { - return value.stack || errorToString.call(value); -} - -var regExpToString = RegExp.prototype.toString; - -function formatRegExp(value) { - return regExpToString.call(value); -} - -/* eslint-disable no-control-regex */ -const NEWLINE_LIMIT = 20; - -function formatString(string, shallow, expanded, name) { - if (shallow === false) { - // String has fewer escapes displayed with double quotes - if (count(string, /["\n]/g) <= count(string, /`|\${/g)) { - const span = document.createElement("span"); - if (name) span.appendChild(inspectName(name)); - const textValue = span.appendChild(document.createElement("span")); - textValue.className = "observablehq--string"; - textValue.textContent = JSON.stringify(string); - return span; - } - const lines = string.split("\n"); - if (lines.length > NEWLINE_LIMIT && !expanded) { - const div = document.createElement("div"); - if (name) div.appendChild(inspectName(name)); - const textValue = div.appendChild(document.createElement("span")); - textValue.className = "observablehq--string"; - textValue.textContent = "`" + templatify(lines.slice(0, NEWLINE_LIMIT).join("\n")); - const splitter = div.appendChild(document.createElement("span")); - const truncatedCount = lines.length - NEWLINE_LIMIT; - splitter.textContent = `Show ${truncatedCount} truncated line${truncatedCount > 1 ? "s": ""}`; splitter.className = "observablehq--string-expand"; - splitter.addEventListener("mouseup", function (event) { - event.stopPropagation(); - replace(div, inspect(string, shallow, true, name)); - }); - return div; - } - const span = document.createElement("span"); - if (name) span.appendChild(inspectName(name)); - const textValue = span.appendChild(document.createElement("span")); - textValue.className = `observablehq--string${expanded ? " observablehq--expanded" : ""}`; - textValue.textContent = "`" + templatify(string) + "`"; - return span; - } - - const span = document.createElement("span"); - if (name) span.appendChild(inspectName(name)); - const textValue = span.appendChild(document.createElement("span")); - textValue.className = "observablehq--string"; - textValue.textContent = JSON.stringify(string.length > 100 ? - `${string.slice(0, 50)}…${string.slice(-49)}` : string); - return span; -} - -function templatify(string) { - return string.replace(/[\\`\x00-\x09\x0b-\x19]|\${/g, templatifyChar); -} - -function templatifyChar(char) { - var code = char.charCodeAt(0); - switch (code) { - case 0x8: return "\\b"; - case 0x9: return "\\t"; - case 0xb: return "\\v"; - case 0xc: return "\\f"; - case 0xd: return "\\r"; - } - return code < 0x10 ? "\\x0" + code.toString(16) - : code < 0x20 ? "\\x" + code.toString(16) - : "\\" + char; -} - -function count(string, re) { - var n = 0; - while (re.exec(string)) ++n; - return n; -} - -var toString$2 = Function.prototype.toString, - TYPE_ASYNC = {prefix: "async ƒ"}, - TYPE_ASYNC_GENERATOR = {prefix: "async ƒ*"}, - TYPE_CLASS = {prefix: "class"}, - TYPE_FUNCTION = {prefix: "ƒ"}, - TYPE_GENERATOR = {prefix: "ƒ*"}; - -function inspectFunction(f, name) { - var type, m, t = toString$2.call(f); - - switch (f.constructor && f.constructor.name) { - case "AsyncFunction": type = TYPE_ASYNC; break; - case "AsyncGeneratorFunction": type = TYPE_ASYNC_GENERATOR; break; - case "GeneratorFunction": type = TYPE_GENERATOR; break; - default: type = /^class\b/.test(t) ? TYPE_CLASS : TYPE_FUNCTION; break; - } - - // A class, possibly named. - // class Name - if (type === TYPE_CLASS) { - return formatFunction(type, "", name); - } - - // An arrow function with a single argument. - // foo => - // async foo => - if ((m = /^(?:async\s*)?(\w+)\s*=>/.exec(t))) { - return formatFunction(type, "(" + m[1] + ")", name); - } - - // An arrow function with parenthesized arguments. - // (…) - // async (…) - if ((m = /^(?:async\s*)?\(\s*(\w+(?:\s*,\s*\w+)*)?\s*\)/.exec(t))) { - return formatFunction(type, m[1] ? "(" + m[1].replace(/\s*,\s*/g, ", ") + ")" : "()", name); - } - - // A function, possibly: async, generator, anonymous, simply arguments. - // function name(…) - // function* name(…) - // async function name(…) - // async function* name(…) - if ((m = /^(?:async\s*)?function(?:\s*\*)?(?:\s*\w+)?\s*\(\s*(\w+(?:\s*,\s*\w+)*)?\s*\)/.exec(t))) { - return formatFunction(type, m[1] ? "(" + m[1].replace(/\s*,\s*/g, ", ") + ")" : "()", name); - } - - // Something else, like destructuring, comments or default values. - return formatFunction(type, "(…)", name); -} - -function formatFunction(type, args, cellname) { - var span = document.createElement("span"); - span.className = "observablehq--function"; - if (cellname) { - span.appendChild(inspectName(cellname)); - } - var spanType = span.appendChild(document.createElement("span")); - spanType.className = "observablehq--keyword"; - spanType.textContent = type.prefix; - span.appendChild(document.createTextNode(args)); - return span; -} - -const {prototype: {toString: toString$1}} = Object; - -function inspect(value, shallow, expand, name, proto) { - let type = typeof value; - switch (type) { - case "boolean": - case "undefined": { value += ""; break; } - case "number": { value = value === 0 && 1 / value < 0 ? "-0" : value + ""; break; } - case "bigint": { value = value + "n"; break; } - case "symbol": { value = formatSymbol(value); break; } - case "function": { return inspectFunction(value, name); } - case "string": { return formatString(value, shallow, expand, name); } - default: { - if (value === null) { type = null, value = "null"; break; } - if (value instanceof Date) { type = "date", value = formatDate$1(value); break; } - if (value === FORBIDDEN) { type = "forbidden", value = "[forbidden]"; break; } - switch (toString$1.call(value)) { - case "[object RegExp]": { type = "regexp", value = formatRegExp(value); break; } - case "[object Error]": // https://github.com/lodash/lodash/blob/master/isError.js#L26 - case "[object DOMException]": { type = "error", value = formatError(value); break; } - default: return (expand ? inspectExpanded : inspectCollapsed)(value, shallow, name, proto); - } - break; - } - } - const span = document.createElement("span"); - if (name) span.appendChild(inspectName(name)); - const n = span.appendChild(document.createElement("span")); - n.className = `observablehq--${type}`; - n.textContent = value; - return span; -} - -function replace(spanOld, spanNew) { - if (spanOld.classList.contains("observablehq--inspect")) spanNew.classList.add("observablehq--inspect"); - spanOld.parentNode.replaceChild(spanNew, spanOld); - dispatch(spanNew, "load"); -} - -const LOCATION_MATCH = /\s+\(\d+:\d+\)$/m; - -class Inspector { - constructor(node) { - if (!node) throw new Error("invalid node"); - this._node = node; - node.classList.add("observablehq"); - } - pending() { - const {_node} = this; - _node.classList.remove("observablehq--error"); - _node.classList.add("observablehq--running"); - } - fulfilled(value, name) { - const {_node} = this; - if (!isnode(value) || (value.parentNode && value.parentNode !== _node)) { - value = inspect(value, false, _node.firstChild // TODO Do this better. - && _node.firstChild.classList - && _node.firstChild.classList.contains("observablehq--expanded"), name); - value.classList.add("observablehq--inspect"); - } - _node.classList.remove("observablehq--running", "observablehq--error"); - if (_node.firstChild !== value) { - if (_node.firstChild) { - while (_node.lastChild !== _node.firstChild) _node.removeChild(_node.lastChild); - _node.replaceChild(value, _node.firstChild); - } else { - _node.appendChild(value); - } - } - dispatch(_node, "update"); - } - rejected(error, name) { - const {_node} = this; - _node.classList.remove("observablehq--running"); - _node.classList.add("observablehq--error"); - while (_node.lastChild) _node.removeChild(_node.lastChild); - var div = document.createElement("div"); - div.className = "observablehq--inspect"; - if (name) div.appendChild(inspectName(name)); - div.appendChild(document.createTextNode((error + "").replace(LOCATION_MATCH, ""))); - _node.appendChild(div); - dispatch(_node, "error", {error: error}); - } -} - -Inspector.into = function(container) { - if (typeof container === "string") { - container = document.querySelector(container); - if (container == null) throw new Error("container not found"); - } - return function() { - return new Inspector(container.appendChild(document.createElement("div"))); - }; -}; - -// Returns true if the given value is something that should be added to the DOM -// by the inspector, rather than being inspected. This deliberately excludes -// DocumentFragment since appending a fragment “dissolves” (mutates) the -// fragment, and we wish for the inspector to not have side-effects. Also, -// HTMLElement.prototype is an instanceof Element, but not an element! -function isnode(value) { - return (value instanceof Element || value instanceof Text) - && (value instanceof value.constructor); -} - -class RuntimeError extends Error { - constructor(message, input) { - super(message); - this.input = input; - } -} - -RuntimeError.prototype.name = "RuntimeError"; - -function generatorish(value) { - return value - && typeof value.next === "function" - && typeof value.return === "function"; -} - -function load(notebook, library, observer) { - if (typeof library == "function") observer = library, library = null; - if (typeof observer !== "function") throw new Error("invalid observer"); - if (library == null) library = new Library(); - - const {modules, id} = notebook; - const map = new Map; - const runtime = new Runtime(library); - const main = runtime_module(id); - - function runtime_module(id) { - let module = map.get(id); - if (!module) map.set(id, module = runtime.module()); - return module; - } - - for (const m of modules) { - const module = runtime_module(m.id); - let i = 0; - for (const v of m.variables) { - if (v.from) module.import(v.remote, v.name, runtime_module(v.from)); - else if (module === main) module.variable(observer(v, i, m.variables)).define(v.name, v.inputs, v.value); - else module.define(v.name, v.inputs, v.value); - ++i; - } - } - - return runtime; -} - -function constant(x) { - return () => x; -} - -function identity$1(x) { - return x; -} - -function rethrow(error) { - return () => { - throw error; - }; -} - -const prototype = Array.prototype; -const map = prototype.map; - -function noop() {} - -const TYPE_NORMAL = 1; // a normal variable -const TYPE_IMPLICIT = 2; // created on reference -const TYPE_DUPLICATE = 3; // created on duplicate definition - -const no_observer = Symbol("no-observer"); - -function Variable(type, module, observer, options) { - if (!observer) observer = no_observer; - Object.defineProperties(this, { - _observer: {value: observer, writable: true}, - _definition: {value: variable_undefined, writable: true}, - _duplicate: {value: undefined, writable: true}, - _duplicates: {value: undefined, writable: true}, - _indegree: {value: NaN, writable: true}, // The number of computing inputs. - _inputs: {value: [], writable: true}, - _invalidate: {value: noop, writable: true}, - _module: {value: module}, - _name: {value: null, writable: true}, - _outputs: {value: new Set, writable: true}, - _promise: {value: Promise.resolve(undefined), writable: true}, - _reachable: {value: observer !== no_observer, writable: true}, // Is this variable transitively visible? - _rejector: {value: variable_rejector(this)}, - _shadow: {value: initShadow(module, options)}, - _type: {value: type}, - _value: {value: undefined, writable: true}, - _version: {value: 0, writable: true} - }); -} - -Object.defineProperties(Variable.prototype, { - _pending: {value: variable_pending, writable: true, configurable: true}, - _fulfilled: {value: variable_fulfilled, writable: true, configurable: true}, - _rejected: {value: variable_rejected, writable: true, configurable: true}, - _resolve: {value: variable_resolve, writable: true, configurable: true}, - define: {value: variable_define, writable: true, configurable: true}, - delete: {value: variable_delete, writable: true, configurable: true}, - import: {value: variable_import, writable: true, configurable: true} -}); - -function initShadow(module, options) { - if (!options?.shadow) return null; - return new Map( - Object.entries(options.shadow) - .map(([name, definition]) => [name, (new Variable(TYPE_IMPLICIT, module)).define([], definition)]) - ); -} - -function variable_attach(variable) { - variable._module._runtime._dirty.add(variable); - variable._outputs.add(this); -} - -function variable_detach(variable) { - variable._module._runtime._dirty.add(variable); - variable._outputs.delete(this); -} - -function variable_undefined() { - throw variable_undefined; -} - -function variable_stale() { - throw variable_stale; -} - -function variable_rejector(variable) { - return (error) => { - if (error === variable_stale) throw error; - if (error === variable_undefined) throw new RuntimeError(`${variable._name} is not defined`, variable._name); - if (error instanceof Error && error.message) throw new RuntimeError(error.message, variable._name); - throw new RuntimeError(`${variable._name} could not be resolved`, variable._name); - }; -} - -function variable_duplicate(name) { - return () => { - throw new RuntimeError(`${name} is defined more than once`); - }; -} - -function variable_define(name, inputs, definition) { - switch (arguments.length) { - case 1: { - definition = name, name = inputs = null; - break; - } - case 2: { - definition = inputs; - if (typeof name === "string") inputs = null; - else inputs = name, name = null; - break; - } - } - return variable_defineImpl.call(this, - name == null ? null : String(name), - inputs == null ? [] : map.call(inputs, this._resolve, this), - typeof definition === "function" ? definition : constant(definition) - ); -} - -function variable_resolve(name) { - return this._shadow?.get(name) ?? this._module._resolve(name); -} - -function variable_defineImpl(name, inputs, definition) { - const scope = this._module._scope, runtime = this._module._runtime; - - this._inputs.forEach(variable_detach, this); - inputs.forEach(variable_attach, this); - this._inputs = inputs; - this._definition = definition; - this._value = undefined; - - // Is this an active variable (that may require disposal)? - if (definition === noop) runtime._variables.delete(this); - else runtime._variables.add(this); - - // Did the variable’s name change? Time to patch references! - if (name !== this._name || scope.get(name) !== this) { - let error, found; - - if (this._name) { // Did this variable previously have a name? - if (this._outputs.size) { // And did other variables reference this variable? - scope.delete(this._name); - found = this._module._resolve(this._name); - found._outputs = this._outputs, this._outputs = new Set; - found._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(this)] = found; }, this); - found._outputs.forEach(runtime._updates.add, runtime._updates); - runtime._dirty.add(found).add(this); - scope.set(this._name, found); - } else if ((found = scope.get(this._name)) === this) { // Do no other variables reference this variable? - scope.delete(this._name); // It’s safe to delete! - } else if (found._type === TYPE_DUPLICATE) { // Do other variables assign this name? - found._duplicates.delete(this); // This variable no longer assigns this name. - this._duplicate = undefined; - if (found._duplicates.size === 1) { // Is there now only one variable assigning this name? - found = found._duplicates.keys().next().value; // Any references are now fixed! - error = scope.get(this._name); - found._outputs = error._outputs, error._outputs = new Set; - found._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(error)] = found; }); - found._definition = found._duplicate, found._duplicate = undefined; - runtime._dirty.add(error).add(found); - runtime._updates.add(found); - scope.set(this._name, found); - } - } else { - throw new Error; - } - } - - if (this._outputs.size) throw new Error; - - if (name) { // Does this variable have a new name? - if (found = scope.get(name)) { // Do other variables reference or assign this name? - if (found._type === TYPE_DUPLICATE) { // Do multiple other variables already define this name? - this._definition = variable_duplicate(name), this._duplicate = definition; - found._duplicates.add(this); - } else if (found._type === TYPE_IMPLICIT) { // Are the variable references broken? - this._outputs = found._outputs, found._outputs = new Set; // Now they’re fixed! - this._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(found)] = this; }, this); - runtime._dirty.add(found).add(this); - scope.set(name, this); - } else { // Does another variable define this name? - found._duplicate = found._definition, this._duplicate = definition; // Now they’re duplicates. - error = new Variable(TYPE_DUPLICATE, this._module); - error._name = name; - error._definition = this._definition = found._definition = variable_duplicate(name); - error._outputs = found._outputs, found._outputs = new Set; - error._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(found)] = error; }); - error._duplicates = new Set([this, found]); - runtime._dirty.add(found).add(error); - runtime._updates.add(found).add(error); - scope.set(name, error); - } - } else { - scope.set(name, this); - } - } - - this._name = name; - } - - // If this redefined variable was previously evaluated, invalidate it. (If the - // variable was never evaluated, then the invalidated value could never have - // been exposed and we can avoid this extra work.) - if (this._version > 0) ++this._version; - - runtime._updates.add(this); - runtime._compute(); - return this; -} - -function variable_import(remote, name, module) { - if (arguments.length < 3) module = name, name = remote; - return variable_defineImpl.call(this, String(name), [module._resolve(String(remote))], identity$1); -} - -function variable_delete() { - return variable_defineImpl.call(this, null, [], noop); -} - -function variable_pending() { - if (this._observer.pending) this._observer.pending(); -} - -function variable_fulfilled(value) { - if (this._observer.fulfilled) this._observer.fulfilled(value, this._name); -} - -function variable_rejected(error) { - if (this._observer.rejected) this._observer.rejected(error, this._name); -} - -const variable_variable = Symbol("variable"); -const variable_invalidation = Symbol("invalidation"); -const variable_visibility = Symbol("visibility"); - -function Module(runtime, builtins = []) { - Object.defineProperties(this, { - _runtime: {value: runtime}, - _scope: {value: new Map}, - _builtins: {value: new Map([ - ["@variable", variable_variable], - ["invalidation", variable_invalidation], - ["visibility", variable_visibility], - ...builtins - ])}, - _source: {value: null, writable: true} - }); -} - -Object.defineProperties(Module.prototype, { - _resolve: {value: module_resolve, writable: true, configurable: true}, - redefine: {value: module_redefine, writable: true, configurable: true}, - define: {value: module_define, writable: true, configurable: true}, - derive: {value: module_derive, writable: true, configurable: true}, - import: {value: module_import, writable: true, configurable: true}, - value: {value: module_value, writable: true, configurable: true}, - variable: {value: module_variable, writable: true, configurable: true}, - builtin: {value: module_builtin, writable: true, configurable: true} -}); - -function module_redefine(name) { - const v = this._scope.get(name); - if (!v) throw new RuntimeError(`${name} is not defined`); - if (v._type === TYPE_DUPLICATE) throw new RuntimeError(`${name} is defined more than once`); - return v.define.apply(v, arguments); -} - -function module_define() { - const v = new Variable(TYPE_NORMAL, this); - return v.define.apply(v, arguments); -} - -function module_import() { - const v = new Variable(TYPE_NORMAL, this); - return v.import.apply(v, arguments); -} - -function module_variable(observer, options) { - return new Variable(TYPE_NORMAL, this, observer, options); -} - -async function module_value(name) { - let v = this._scope.get(name); - if (!v) throw new RuntimeError(`${name} is not defined`); - if (v._observer === no_observer) { - v = this.variable(true).define([name], identity$1); - try { - return await module_revalue(this._runtime, v); - } finally { - v.delete(); - } - } else { - return module_revalue(this._runtime, v); - } -} - -// If the variable is redefined before its value resolves, try again. -async function module_revalue(runtime, variable) { - await runtime._compute(); - try { - return await variable._promise; - } catch (error) { - if (error === variable_stale) return module_revalue(runtime, variable); - throw error; - } -} - -function module_derive(injects, injectModule) { - const map = new Map(); - const modules = new Set(); - const copies = []; - - // Given a module, derives an alias of that module with an initially-empty - // definition. The variables will be copied later in a second pass below. - function alias(source) { - let target = map.get(source); - if (target) return target; - target = new Module(source._runtime, source._builtins); - target._source = source; - map.set(source, target); - copies.push([target, source]); - modules.add(source); - return target; - } - - // Inject the given variables as reverse imports into the derived module. - const derive = alias(this); - for (const inject of injects) { - const {alias, name} = typeof inject === "object" ? inject : {name: inject}; - derive.import(name, alias == null ? name : alias, injectModule); - } - - // Iterate over all the variables (currently) in this module. If any - // represents an import-with (i.e., an import of a module with a _source), the - // transitive import-with must be copied, too, as direct injections may affect - // transitive injections. Note that an import-with can only be created with - // module.derive and hence it’s not possible for an import-with to be added - // later; therefore we only need to apply this check once, now. - for (const module of modules) { - for (const [name, variable] of module._scope) { - if (variable._definition === identity$1) { // import - if (module === this && derive._scope.has(name)) continue; // overridden by injection - const importedModule = variable._inputs[0]._module; - if (importedModule._source) alias(importedModule); - } - } - } - - // Finally, with the modules resolved, copy the variable definitions. - for (const [target, source] of copies) { - for (const [name, sourceVariable] of source._scope) { - const targetVariable = target._scope.get(name); - if (targetVariable && targetVariable._type !== TYPE_IMPLICIT) continue; // preserve injection - if (sourceVariable._definition === identity$1) { // import - const sourceInput = sourceVariable._inputs[0]; - const sourceModule = sourceInput._module; - target.import(sourceInput._name, name, map.get(sourceModule) || sourceModule); - } else { // non-import - target.define(name, sourceVariable._inputs.map(variable_name), sourceVariable._definition); - } - } - } - - return derive; -} - -function module_resolve(name) { - let variable = this._scope.get(name), value; - if (!variable) { - variable = new Variable(TYPE_IMPLICIT, this); - if (this._builtins.has(name)) { - variable.define(name, constant(this._builtins.get(name))); - } else if (this._runtime._builtin._scope.has(name)) { - variable.import(name, this._runtime._builtin); - } else { - try { - value = this._runtime._global(name); - } catch (error) { - return variable.define(name, rethrow(error)); - } - if (value === undefined) { - this._scope.set(variable._name = name, variable); - } else { - variable.define(name, constant(value)); - } - } - } - return variable; -} - -function module_builtin(name, value) { - this._builtins.set(name, value); -} - -function variable_name(variable) { - return variable._name; -} - -const frame = typeof requestAnimationFrame === "function" ? requestAnimationFrame - : typeof setImmediate === "function" ? setImmediate - : f => setTimeout(f, 0); - -function Runtime(builtins = new Library, global = window_global) { - const builtin = this.module(); - Object.defineProperties(this, { - _dirty: {value: new Set}, - _updates: {value: new Set}, - _precomputes: {value: [], writable: true}, - _computing: {value: null, writable: true}, - _init: {value: null, writable: true}, - _modules: {value: new Map}, - _variables: {value: new Set}, - _disposed: {value: false, writable: true}, - _builtin: {value: builtin}, - _global: {value: global} - }); - if (builtins) for (const name in builtins) { - (new Variable(TYPE_IMPLICIT, builtin)).define(name, [], builtins[name]); - } -} - -Object.defineProperties(Runtime.prototype, { - _precompute: {value: runtime_precompute, writable: true, configurable: true}, - _compute: {value: runtime_compute, writable: true, configurable: true}, - _computeSoon: {value: runtime_computeSoon, writable: true, configurable: true}, - _computeNow: {value: runtime_computeNow, writable: true, configurable: true}, - dispose: {value: runtime_dispose, writable: true, configurable: true}, - module: {value: runtime_module, writable: true, configurable: true}, - fileAttachments: {value: FileAttachments, writable: true, configurable: true}, - load: {value: load, writable: true, configurable: true} -}); - -function runtime_dispose() { - this._computing = Promise.resolve(); - this._disposed = true; - this._variables.forEach(v => { - v._invalidate(); - v._version = NaN; - }); -} - -function runtime_module(define, observer = noop) { - let module; - if (define === undefined) { - if (module = this._init) { - this._init = null; - return module; - } - return new Module(this); - } - module = this._modules.get(define); - if (module) return module; - this._init = module = new Module(this); - this._modules.set(define, module); - try { - define(this, observer); - } finally { - this._init = null; - } - return module; -} - -function runtime_precompute(callback) { - this._precomputes.push(callback); - this._compute(); -} - -function runtime_compute() { - return this._computing || (this._computing = this._computeSoon()); -} - -function runtime_computeSoon() { - return new Promise(frame).then(() => this._disposed ? undefined : this._computeNow()); -} - -async function runtime_computeNow() { - let queue = [], - variables, - variable, - precomputes = this._precomputes; - - // If there are any paused generators, resume them before computing so they - // can update (if synchronous) before computing downstream variables. - if (precomputes.length) { - this._precomputes = []; - for (const callback of precomputes) callback(); - await runtime_defer(3); - } - - // Compute the reachability of the transitive closure of dirty variables. - // Any newly-reachable variable must also be recomputed. - // Any no-longer-reachable variable must be terminated. - variables = new Set(this._dirty); - variables.forEach(function(variable) { - variable._inputs.forEach(variables.add, variables); - const reachable = variable_reachable(variable); - if (reachable > variable._reachable) { - this._updates.add(variable); - } else if (reachable < variable._reachable) { - variable._invalidate(); - } - variable._reachable = reachable; - }, this); - - // Compute the transitive closure of updating, reachable variables. - variables = new Set(this._updates); - variables.forEach(function(variable) { - if (variable._reachable) { - variable._indegree = 0; - variable._outputs.forEach(variables.add, variables); - } else { - variable._indegree = NaN; - variables.delete(variable); - } - }); - - this._computing = null; - this._updates.clear(); - this._dirty.clear(); - - // Compute the indegree of updating variables. - variables.forEach(function(variable) { - variable._outputs.forEach(variable_increment); - }); - - do { - // Identify the root variables (those with no updating inputs). - variables.forEach(function(variable) { - if (variable._indegree === 0) { - queue.push(variable); - } - }); - - // Compute the variables in topological order. - while (variable = queue.pop()) { - variable_compute(variable); - variable._outputs.forEach(postqueue); - variables.delete(variable); - } - - // Any remaining variables are circular, or depend on them. - variables.forEach(function(variable) { - if (variable_circular(variable)) { - variable_error(variable, new RuntimeError("circular definition")); - variable._outputs.forEach(variable_decrement); - variables.delete(variable); - } - }); - } while (variables.size); - - function postqueue(variable) { - if (--variable._indegree === 0) { - queue.push(variable); - } - } -} - -// We want to give generators, if they’re defined synchronously, a chance to -// update before computing downstream variables. This creates a synchronous -// promise chain of the given depth that we’ll await before recomputing -// downstream variables. -function runtime_defer(depth = 0) { - let p = Promise.resolve(); - for (let i = 0; i < depth; ++i) p = p.then(() => {}); - return p; -} - -function variable_circular(variable) { - const inputs = new Set(variable._inputs); - for (const i of inputs) { - if (i === variable) return true; - i._inputs.forEach(inputs.add, inputs); - } - return false; -} - -function variable_increment(variable) { - ++variable._indegree; -} - -function variable_decrement(variable) { - --variable._indegree; -} - -function variable_value(variable) { - return variable._promise.catch(variable._rejector); -} - -function variable_invalidator(variable) { - return new Promise(function(resolve) { - variable._invalidate = resolve; - }); -} - -function variable_intersector(invalidation, variable) { - let node = typeof IntersectionObserver === "function" && variable._observer && variable._observer._node; - let visible = !node, resolve = noop, reject = noop, promise, observer; - if (node) { - observer = new IntersectionObserver(([entry]) => (visible = entry.isIntersecting) && (promise = null, resolve())); - observer.observe(node); - invalidation.then(() => (observer.disconnect(), observer = null, reject())); - } - return function(value) { - if (visible) return Promise.resolve(value); - if (!observer) return Promise.reject(); - if (!promise) promise = new Promise((y, n) => (resolve = y, reject = n)); - return promise.then(() => value); - }; -} - -function variable_compute(variable) { - variable._invalidate(); - variable._invalidate = noop; - variable._pending(); - - const value0 = variable._value; - const version = ++variable._version; - - // Lazily-constructed invalidation variable; only constructed if referenced as an input. - let invalidation = null; - - // If the variable doesn’t have any inputs, we can optimize slightly. - const promise = variable._promise = (variable._inputs.length - ? Promise.all(variable._inputs.map(variable_value)).then(define) - : new Promise(resolve => resolve(variable._definition.call(value0)))) - .then(generate); - - // Compute the initial value of the variable. - function define(inputs) { - if (variable._version !== version) throw variable_stale; - - // Replace any reference to invalidation with the promise, lazily. - for (let i = 0, n = inputs.length; i < n; ++i) { - switch (inputs[i]) { - case variable_invalidation: { - inputs[i] = invalidation = variable_invalidator(variable); - break; - } - case variable_visibility: { - if (!invalidation) invalidation = variable_invalidator(variable); - inputs[i] = variable_intersector(invalidation, variable); - break; - } - case variable_variable: { - inputs[i] = variable; - break; - } - } - } - - return variable._definition.apply(value0, inputs); - } - - // If the value is a generator, then retrieve its first value, and dispose of - // the generator if the variable is invalidated. Note that the cell may - // already have been invalidated here, in which case we need to terminate the - // generator immediately! - function generate(value) { - if (variable._version !== version) throw variable_stale; - if (generatorish(value)) { - (invalidation || variable_invalidator(variable)).then(variable_return(value)); - return variable_generate(variable, version, value); - } - return value; - } - - promise.then((value) => { - variable._value = value; - variable._fulfilled(value); - }, (error) => { - if (error === variable_stale || variable._version !== version) return; - variable._value = undefined; - variable._rejected(error); - }); -} - -function variable_generate(variable, version, generator) { - const runtime = variable._module._runtime; - let currentValue; // so that yield resolves to the yielded value - - // Retrieve the next value from the generator; if successful, invoke the - // specified callback. The returned promise resolves to the yielded value, or - // to undefined if the generator is done. - function compute(onfulfilled) { - return new Promise(resolve => resolve(generator.next(currentValue))).then(({done, value}) => { - return done ? undefined : Promise.resolve(value).then(onfulfilled); - }); - } - - // Retrieve the next value from the generator; if successful, fulfill the - // variable, compute downstream variables, and schedule the next value to be - // pulled from the generator at the start of the next animation frame. If not - // successful, reject the variable, compute downstream variables, and return. - function recompute() { - const promise = compute((value) => { - if (variable._version !== version) throw variable_stale; - currentValue = value; - postcompute(value, promise).then(() => runtime._precompute(recompute)); - variable._fulfilled(value); - return value; - }); - promise.catch((error) => { - if (error === variable_stale || variable._version !== version) return; - postcompute(undefined, promise); - variable._rejected(error); - }); - } - - // After the generator fulfills or rejects, set its current value, promise, - // and schedule any downstream variables for update. - function postcompute(value, promise) { - variable._value = value; - variable._promise = promise; - variable._outputs.forEach(runtime._updates.add, runtime._updates); - return runtime._compute(); - } - - // When retrieving the first value from the generator, the promise graph is - // already established, so we only need to queue the next pull. - return compute((value) => { - if (variable._version !== version) throw variable_stale; - currentValue = value; - runtime._precompute(recompute); - return value; - }); -} - -function variable_error(variable, error) { - variable._invalidate(); - variable._invalidate = noop; - variable._pending(); - ++variable._version; - variable._indegree = NaN; - (variable._promise = Promise.reject(error)).catch(noop); - variable._value = undefined; - variable._rejected(error); -} - -function variable_return(generator) { - return function() { - generator.return(); - }; -} - -function variable_reachable(variable) { - if (variable._observer !== no_observer) return true; // Directly reachable. - const outputs = new Set(variable._outputs); - for (const output of outputs) { - if (output._observer !== no_observer) return true; - output._outputs.forEach(outputs.add, outputs); - } - return false; -} - -function window_global(name) { - return globalThis[name]; -} - -function renderHtml(string) { - const template = document.createElement("template"); - template.innerHTML = string; - return document.importNode(template.content, true); -} - -function renderSvg(string) { - const g = document.createElementNS("http://www.w3.org/2000/svg", "g"); - g.innerHTML = string; - return g; -} - -const html = Object.assign(hypertext(renderHtml, fragment => { - if (fragment.firstChild === null) return null; - if (fragment.firstChild === fragment.lastChild) return fragment.removeChild(fragment.firstChild); - const span = document.createElement("span"); - span.appendChild(fragment); - return span; -}), {fragment: hypertext(renderHtml, fragment => fragment)}); - -Object.assign(hypertext(renderSvg, g => { - if (g.firstChild === null) return null; - if (g.firstChild === g.lastChild) return g.removeChild(g.firstChild); - return g; -}), {fragment: hypertext(renderSvg, g => { - const fragment = document.createDocumentFragment(); - while (g.firstChild) fragment.appendChild(g.firstChild); - return fragment; -})}); - -const -CODE_TAB = 9, -CODE_LF = 10, -CODE_FF = 12, -CODE_CR = 13, -CODE_SPACE = 32, -CODE_UPPER_A = 65, -CODE_UPPER_Z = 90, -CODE_LOWER_A = 97, -CODE_LOWER_Z = 122, -CODE_LT = 60, -CODE_GT = 62, -CODE_SLASH = 47, -CODE_DASH = 45, -CODE_BANG = 33, -CODE_EQ = 61, -CODE_DQUOTE = 34, -CODE_SQUOTE = 39, -CODE_QUESTION = 63, -STATE_DATA = 1, -STATE_TAG_OPEN = 2, -STATE_END_TAG_OPEN = 3, -STATE_TAG_NAME = 4, -STATE_BOGUS_COMMENT = 5, -STATE_BEFORE_ATTRIBUTE_NAME = 6, -STATE_AFTER_ATTRIBUTE_NAME = 7, -STATE_ATTRIBUTE_NAME = 8, -STATE_BEFORE_ATTRIBUTE_VALUE = 9, -STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED = 10, -STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED = 11, -STATE_ATTRIBUTE_VALUE_UNQUOTED = 12, -STATE_AFTER_ATTRIBUTE_VALUE_QUOTED = 13, -STATE_SELF_CLOSING_START_TAG = 14, -STATE_COMMENT_START = 15, -STATE_COMMENT_START_DASH = 16, -STATE_COMMENT = 17, -STATE_COMMENT_LESS_THAN_SIGN = 18, -STATE_COMMENT_LESS_THAN_SIGN_BANG = 19, -STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH = 20, -STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH = 21, -STATE_COMMENT_END_DASH = 22, -STATE_COMMENT_END = 23, -STATE_COMMENT_END_BANG = 24, -STATE_MARKUP_DECLARATION_OPEN = 25, -STATE_RAWTEXT = 26, -STATE_RAWTEXT_LESS_THAN_SIGN = 27, -STATE_RAWTEXT_END_TAG_OPEN = 28, -STATE_RAWTEXT_END_TAG_NAME = 29, -SHOW_COMMENT = 128, -SHOW_ELEMENT = 1, -TYPE_COMMENT = 8, -TYPE_ELEMENT = 1, -NS_SVG = "http://www.w3.org/2000/svg", -NS_XLINK = "http://www.w3.org/1999/xlink", -NS_XML = "http://www.w3.org/XML/1998/namespace", -NS_XMLNS = "http://www.w3.org/2000/xmlns/"; - -const svgAdjustAttributes = new Map([ - "attributeName", - "attributeType", - "baseFrequency", - "baseProfile", - "calcMode", - "clipPathUnits", - "diffuseConstant", - "edgeMode", - "filterUnits", - "glyphRef", - "gradientTransform", - "gradientUnits", - "kernelMatrix", - "kernelUnitLength", - "keyPoints", - "keySplines", - "keyTimes", - "lengthAdjust", - "limitingConeAngle", - "markerHeight", - "markerUnits", - "markerWidth", - "maskContentUnits", - "maskUnits", - "numOctaves", - "pathLength", - "patternContentUnits", - "patternTransform", - "patternUnits", - "pointsAtX", - "pointsAtY", - "pointsAtZ", - "preserveAlpha", - "preserveAspectRatio", - "primitiveUnits", - "refX", - "refY", - "repeatCount", - "repeatDur", - "requiredExtensions", - "requiredFeatures", - "specularConstant", - "specularExponent", - "spreadMethod", - "startOffset", - "stdDeviation", - "stitchTiles", - "surfaceScale", - "systemLanguage", - "tableValues", - "targetX", - "targetY", - "textLength", - "viewBox", - "viewTarget", - "xChannelSelector", - "yChannelSelector", - "zoomAndPan" -].map(name => [name.toLowerCase(), name])); - -const svgForeignAttributes = new Map([ - ["xlink:actuate", NS_XLINK], - ["xlink:arcrole", NS_XLINK], - ["xlink:href", NS_XLINK], - ["xlink:role", NS_XLINK], - ["xlink:show", NS_XLINK], - ["xlink:title", NS_XLINK], - ["xlink:type", NS_XLINK], - ["xml:lang", NS_XML], - ["xml:space", NS_XML], - ["xmlns", NS_XMLNS], - ["xmlns:xlink", NS_XMLNS] -]); - -function hypertext(render, postprocess) { - return function({raw: strings}) { - let state = STATE_DATA; - let string = ""; - let tagNameStart; // either an open tag or an end tag - let tagName; // only open; beware nesting! used only for rawtext - let attributeNameStart; - let attributeNameEnd; - let nodeFilter = 0; - - for (let j = 0, m = arguments.length; j < m; ++j) { - const input = strings[j]; - - if (j > 0) { - const value = arguments[j]; - switch (state) { - case STATE_RAWTEXT: { - if (value != null) { - const text = `${value}`; - if (isEscapableRawText(tagName)) { - string += text.replace(/[<]/g, entity); - } else if (new RegExp(`/]`, "i").test(string.slice(-tagName.length - 2) + text)) { - throw new Error("unsafe raw text"); // appropriate end tag - } else { - string += text; - } - } - break; - } - case STATE_DATA: { - if (value == null) ; else if (value instanceof Node - || (typeof value !== "string" && value[Symbol.iterator]) - || (/(?:^|>)$/.test(strings[j - 1]) && /^(?:<|$)/.test(input))) { - string += ""; - nodeFilter |= SHOW_COMMENT; - } else { - string += `${value}`.replace(/[<&]/g, entity); - } - break; - } - case STATE_BEFORE_ATTRIBUTE_VALUE: { - state = STATE_ATTRIBUTE_VALUE_UNQUOTED; - let text; - if (/^[\s>]/.test(input)) { - if (value == null || value === false) { - string = string.slice(0, attributeNameStart - strings[j - 1].length); - break; - } - if (value === true || (text = `${value}`) === "") { - string += "''"; - break; - } - const name = strings[j - 1].slice(attributeNameStart, attributeNameEnd); - if ((name === "style" && isObjectLiteral(value)) || typeof value === "function") { - string += "::" + j; - nodeFilter |= SHOW_ELEMENT; - break; - } - } - if (text === undefined) text = `${value}`; - if (text === "") throw new Error("unsafe unquoted empty string"); - string += text.replace(/^['"]|[\s>&]/g, entity); - break; - } - case STATE_ATTRIBUTE_VALUE_UNQUOTED: { - string += `${value}`.replace(/[\s>&]/g, entity); - break; - } - case STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED: { - string += `${value}`.replace(/['&]/g, entity); - break; - } - case STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED: { - string += `${value}`.replace(/["&]/g, entity); - break; - } - case STATE_BEFORE_ATTRIBUTE_NAME: { - if (isObjectLiteral(value)) { - string += "::" + j + "=''"; - nodeFilter |= SHOW_ELEMENT; - break; - } - throw new Error("invalid binding"); - } - case STATE_COMMENT: break; - default: throw new Error("invalid binding"); - } - } - - for (let i = 0, n = input.length; i < n; ++i) { - const code = input.charCodeAt(i); - - switch (state) { - case STATE_DATA: { - if (code === CODE_LT) { - state = STATE_TAG_OPEN; - } - break; - } - case STATE_TAG_OPEN: { - if (code === CODE_BANG) { - state = STATE_MARKUP_DECLARATION_OPEN; - } else if (code === CODE_SLASH) { - state = STATE_END_TAG_OPEN; - } else if (isAsciiAlphaCode(code)) { - tagNameStart = i, tagName = undefined; - state = STATE_TAG_NAME, --i; - } else if (code === CODE_QUESTION) { - state = STATE_BOGUS_COMMENT, --i; - } else { - state = STATE_DATA, --i; - } - break; - } - case STATE_END_TAG_OPEN: { - if (isAsciiAlphaCode(code)) { - state = STATE_TAG_NAME, --i; - } else if (code === CODE_GT) { - state = STATE_DATA; - } else { - state = STATE_BOGUS_COMMENT, --i; - } - break; - } - case STATE_TAG_NAME: { - if (isSpaceCode(code)) { - state = STATE_BEFORE_ATTRIBUTE_NAME; - tagName = lower(input, tagNameStart, i); - } else if (code === CODE_SLASH) { - state = STATE_SELF_CLOSING_START_TAG; - } else if (code === CODE_GT) { - tagName = lower(input, tagNameStart, i); - state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA; - } - break; - } - case STATE_BEFORE_ATTRIBUTE_NAME: { - if (isSpaceCode(code)) ; else if (code === CODE_SLASH || code === CODE_GT) { - state = STATE_AFTER_ATTRIBUTE_NAME, --i; - } else if (code === CODE_EQ) { - state = STATE_ATTRIBUTE_NAME; - attributeNameStart = i + 1, attributeNameEnd = undefined; - } else { - state = STATE_ATTRIBUTE_NAME, --i; - attributeNameStart = i + 1, attributeNameEnd = undefined; - } - break; - } - case STATE_ATTRIBUTE_NAME: { - if (isSpaceCode(code) || code === CODE_SLASH || code === CODE_GT) { - state = STATE_AFTER_ATTRIBUTE_NAME, --i; - attributeNameEnd = i; - } else if (code === CODE_EQ) { - state = STATE_BEFORE_ATTRIBUTE_VALUE; - attributeNameEnd = i; - } - break; - } - case STATE_AFTER_ATTRIBUTE_NAME: { - if (isSpaceCode(code)) ; else if (code === CODE_SLASH) { - state = STATE_SELF_CLOSING_START_TAG; - } else if (code === CODE_EQ) { - state = STATE_BEFORE_ATTRIBUTE_VALUE; - } else if (code === CODE_GT) { - state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA; - } else { - state = STATE_ATTRIBUTE_NAME, --i; - attributeNameStart = i + 1, attributeNameEnd = undefined; - } - break; - } - case STATE_BEFORE_ATTRIBUTE_VALUE: { - if (isSpaceCode(code)) ; else if (code === CODE_DQUOTE) { - state = STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED; - } else if (code === CODE_SQUOTE) { - state = STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED; - } else if (code === CODE_GT) { - state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA; - } else { - state = STATE_ATTRIBUTE_VALUE_UNQUOTED, --i; - } - break; - } - case STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED: { - if (code === CODE_DQUOTE) { - state = STATE_AFTER_ATTRIBUTE_VALUE_QUOTED; - } - break; - } - case STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED: { - if (code === CODE_SQUOTE) { - state = STATE_AFTER_ATTRIBUTE_VALUE_QUOTED; - } - break; - } - case STATE_ATTRIBUTE_VALUE_UNQUOTED: { - if (isSpaceCode(code)) { - state = STATE_BEFORE_ATTRIBUTE_NAME; - } else if (code === CODE_GT) { - state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA; - } - break; - } - case STATE_AFTER_ATTRIBUTE_VALUE_QUOTED: { - if (isSpaceCode(code)) { - state = STATE_BEFORE_ATTRIBUTE_NAME; - } else if (code === CODE_SLASH) { - state = STATE_SELF_CLOSING_START_TAG; - } else if (code === CODE_GT) { - state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA; - } else { - state = STATE_BEFORE_ATTRIBUTE_NAME, --i; - } - break; - } - case STATE_SELF_CLOSING_START_TAG: { - if (code === CODE_GT) { - state = STATE_DATA; - } else { - state = STATE_BEFORE_ATTRIBUTE_NAME, --i; - } - break; - } - case STATE_BOGUS_COMMENT: { - if (code === CODE_GT) { - state = STATE_DATA; - } - break; - } - case STATE_COMMENT_START: { - if (code === CODE_DASH) { - state = STATE_COMMENT_START_DASH; - } else if (code === CODE_GT) { - state = STATE_DATA; - } else { - state = STATE_COMMENT, --i; - } - break; - } - case STATE_COMMENT_START_DASH: { - if (code === CODE_DASH) { - state = STATE_COMMENT_END; - } else if (code === CODE_GT) { - state = STATE_DATA; - } else { - state = STATE_COMMENT, --i; - } - break; - } - case STATE_COMMENT: { - if (code === CODE_LT) { - state = STATE_COMMENT_LESS_THAN_SIGN; - } else if (code === CODE_DASH) { - state = STATE_COMMENT_END_DASH; - } - break; - } - case STATE_COMMENT_LESS_THAN_SIGN: { - if (code === CODE_BANG) { - state = STATE_COMMENT_LESS_THAN_SIGN_BANG; - } else if (code !== CODE_LT) { - state = STATE_COMMENT, --i; - } - break; - } - case STATE_COMMENT_LESS_THAN_SIGN_BANG: { - if (code === CODE_DASH) { - state = STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH; - } else { - state = STATE_COMMENT, --i; - } - break; - } - case STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH: { - if (code === CODE_DASH) { - state = STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH; - } else { - state = STATE_COMMENT_END, --i; - } - break; - } - case STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH: { - state = STATE_COMMENT_END, --i; - break; - } - case STATE_COMMENT_END_DASH: { - if (code === CODE_DASH) { - state = STATE_COMMENT_END; - } else { - state = STATE_COMMENT, --i; - } - break; - } - case STATE_COMMENT_END: { - if (code === CODE_GT) { - state = STATE_DATA; - } else if (code === CODE_BANG) { - state = STATE_COMMENT_END_BANG; - } else if (code !== CODE_DASH) { - state = STATE_COMMENT, --i; - } - break; - } - case STATE_COMMENT_END_BANG: { - if (code === CODE_DASH) { - state = STATE_COMMENT_END_DASH; - } else if (code === CODE_GT) { - state = STATE_DATA; - } else { - state = STATE_COMMENT, --i; - } - break; - } - case STATE_MARKUP_DECLARATION_OPEN: { - if (code === CODE_DASH && input.charCodeAt(i + 1) === CODE_DASH) { - state = STATE_COMMENT_START, ++i; - } else { // Note: CDATA and DOCTYPE unsupported! - state = STATE_BOGUS_COMMENT, --i; - } - break; - } - case STATE_RAWTEXT: { - if (code === CODE_LT) { - state = STATE_RAWTEXT_LESS_THAN_SIGN; - } - break; - } - case STATE_RAWTEXT_LESS_THAN_SIGN: { - if (code === CODE_SLASH) { - state = STATE_RAWTEXT_END_TAG_OPEN; - } else { - state = STATE_RAWTEXT, --i; - } - break; - } - case STATE_RAWTEXT_END_TAG_OPEN: { - if (isAsciiAlphaCode(code)) { - tagNameStart = i; - state = STATE_RAWTEXT_END_TAG_NAME, --i; - } else { - state = STATE_RAWTEXT, --i; - } - break; - } - case STATE_RAWTEXT_END_TAG_NAME: { - if (isSpaceCode(code) && tagName === lower(input, tagNameStart, i)) { - state = STATE_BEFORE_ATTRIBUTE_NAME; - } else if (code === CODE_SLASH && tagName === lower(input, tagNameStart, i)) { - state = STATE_SELF_CLOSING_START_TAG; - } else if (code === CODE_GT && tagName === lower(input, tagNameStart, i)) { - state = STATE_DATA; - } else if (!isAsciiAlphaCode(code)) { - state = STATE_RAWTEXT, --i; - } - break; - } - default: { - state = undefined; - break; - } - } - } - - string += input; - } - - const root = render(string); - - const walker = document.createTreeWalker(root, nodeFilter, null, false); - const removeNodes = []; - while (walker.nextNode()) { - const node = walker.currentNode; - switch (node.nodeType) { - case TYPE_ELEMENT: { - const attributes = node.attributes; - for (let i = 0, n = attributes.length; i < n; ++i) { - const {name, value: currentValue} = attributes[i]; - if (/^::/.test(name)) { - const value = arguments[+name.slice(2)]; - removeAttribute(node, name), --i, --n; - for (const key in value) { - const subvalue = value[key]; - if (subvalue == null || subvalue === false) ; else if (typeof subvalue === "function") { - node[key] = subvalue; - } else if (key === "style" && isObjectLiteral(subvalue)) { - setStyles(node[key], subvalue); - } else { - setAttribute(node, key, subvalue === true ? "" : subvalue); - } - } - } else if (/^::/.test(currentValue)) { - const value = arguments[+currentValue.slice(2)]; - removeAttribute(node, name), --i, --n; - if (typeof value === "function") { - node[name] = value; - } else { // style - setStyles(node[name], value); - } - } - } - break; - } - case TYPE_COMMENT: { - if (/^::/.test(node.data)) { - const parent = node.parentNode; - const value = arguments[+node.data.slice(2)]; - if (value instanceof Node) { - parent.insertBefore(value, node); - } else if (typeof value !== "string" && value[Symbol.iterator]) { - if (value instanceof NodeList || value instanceof HTMLCollection) { - for (let i = value.length - 1, r = node; i >= 0; --i) { - r = parent.insertBefore(value[i], r); - } - } else { - for (const subvalue of value) { - if (subvalue == null) continue; - parent.insertBefore(subvalue instanceof Node ? subvalue : document.createTextNode(subvalue), node); - } - } - } else { - parent.insertBefore(document.createTextNode(value), node); - } - removeNodes.push(node); - } - break; - } - } - } - - for (const node of removeNodes) { - node.parentNode.removeChild(node); - } - - return postprocess(root); - }; -} - -function entity(character) { - return `&#${character.charCodeAt(0).toString()};`; -} - -function isAsciiAlphaCode(code) { - return (CODE_UPPER_A <= code && code <= CODE_UPPER_Z) - || (CODE_LOWER_A <= code && code <= CODE_LOWER_Z); -} - -function isSpaceCode(code) { - return code === CODE_TAB - || code === CODE_LF - || code === CODE_FF - || code === CODE_SPACE - || code === CODE_CR; // normalize newlines -} - -function isObjectLiteral(value) { - return value && value.toString === Object.prototype.toString; -} - -function isRawText(tagName) { - return tagName === "script" || tagName === "style" || isEscapableRawText(tagName); -} - -function isEscapableRawText(tagName) { - return tagName === "textarea" || tagName === "title"; -} - -function lower(input, start, end) { - return input.slice(start, end).toLowerCase(); -} - -function setAttribute(node, name, value) { - if (node.namespaceURI === NS_SVG) { - name = name.toLowerCase(); - name = svgAdjustAttributes.get(name) || name; - if (svgForeignAttributes.has(name)) { - node.setAttributeNS(svgForeignAttributes.get(name), name, value); - return; - } - } - node.setAttribute(name, value); -} - -function removeAttribute(node, name) { - if (node.namespaceURI === NS_SVG) { - name = name.toLowerCase(); - name = svgAdjustAttributes.get(name) || name; - if (svgForeignAttributes.has(name)) { - node.removeAttributeNS(svgForeignAttributes.get(name), name); - return; - } - } - node.removeAttribute(name); -} - -// We can’t use Object.assign because custom properties… -function setStyles(style, values) { - for (const name in values) { - const value = values[name]; - if (name.startsWith("--")) style.setProperty(name, value); - else style[name] = value; - } -} - -function length(x) { - return x == null ? null : typeof x === "number" ? `${x}px` : `${x}`; -} - -const bubbles = {bubbles: true}; - -function preventDefault(event) { - event.preventDefault(); -} - -function dispatchInput({currentTarget}) { - (currentTarget.form || currentTarget).dispatchEvent(new Event("input", bubbles)); -} - -function identity(x) { - return x; -} - -let nextId = 0; - -function newId() { - return `__ns__-${++nextId}`; -} - -function maybeLabel(label, input) { - if (!label) return; - label = html`