diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..d0d1a8e --- /dev/null +++ b/404.html @@ -0,0 +1,686 @@ + + + + + + + + + + + + + + + + + + + V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Algorithm/01 Algorithm Analysis/index.html b/Computer Science/Algorithm/01 Algorithm Analysis/index.html new file mode 100644 index 0000000..491b2f9 --- /dev/null +++ b/Computer Science/Algorithm/01 Algorithm Analysis/index.html @@ -0,0 +1,1147 @@ + + + + + + + + + + + + + + + + + + + + + + + Algorithm Analysis - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Algorithm Analysis

+ +

Chapter 1 Algorithm Analysis

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Algorithm/02 Linear List/index.html b/Computer Science/Algorithm/02 Linear List/index.html new file mode 100644 index 0000000..96a673a --- /dev/null +++ b/Computer Science/Algorithm/02 Linear List/index.html @@ -0,0 +1,1088 @@ + + + + + + + + + + + + + + + + + + + + + + + Linear List - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Linear List

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Algorithm/Algorithms and Data Structure/index.html b/Computer Science/Algorithm/Algorithms and Data Structure/index.html new file mode 100644 index 0000000..7f159b1 --- /dev/null +++ b/Computer Science/Algorithm/Algorithms and Data Structure/index.html @@ -0,0 +1,1095 @@ + + + + + + + + + + + + + + + + + + + + + + + Algorithms and Data Structure - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Algorithms and Data Structure

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Basis/GNU Make/index.html b/Computer Science/Programming Basis/GNU Make/index.html new file mode 100644 index 0000000..4cb0acf --- /dev/null +++ b/Computer Science/Programming Basis/GNU Make/index.html @@ -0,0 +1,1421 @@ + + + + + + + + + + + + + + + + + + + + + + + GNU Make - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

GNU Make

+
+

Abstract

+

GNU Make是一个用于自动化编译的工具,它可以根据文件的依赖关系自动执行编译任务.本文将介绍GNU Make的基本使用方法.

+

为啥要学Make?

+

属于是为了这盘醋包了顿饺子,由于数据结构基础这门课的大作业或多或少需要用到多文件编译,我干脆就希望使用Make进行自动化编译,而且在系统课上接触了Makefile的编写,所以就有了这篇文章.

+
+

Part 1 别急,先看看 gcc 编译!

+

gcc的编译过程可以简要分为四个阶段:预处理编译汇编链接.

+

gcc编译工具链是以gcc编译器为核心的一整套工具,主要包含以下三部分内容:

+
    +
  • gcc-core:亦即gcc编译器,用于完成预处理过程和编译过程,将C代码转换成汇编代码;
  • +
  • Binutils:包含了除了gcc编译器以外的一系列小工具,比如汇编器as、连接器ld、目标文件格式查看器readelf等;
  • +
  • glibc:GNU C Library,是GNU组织为了GNU系统以及Linux系统编写的C语言标准库.
  • +
+

1.1 预处理/Pre-Processing

+

预处理阶段的主要任务是处理源文件以#开头的预处理指令,比如#include#define等.这里主要是将#include的一些头文件宏定义进行展开,生成一个.i文件.

+

预处理过程输入的是C的源文件,输出的是一个中间/预加载文件,这个文件还是C代码.此阶段使用gcc参数-E,同时参数-o指定了最后输出文件的名字,下面的例子就将main.c文件经过预处理生成main.i文件

+
gcc -E main.c -o main.i
+
+

1.2 编译/Compiling

+

编译过程使用gcc编译器将预处理后的.i文件通过编译转换为汇编语言,生成一个.s文件.这是gcc编译器完成的工作,在这部分过程之中,gcc编译器会检查各个源文件的语法,即使我们调用了一个没有定义的函数,也不会报错,

+

编译过程输入的是一个中间/预加载文件,输出的是一个汇编文件,当然,直接以C文件作为输入进行编译也是可以的.此阶段使用gcc参数-S,具体例子如下:

+
gcc -S main.i -o main.s
+gcc -S main.c -o main.s
+
+

1.3 汇编/Assembling

+

汇编阶段的主要任务是将汇编语言文件经过汇编,生成目标文件.o文件,每一个源文件都对应一个目标文件.即把汇编语言的代码转换成机器码,这是as汇编器完成的工作.

+

汇编过程输入的是汇编文件,输出.o后缀的目标文件,gcc的参数-c表示只编译源文件但不链接,当然,我们也可以直接输入C源文件,就直接包含了前面两个过程.

+
gcc -c main.s -o main.o
+gcc -c main.c -o main.o
+
+

Linux下生成的.o目标文件、.so动态库文件以及下一小节链接阶段生成最终的可执行文件都是elf格式的, 可以使用 readelf 工具来查看它们的内容.

+

从 readelf 的工具输出的信息,可以了解到目标文件包含ELF头、程序头、节等内容,对于.o目标文件或.so库文件,编译器在链接阶段利用这些信息把多个文件组织起来,对于可执行文件,系统在运行时根据这些信息加载程序运行.

+

1.4 链接/Linking

+

最后将每个源文件对应的.o文件链接起来,就生成了一个可执行程序文件,这是这是链接器ld完成的工作.

+

例如一个工程里包含了A和B两个代码文件,在链接阶段,链接过程需要把A和B之间的函数调用关系理顺,也就是说要告诉A在哪里能够调用到fun函数,建立映射关系,所以称之为链接.若链接过程中找不到fun函数的具体定义,则会链接报错.

+

链接分为两种:

+
    +
  • 动态链接:gcc编译时的默认选项.动态是指在应用程序运行时才去加载外部的代码库,不同的程序可以共用代码库.所以动态链接生成的程序比较小,占用较少的内存.
  • +
  • 静态链接:链接时使用选项--static,它在编译阶段就会把所有用到的库打包到自己的可执行程序中.所以静态链接的优点是具有较好的兼容性,不依赖外部环境,但是生成的程序比较大.
  • +
+
gcc main.o -o main
+gcc main.c -o main --static
+
+

Part 2 Makefile

+

2.1 书写规则

+

Makefile的规则包括两个部分:一个是依赖关系/prerequisites,另一个是生成目标的方法/command.在Makefile中,规则的顺序是很重要的,Makeflie中有且仅有一个最终目标,其他目标都是这个目标连带出来的,一般来说,定义在第一条规则的第一个目标就是最终目标,make完成的就是这个目标.

+

但是我们经常会遇见make a.o这样的命令,make后可以跟着一个或多个target,a.o作为make的参数,指定了执行的内容,优先级比Makefile里边的定义要高.换句话说,倘若make后边有目标,这个目标就是最终目标,make后边没目标,默认执行Makefile的第一个目标.

+

规则的语法是这样的:

+
targets : prerequisites
+    recipe
+    ...
+
+

或者这样的:

+
targets : prerequisites ; command
+    recipe
+    ...
+
+

targets是文件名,可以使用通配符,基本来说,我们的目标基本上是一个文件,可以是一个目标文件,可以是一个可执行文件,还可以是一个标签,是多个文件也是有可能的.

+

prerequisites是生成该target所依赖的文件或者target.

+

recipe是命令行,可以是任意的shell命令,如果其不与target:prerequisites在一行,那么,必须以 Tab 键开头,如果和prerequisites在一行,那么可以用分号做为分隔.如果命令太长,我们可以使用反斜杠\来作为换行符.

+

规则告诉make两件事:一个是文件的依赖关系,target依赖于prerequisites中的文件;另一个时就会如何生成目标文件,生成规则定义在recipe中,makefile最核心的内容是:

+

prerequisites中如果有一个以上的文件比target文件要新的话,recipe所定义的命令就会被执行.

+

2.2 使用变量

+

Makefile中的变量就像是C语言的宏一样,代表着一个文本字符串,在执行的时候会自动展开在所使用的地方,不过,我们可以在Makefile中改变其值.变量可以使用在目标,规则,依赖目标或者其他部分之中.

+

在声明变量的时候,我们需要给予其初值,使用的时候需要在变量名前面加上$符号,最好还用小括号括起来(),变量的名字可以包含字符,数字,下划线,甚至还可以数字开头,但是不能含有:#=或者空字符.

+

我们可以使用其他变量来构造变量的值,比如foo = $(bar),这里的bar不一定非要是已经定义好的值,我们可以使用后面定义的值,这就很好了嘛,我们可以把变量的真实值退到后面去定义,但是无法避免递归定义,虽然make有能力检测这样的定义:-)

+

为了避免这个问题,我们使用:=操作符,对于VAR := value,右边的value会在定义的时候就被展开.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Basis/Linux/index.html b/Computer Science/Programming Basis/Linux/index.html new file mode 100644 index 0000000..7d5d6b7 --- /dev/null +++ b/Computer Science/Programming Basis/Linux/index.html @@ -0,0 +1,1140 @@ + + + + + + + + + + + + + + + + + + + + + + + Linux - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Linux

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Basis/MIT Missing Semester/index.html b/Computer Science/Programming Basis/MIT Missing Semester/index.html new file mode 100644 index 0000000..93f9a70 --- /dev/null +++ b/Computer Science/Programming Basis/MIT Missing Semester/index.html @@ -0,0 +1,1143 @@ + + + + + + + + + + + + + + + + + + + + + + + MIT Missing Semester - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

MIT Missing Semester

+ +
+

Warning

+

待更新!

+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Basis/Regular Expression/index.html b/Computer Science/Programming Basis/Regular Expression/index.html new file mode 100644 index 0000000..e8f3211 --- /dev/null +++ b/Computer Science/Programming Basis/Regular Expression/index.html @@ -0,0 +1,1147 @@ + + + + + + + + + + + + + + + + + + + + + + + Regular Expression - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Regular Expression

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Basis/Shell/index.html b/Computer Science/Programming Basis/Shell/index.html new file mode 100644 index 0000000..08a017c --- /dev/null +++ b/Computer Science/Programming Basis/Shell/index.html @@ -0,0 +1,1231 @@ + + + + + + + + + + + + + + + + + + + + + + + Shell - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Shell

+
+

Abstract

+

这份笔记将专注于bash(也就是Bourne Again SHell),暂不涉及其他种类的shell。

+

下面代码均以本人 Ubuntu 22.04.3 系统中的bash为例。

+
+

Basis

+

我们所熟悉的图像用户界面/Graphical User Interface/GUI在某些情况下反而限制了我们对计算机的使用,shell为我们提供了一种充分利用计算机的方式,它允许我们执行程序、输入并且获取某种半结构化的输出。

+

打开终端,我们就可以使用shell,下面就是我们一般看起来的样子。

+
test@testMachine:~$
+
+

其中test是用户名;testMachine是主机名;~是当前工作目录,特别地,~代表home$是提示符,表示现在的身份不是root用户。在提示符后面,我们可以输入命令,命令最终会被shell解析并且执行。我们现在执行一些基本的命令:

+
test@testMachine:~$ date
+Thu 14 Oct 2021 10:00:00 PM CST
+test@testMachine:~$ echo hello
+hello
+
+

在这个例子中:

+
    +
  • +

    我们不仅可以直接输入类似date的命令,还可以向shell传递参数,比如echo hello

    +
  • +
  • +

    如果我们想让shell输出hello world,方法之一是使用单引号或者双引号包裹起来,

    +
  • +
  • +

    我们让shell执行了echo命令

    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Basis/index.html b/Computer Science/Programming Basis/index.html new file mode 100644 index 0000000..812030e --- /dev/null +++ b/Computer Science/Programming Basis/index.html @@ -0,0 +1,1132 @@ + + + + + + + + + + + + + + + + + + + + + + + Index - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Index

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Language/C++/index.html b/Computer Science/Programming Language/C++/index.html new file mode 100644 index 0000000..c3a4b30 --- /dev/null +++ b/Computer Science/Programming Language/C++/index.html @@ -0,0 +1,1119 @@ + + + + + + + + + + + + + + + + + + + + + + + C++ - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

C++

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Language/C/index.html b/Computer Science/Programming Language/C/index.html new file mode 100644 index 0000000..b9fe14f --- /dev/null +++ b/Computer Science/Programming Language/C/index.html @@ -0,0 +1,3506 @@ + + + + + + + + + + + + + + + + + + + + + + + C - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +
+

Warning

+

未完工!等我学完CS61A后再接着写吧QAQ。

+
+

EVERYTHING begins with C

+

Chapter 0:Preface

+

0.1 初衷

+

这个笔记建立的初衷是帮助笔者深刻记忆C语言的语法和特性,也作为加深对C语言的理解的工具(似乎终极目的就是提升程算分数编程能力)使用。

+

C语言因为其比较贴近底层,语法精简而高效,扩展性和可移植性强而闻名,因而作为计算机专业学生的第一门语言存在。另外,笔者在学习完C后,学习Python的过程极其愉悦()

+

Chapter 1 Basis

+

常见数据类型

+

字面量即一个值:

+
    +
  • +

    整型:123表示十进制的123;0123表示八进制的123,亦即十进制的83;0x123是十六进制的123,亦即十进制的291。

    +
  • +
  • +

    字符型:

    +
  • +
  • +

    一个字符类型相当于一个字节的整型,所以字符类型可以通过整型来表示:char c = 65

    +
  • +
  • 引号里的反斜杠\有转义的效果,比如'\n'表示一个控制字符,而反斜杠只有通过\\才能表示出来。
  • +
  • 反斜杠后边可以接最多三个数字,并且此时使用八进制表示一个字节,且遇见0~7之外的数字就会阶数当前字节,比如'\101'表示A,而'08'由于8超过了八进制的范围,这就是两个字符放在了一个单引号里边,是错误的用法,如果写成字符串,"\08"就表示两个字符:一个空字符和一个8
  • +
  • \x后边接在0-9A-F内的字符,可以通过十六进制表示一个字符,不过没有长度限制,遇到范围外的字符就结束,比如\x000041也是一个字符。
  • +
+

字节分配:char1byte,short2byte,int4byte,long 4byte,long long8byte, float4byte,double8byte,pointer4/8byte。

+

运算符优先级

+
    +
  • 优先级最高的:(Left-to-Right)后缀运算符:后缀形式的递增递减、函数调用、数组下标、访问结构、复合字面量。
  • +
  • 优先级略低的:(Right-to-Left)单目运算符:前缀形式的递增递减、单目的正负、逻辑非和按位非、强制类型转换、解引用、取地址、sizeof、对齐。
  • +
  • 算数运算:(Left-to-Right)乘除取余、加减、移位——优先级递减。
  • +
  • 关系运算:(Left-to-Right)不等关系、相等关系。
  • +
  • 位运算:(Left-to-Right)按位与、异或、或。
  • +
  • 逻辑运算:(Left-to-Right)逻辑与、逻辑或。
  • +
  • 条件运算:(Right-to-Left)三目运算符?:
  • +
  • 赋值运算:(Right-to-Left)各种赋值,包括复合的赋值运算。
  • +
  • 逗号运算符:(Left-to-Right),
  • +
+

% & <<不能用在double\float上。

+

printf()的转换说明修饰符

+

const

+

Chapter 3 函数

+

3.2 内联函数

+

Chapter 4 数组和指针

+

重要:声明一个指针只会分配一个给指针变量的空间(这部分空间用来存储它指向的位置的地址值),而不会分配指向的空间。使一个指针可用可以将其它变量取地址赋值给它,这样它指向的位置就是有效的。或者通过 malloc来新分配一块堆上的内存,malloc 的返回值就是这块内存的首地址,也是你可用的。

+

:二维数组不能退化为二级指针;数组名不能被重新赋值。

+

:数组是数组,指针是指针(这里指类型)。

+

:指针相减的意义是计算两个指针相差几个“单位”的距离,而不是将其值简单的相减。比如:

+
    +
  • +

    c + int a[] = {1, 2, 3, 4, 5}; + int *p = a, *q = &a[2]; + printf("%lu", q-p); // Output: 2

    +
  • +
  • +

    c + double a[]={1, 2, 3, 4, 5}; + printf("%d", (int)&a[3] - (int)&a[0]); // Output: 24

    +
  • +
  • +
+

神坑:变长数组不能通过int a[n] = {0};的方式初始化

+

Chapter 5:字符串和字符串函数

+

5.1 字符串的定义与初始化

+

字符串其实是以空字符\0结尾的char类型数组,因此,我们可以像处理一般数组的方式处理字符串,比如:

+
char words[81] = "I am a string in an array.";//定义字符串words
+words[8] = 'p';//将字符串的第9个字符改为'p'
+const char* MSG = "This cannot be changed";//定义只读字符串MSG
+
+

如果要打印MSG[22],则输出的是空字符,空字符不是空格,不会在输出窗口占用位置,只是标志字符串数组的结束。

+

我们一般用三种方法定义字符串:字符串常量、char类型数组、指向char类型的指针。被双引号括起来的内容被视为指向该字符串存储位置的指针,这类似于将数组名作为指向该数组的指针。比如以下程序:

+
printf("%s,%p,%c","We","are","champions");
+//Output: We,0x10000f61,c
+
+

我们对字符串用%c%p进行转换的时候,转换过去的其实是字符串第一个元素的地址和其对应的字符

+

数组形式的字符串(如char arr1[] = "III" )在计算机的内存中分配一个内含4个元素的数组,每个元素作为一个字符,且最后一个元素为空字符。先将字符串常量存储在静态存储区中,程序开始运行之后为数组分配内存,初始化数组将静态存储区的字符串拷贝到数组中,编译器将数组名arr1作为该数组首元素地址的别名,而且作为地址常量,不能被改变。

+

一般来说,指针形式的定义一般于字符串字面量一起使用,被双引号括起来的内容是字符串字面量,而且被视为字符串的地址。指针形式(如char *pt1 = "III"让编译器在静态存储区中分配4个元素的空间,开始运行程序时,编译器为指针变量(*pt1)留出一个存储位置,该变量最初指向该字符串的首字母,但是它的值可以被改变,即可以使用递增运算符。

+

由于指针形式字符串的存储形式,一般建议将指针初始化为字符串自变量时使用const 限定符。

+

编译器可以使用内存中的一个副本来表示所有完全相同的字符串字面量,所以下面程序打印出来的都是"Jey"

+
char *p1 = "Hey";
+p1[0] = 'J';
+printf("Hey");
+printf("%s","Hey");
+
+

由于数组名是一个指针变量,所以不能用str1 = str2 来简单地拷贝数组,这样只会让两个指针指向相同的内存区域。

+

我们可以定义字符串数组,也就是通过数组下标来访问不多个不同的字符串,有两种方式:使用存储字符串指针的数组或者多维数组:

+
const char* strarr1[3] = {
+    "Hello",
+    "Pardon",
+    "Excuse me";
+};
+char strarr2[3][10] = {
+    "Hello",
+    "Pardon",
+    "Excuse me";
+};
+
+

这两种方式最后实现的效果是几乎一样的,都代表着五个字符串,只使用一个下标时只代表一个字符串。比如strarr1[0]strarr2[0]都代表着字符串 "Hello"

+

一般来说对数组的操作都是依赖于指针进行的。

+

5.2 字符串输入和输出

+

5.2.1 分配空间

+

最简单的分配空间的方式就是在 stack 上建立数组变量,而且还只能如此建立

+
char name[81];
+scanf("%s",name);
+
+

再就是利用C库函数malloc()分配内存,比如char *name = (char *) malloc (sizeof(char)*8)这样就可以按照数组形式的字符串来使用字符串了

+

5.2.2 危险的gets()函数

+

C11标准中,废弃了不安全的gets()函数,但是大多数编译器为了兼容性,仍然保留gets()函数。

+

gets()函数读取一整行输入,直到遇到换行符,然后丢弃换行符,存储其余字符在传递进来的字符串指针指向的地址上,并在字符的末尾添加一个空字符,使其成为字符串。比如:

+
int strl = 10;
+char words[strl];
+puts("Enter a string please.");
+gets(words);
+puts(words):
+
+

puts()函数经常和gets()函数一起使用,这个函数用于显示字符串,并且在字符串的末尾添加换行符。

+

使用gets()函数时,gets()函数只知道数组的开始处,而不会检查数组的长度和字符串的长度是否相融洽。如果输入的字符串过长,超出了数组的存储范围,就会造成缓冲区溢出(buffer overflow),读取的数据将一直向后存储,覆盖掉后边内存上的内容,如果这些多余的字符只是占用了未被使用的内存,就不会立刻出现问题,而如果擦写掉了程序中的其余内存,这样就会让程序异常终止,或者出现其他情况。

+

出现fragmentation fault的错误的时候,一般是程序试图访问某些未被分配的内存。

+

5.2.3 gets()的替代品

+
    +
  • fgets()fputs()函数
  • +
+

fgets()函数接受三个参数:字符串存储的位置、读入字符的最大数量和要输入的文件。

+

fgets()函数接受的第二个参数时读入数组的最大数量,如果该参数的值是n那么fgets()将读入n-1个字符,并且在最后加上一个空字符,或者读到第一个换行符号为止。

+

fgets()函数的第三个参数指明要读入的文件,如果是从键盘读入数据,那么以stdin作为参数,或者输入文件指针。

+

当输入行不溢出的时候,fgets()函数将换行符放在结尾,这与fputs()函数的特性相仿:这个函数在打印字符串的时候不会在最后加上换行符。可是如果使用puts()函数一起使用,那么可能就会发现出现了两个换行。

+

fputs()函数接受两个参数:第一个指出要写入的字符串的位置,第二个指出目标写入的位置,如果输出到屏幕上,那么输入stdout作为参数。

+

fgets()返回指向char的指针,如果一切顺利,函数返回的地址和传入的第一个参数相同,如果传到文件的结尾,将返回一个特殊的指针:空指针(null pointer),这个指针不会指向有效的数据,所以可以用来标识特殊情况。在代码钟可以用数字0来代替,但是C利用宏NULL来代替。下面是一个很有意思的例子:

+
char words[10];
+while(fgets(words,10,stdin) != NULL && words[0]!='\n')
+{
+    fputs(words,stdout);
+}
+
+//Input :By the way,it returns a NULL pointer.
+//Output:By the way,it returns a NULL pointer.
+
+

这个程序的实际操作过程是:首先fgets()函数读入9个字符,在后边加入\\0之后交给fputs()函数输出,但是此时不输出换行符,接着进入下一轮迭代,fgets()函数继续读入字符、交给fputs()函数输出……

+
    +
  • +

    gets_s()函数

    +
  • +
  • +

    s_gets()函数

    +
  • +
+

我们可以利用fgets()函数自行创建一个读取整行输入,并且利用空字符取代换行符、或者读取一部分字符,丢弃溢出的字符(其余部分的字符)的函数:

+
char *s_gets(char *st, int n){
+    char *ret_val;
+    int i = 0;
+    ret_val = fgets(st, n, stdin);
+    if(ret_val){
+        while(st[i] != '\n' && st[i] != '\0')
+            i++;
+        if(st[i] == '\n')
+            st[i] = '\0';
+        else
+            while(getchar()!= '\n')
+                continue;
+    }
+    return ret_val;
+}
+
+

利用字符串函数,我们可以对函数进行修改,让它更加简洁。

+
char *s_gets(char *st, int n)
+{
+    char *ret_val;
+    char *find;
+
+    ret_val = fgets(st, n, stdin);
+    if(ret_val)
+    {
+        find = strchr(st, '\n');
+        if(find)
+            *find = '\0';
+        else
+            while(getchar() != '\n')
+                continue;
+    }
+    return ret_val;
+}
+
+

如果fgets()函数返回NULL,则证明读到文件结尾或者读取错误,s_gets()函数跳过了这个过程。

+

我们丢弃多余的字符的原因是:这些多余的字符都存储于缓冲区之中,如果我们下一个要读取的数据是double类型的,那么就可能造成程序崩溃(因为输入了char类型甚至char*类型的数据),丢弃剩余行的数据可以令读取语句和键盘输入同步。

+

这个函数并不完美,因为它在遇到不合适的输入的时候毫无反应,并且丢弃多余的字符的时候,不会告诉程序也不会告诉用户。但是至少会比gets()函数安全的多;-)。

+
    +
  • scanf()函数
  • +
+

scanf()函数和%s转换说明可以读取字符串,但是scanf()函数在读取到空白字符(包括空格、换行符和空字符)的时候会终止对字符串的读取。scanf()函数还有另外一种确定输入结束的方法,也就是指定字符宽度,比如%5d,那么scanf()将在读取完五个字符或者读取到第一个空白字符后停止。

+

5.2.4 字符串输出

+
    +
  1. 在输出字符串的时候,我们必须确定字符串末尾有指示终止的空字符,下面就是一个错误的例子:char words[]={'H','e','y','!'};
  2. +
+

由于这个字符数组(不是字符串!)结尾并未有空字符,所以words不是字符串,如果我们使用这样的代码:put(words)puts()函数由于未识别到空字符,就会一直向下读取、输出后续内存中的内容,这或许是 garbage value ,直到读到内存中的空字符(内存中还是有不少空字符的)。

+
    +
  1. +

    puts()函数很容易使用,只需要传入需要输出的字符串的地址就可以了,它在输出的时候会在后边加上一个换行符。但是puts()函数的返回值众说纷纭:某些编译器返回的是输出的字符的个数,某些编译器输出的是输出的最后一个字符,有的干脆就返回一个非零的整数。

    +
  2. +
  3. +

    fputs()函数需要接受两个参数,一个是字符串的地址,另一个是写入的地址:这一般是文件指针,如果需要输出到屏幕上,传入stdout则可。这个函数的特点在于不会输出换行符。

    +
  4. +
  5. +

    printf()函数需要转换说明,它的形式更复杂些,需要输入更多的代码,计算机执行的时间会更长,但是优点在于可以更容易地输出更复杂、更多的字符串。

    +
  6. +
+

5.2.5 自定义输入输出函数

+

5.3 字符串函数

+

这里讲的字符串函数是指定义在头文件string.h内的函数。

+
    +
  1. strlen()函数
  2. +
+

strlen()函数的实现其实很简单,我们写一个while循环就好了(),strlen()函数接受字符串地址,返回一个unsigned int的值来表示字符串的长度。

+

重要的是我们可以利用strlen()函数来得到字符串的一些性质参数,进而更容易实现对字符串的操作,比如我们可以利用下面自行设计的函数来实现字符串的截断:

+
char *vit(char str[],unsigned int point)
+{
+     unsigned int length = strlen(str);
+     if(point > length - 1)
+     {
+         return str;
+     }
+     else
+     {
+         str[point]='\\0';
+         return str;
+     }   
+ }
+ //或者:if(strlen(str)>point)
+ //      {
+ //      str[point] = '\\0';
+ //  }
+
+
    +
  1. strcat()函数
  2. +
+

strcat()函数接受两个字符串作为参数,用于将两个字符串拼接在一起,更确切地说是将第二个字符串的拷贝附加在第一个字符串的末尾,并且将拼接后的字符串作为第一个字符串,第二个字符串不变。strcat()函数返回第一个参数。

+

strcat()函数和gets()函数一样,如果使用不当,也会导致缓冲区溢出。但是gets()函数被废弃的原因在于无法控制用户向程序里边输入什么,但是程序员是可以控制程序干什么的。因此,在经历输入的检查之后,我们认为至少程序是比较安全的,而使用strcat()函数不当导致缓冲区溢出的情况,被认为是程序员粗心导致的,而C语言相信程序员,程序员也有责任确保strcat()函数的使用安全。

+
    +
  1. strncat()函数
  2. +
+

为了避免strcat()函数的不安全的可能,我们类似fputs()函数那样,添加第二个参数,确定最大添加字符数,这就是strncat()函数的逻辑。

+

strncat()函数接受三个参数,两个字符串指针和最大添加字符量,在加到最大字符量或者遇到空字符的时候停止。

+

配合strlen()函数,strncat()函数可以很好用。

+
    +
  1. strcmp()函数和strncmp()函数
  2. +
+

首先,我们比较两个字符串的时候,比较的是字符串的内容,而不是字符串的地址,所以我们不能做判断指针是否相等的操作,而利用循环挨个判断还蛮复杂,这就是strcmp()函数诞生的逻辑。

+

strcmp()函数接受两个字符串指针参数,如果字符串内容完全相等(包括大小写),strcmp()函数就会返回0,否则返回非零值。

+

在字符串内容不一样的时候,如果第一个字符串的字符在ASCII码在第二个字符串的之前,strcmp()返回负数,反之返回正数;在某些编译器中,会作更加复杂的操作,也就是返回两字符的ASCII码的差。

+

strcmp()函数会一直比较字符是否相同,直到出现不同或者字符串结束,这样的比较方式显得就非常笨重,而strncmp()函数提供了一种更为灵活的选择:strncmp()函数接受的第三个整数参数指定了比较到第几个字符(这里从1开始计数 ;-) )比如strncmp(str1,"strings",7)就指定只查找strings这七个字符。

+
    +
  1. strcpy()函数和strncpy()函数
  2. +
+

strcpy()函数

+
    +
  1. +

    sprint()函数

    +
  2. +
  3. +

    memcpy()函数

    +
  4. +
  5. +

    Others.

    +
  6. +
+
    +
  • +

    strchr()函数

    +
  • +
  • +

    strrchr()函数

    +
  • +
  • +

    strstr()函数

    +
  • +
  • +

    atoi()函数

    +
  • +
  • +

    Character Classification

    +

    isalpha()函数

    +

    isalpha()函数属于一类的函数还有

    +

    tolower()toupper()函数

    +

    cppreference 上对这两个函数归类为 Character Manipulation 解释是:converts a character to lowercase/uppercase.

    +
  • +
+

+

Chapter 6:存储类别和内存管理

+

6.1 存储类别

+

6.1.1 总览

+

6.1.2 关键词

+
    +
  • 其实这种关键词叫做存储类别说明符。
  • +
  • static关键词让变量具有内部链接,同时具有静态存储期。
  • +
  • extern关键词让变量具有外部链接,同时具有静态存储期。
  • +
+

6.1.3 作用域

+

作用域描述程序中可以访问标识符的区域,包括:块作用域,函数作用域,函数原型作用域和文件作用域。

+
    +
  • +

    是用一对花括号括起来的代码区域,包含for循环、while循环、do while循环和if语句所控制的代码,就算这些代码没有被花括号括起来,这也算是一个块。定义在块中的变量具有块作用域(block scope),它的可见范围只是在块内,或者说从定义处到包含该定义的块的末尾。此外,函数的形式参数虽然在花括号表示的块之前,但还是具有块作用域。只有在块内的语句才能访问具有块定义域的变量。

    +
  • +
  • +

    函数作用域仅仅用于goto语句的标签,当这个标签首次出现在函数的内层时,作用域也延伸到整个函数。函数作用域有效防止了标签混乱的情况发生,当然更好的处理方式或许是干脆不用goto语句()

    +
  • +
  • +

    函数原型作用域的作用范围时从形式参数定义处到函数原型声明结束。这表明编译器更多的关心形式参数的类型而不是形参名,而只有在变长数组中,形参名才更有用。

    +
  • +
  • +

    如果在函数的外边定义了一个变量,比如以下程序:

    +
  • +
+
#include<stdio.h>
+int glb_val =1;
+int main(void)
+{
+    printf("%d",glb_val);
+}
+
+

这里的变量glb_val就具有文件作用域,更确切地说,具有外部链接的文件作用域,我们也叫它为全局变量。

+

Tip:这里的glb_val它的作用域是从定义处到文件结束。

+

6.1.4 翻译单元

+

某些我们认为的多个文件可能在编译器里边以单个文件的形式出现,比如C预处理器就将头文件里边的内容替换#include指令。所以,编译器将源代码文件和所有的头文件都看作是一个包含着信息的单独文件,这个文件被称为是翻译单元(translation unit)。

+

如果程序由多个源代码文件组成,那么这个程序也由多个翻译单元组成,每个翻译单元对应着一个源代码文件和它的头文件。

+

目前我们的程序还不进行多文件处理。

+

6.1.5 链接

+

C 文件有着三种链接属性:外部链接、内部链接和无连接。具有块作用域、函数作用域和函数原型作用域的变量都是无连接变量。具有文件作用域的变量可以是外部链接也可以是内部链接。具有内部链接的变量只能在一个翻译单元使用,而具有外部链接的变量能在多文件程序中使用。

+

使用extern关键词,或者直接在函数外边定义的变量都是具有外部链接的变量,而使用static关键词的变量是具有内部链接的变量。

+

6.1.6 存储期

+

存储期(storage duration)描述了通过这些标识符访问的对象的生存期,某些变量存储期一过,它所占的内存就会被释放,相应的,存储的内容也会丢失。C对象有着四种存储期:静态存储期、自动存储期、线程存储期和动态分配存储期。

+
    +
  • 如果对象具有静态存储期,那么对象在程序的执行期间就会一直存在,并且只在主调函数前初始化一次,内存不会被释放。关键词externstatic表明了对象的链接属性与存储期(静态存储期)。The static/extern specifier specifies both static storage duration (unless combined with _Thread_local) and internal/external linkage.
  • +
  • 具有块作用域的变量一般具有自动存储期,当程序进入这些变量的块的时候时,为这+些变量分配内存,当退出这个块的时候,就释放刚才分配的内存。值得注意的时,变长数组的存储期是声明处到块的末尾。
  • +
  • 线程存储期用于并发程序设计
  • +
  • 动态分配存储期
  • +
+

6.1.7 自动变量

+

声明在函数头、块内的变量属于自动存储类别的变量,具有自动存储期,块作用域且无连接。我们可以在C中使用关键词auto来表明这个变量的存储类型是自动变量。

+

6.1.8 寄存器变量

+

我们使用关键词register来表示该变量的存储类型为寄存器变量。寄存器变量存储在CPU的寄存器之中,寄存器是计算机最快的可用内存,因此访问并且处理这些变量的速度会更快,但是无法获取寄存器变量的地址(因为它没有内存位置)。寄存器变量在绝大多数方面都和自动变量一样,也就是具有块作用域、无链接和自动存储期。

+

声明变量为register类型更像是一种请求而不是命令,因为编译器必须根据寄存器或者最快可用内存数量来衡量请求;并且由于寄存器的大小有限(通常是一个字,亦即4或8字节),可以声明为寄存器变量的数据类型有限,比如寄存器可能就没有足够大的空间来存储double类型的值。计算机很可能会忽略我们的请求,变量则被声明成一般的自动变量(也就是存储在内存之中),即使这样,仍然不能对该变量使用取地址运算符。

+

6.1.9 块作用域的静态变量

+

我们可以创建具有块作用域、无连接的静态变量,只需要在块中(这样就提供块作用域和无连接了)用存储类别说明符static(提供静态存储期)说明这个变量就可以了。

+

编译器在程序的生命周期内保证静态变量的存在,静态变量只会在程序中被初始化一次,不会在离开和进入作用域时被销毁或者重置。这是因为静态变量和外部变量在程序被载入内存的时候已经执行完毕,所以在逐个步骤调试的时候会发现含有 static声明的变量不太像时程序中的变量 ;-)

+

6.1.10 外部链接和内部链接的静态变量

+

外部链接的静态变量具有文件作用域、外部链接和静态存储期,该类别有时被称为外部存储类别,属于该类别的变量称为外部变量。如果未初始化外部变量,则其被默认初始化为0只能用常量表达式初始化文件作用域变量(除了变长数组以外,sizeof()表达式可以看作常量表达式)。

+

全局变量在main()函数执行之前完成初始化。

+

我们在文件之间共享全局变量的时候需要特别小心,可以使用以下两个策略:其一,遵循外部变量的常用规则,亦即在一个文件之中使用定义式声明,在另一个文件之中使用引用式说明(使用extern关键字);其二,将需要共享的全局变量放在一个头文件之中,在其他文件中包含这个头文件就可以了,然而,这种处理方式需要我们在头文件中使用static关键词,如果我们不使用static关键词或者使用extern关键词,那么我们就在每一个文件之中都包含了一个定义式声明,C标准是不允许这样子的。然而头文件实际上是给每一个文件提供了一个单独的数据副本,数据是重复的,浪费了很多的内存。

+
int exint = 1;          //declaration 1
+extern int falseint;    //declaration 2
+int main(void){
+    /*内部不表*/
+    extern int exint;   //declaration 3
+}
+
+

考虑上面的例子:对于外部变量来说,第一次声明declaration 1被称为定义式声明(defining definition),为变量预留了存储空间;第二次声明declaration 3被称为引用式声明(referencing definition),关键词extern表明此次声明不是定义,指示编译器到别处查询定义,这表明declaration 2是不正确的,这时编译器假定falseint定义在程序别处,不会引起分配空间。因此我们不要用extern关键字创建外部定义只使用它引用外部定义

+

使用关键字static可以声明内部链接的静态变量,只需要在函数外使用static声明就可以,并且在函数内使用时使用extern进行引用式声明即可,但是extern并不改变链接属性

+

6.1.11 存储类别和函数

+

函数也有存储类别,可以是外部函数(默认)、静态函数或者内联函数。

+
    +
  • 使用extern关键词定义的函数是外部函数,是为了表明当前文件中使用的函数被定义在别处,除非使用static关键词,一般函数声明都默认为extern
  • +
  • 使用static关键词定义的函数是静态函数,静态函数只能用于其定义所在的文件。可以在其他文件中定义与之同名的函数,这样子就避免了名称冲突的问题。
  • +
  • 内联函数:inline
  • +
+

6.2 动态分配内存

+

我们在前面所探讨的存储类别都有一个共同之处,在确定好存储类别之后,就只能根据确定好的内存存储规则,自动指定存储期和作用域。但是我们也可以利用库函数灵活分配和管理内存,只不过必须好好利用指针。

+

我们下面讨论malloc()free()calloc()realloc()函数。

+

6.2.1 void* malloc(size_t size)函数

+

malloc()函数接受一个参数:所需要的内存字节数,之后它会找到合适的内存块,匿名分配sizebyte大小的内存,返回动态分配内存块的首字节地址。如果无法分配内存,malloc()函数就会返回一个空指针。最早,由于char类型只占用一个字节,所以malloc()函数返回一个char *类型的指针,后来malloc()返回void *类型的通用指针,指向什么都可以,完全不需要考虑类型匹配的问题,但是为了增加代码的可读性,应该坚持强制类型转换。

+

我们可以利用malloc()函数提供第三种声明数组的方式:将调用malloc()函数的返回值赋给指针,利用指针访问数组的元素,这样创建的其实是一个动态数组。比如:

+
double *ptd;
+ptd = (double *) malloc(30*sizeof(double));
+
+

我们完全可以使用正常声明数组一样的方式访问这个数组ptd,比如ptd[18]

+

malloc()函数也可以声明多维数组,但是语法会复杂一些:

+
int numrow = 6,numcolumn = 5;
+int **array2 = (int **)malloc(sizeof(int*)*numrow);
+for(int i = 0; i<m; i++)
+{
+    array2[i] = (int *)malloc(sizeof(int)*numcolumn);
+}
+//或者
+int (* array)[numcolumn] = (int (* array)[numcolumn])malloc(sizeof(int)*numcolumn*numrow);
+
+

先看第一种定义方式:在第二行创建了一个二级指针,也就是存储着指针的数组array2,在接下来的循环中,逐个为二维数组的每一行分配空间,同时将数组指针存储在array2[i]中。在读取元素array2[1][2]的时候,我们先读取出array2[1],发现是个指针(其实是数组),然后读取这个数组的第三个元素(编号是2),这样就读出来了元素array2[1][2]

+

再看第二种定义方式:简而言之,等号左侧定义了一个指针变量array,指向的是int[numcolumn]类型的指针,说白了array也是一个二级指针。如果还要整花活,我们发现*(*(array+1)+2)array[1][2]其实是一样的。换句话说,array指向一个内含6个整型的数组,因此array[i]表示一个由numcolumn个整数构成的元素,array[i][j]表明一个整数。

+

逻辑上看,二维数组是指针的数组(亦即二级数组);但是从物理上来看,二维数组是一块连续的内存,对于二维数组array3[4][5]:我们完全可以按照5进制来理解这块内存的排布,五进制数 ij 表示的数所对应的内存上边的内容就是array[i][j]存储的内容。

+

6.2.2 void* calloc(size_t num,size_t size)函数

+

calloc()函数分配numsize大小的连续内存空间,并且将每一个字节都初始化为0,所以calloc()调用的结果是分配了num*size个字节长度的内存空间。calloc()函数的返回值和malloc()函数的一样。

+

6.2.3 void* realloc(void* ptr,size_t new_size)函数

+

realloc()函数重新分配指针ptr指向位置内存块的大小。函数返回新分配内存块的起始位置的地址,并且原指针ptr在调用后不再可用。

+

realloc()函数被调用时,只会做下面两种行为之中的一种:

+
    +
  • 其一,将ptr指向的内存区域扩大或者缩小,并且尽可能保留剩余原有区域的内容(The contents of the area remain unchanged up to the lesser of the new and old sizes.),如果内存区域扩大,新的内存内容为未定义的(the contens of the new part of the array are undefined.)。
  • +
  • 其二,重新分配一块新的内存,将原内存区域的内容拷贝过来,并释放原内存(copying memory area with size equal the lesser of the new and the old sizes, and freeing the old block.)。
  • +
+

6.2.4 void free(void *ptr)函数

+

free()函数接受先前被malloc(),calloc(),realloc()动态分配过的内存地址,之后将这些内存释放(deallocate),如果free()接受一个空指针,那么它什么都不会做。free()函数不返回任何值。如果free()函数接受的参数不是先前被malloc(),calloc(),realloc()分配过的内存地址,它的行为并未被定义。(The behavior is undefined if the value of ptr does not equal a value returned earlier by malloc(),calloc(),realloc())我们也不能释放同一内存两次(The behavior is undefined if the memory area referred to by ptr has already been deallocated, that is, free(), free_sized(), free_aligned_sized() (since C23), or realloc() has already been called with ptr as the argument and no calls tomalloc(), calloc(), realloc() or aligned_alloc() (since C11) resulted in a pointer equal to ptr afterwards.)。

+

最重要的是:动态分配的内存必须被释放,否则会发生内存泄漏(memory leak)

+

6.3 ANSI C 类型限定符

+

值得注意的是,C99标准为限定符增加了一个新的属性:幂等性。也就是说可以在同一个声明之中使用多个相同的限定符,多余的限定符将被忽略。

+

6.3.1 const限定符

+

const关键词声明的对象将成为只读变量,其值不能通过赋值、递增或递减等方式修改,但是至少初始化变量是没问题的,这样我们就只可以使用但不能修改对象的值了。

+

如果对指针使用const限定符,如果const限定符在*的前面,也就是const int *num或者int const *num,其实限定了指针指向的值为constnum指向了一个int类型的const值。如果const限定符在*的后面,也就是int * const num,则我们创建的指针本身的值不能改变,但是它指向的值可以改变。

+

更加常见的用法是声明为函数形参的指针。比如void display(const int array[], int num),另外一个更熟悉的例子是字符串函数void strcat(char * restrict string1,const char * restrict string2)。 这使得传进去的数组的值没有被修改,这其实表明了const限定符实际提供了一种保护数据的方法。

+

我们同样可以对全局变量使用const限定符保护数据,因为extern限定符使得程序的任何一个部分都能使用并且改变这个变量,所以会平白无故产生许多危险,而const限定符让变量变成只读变量,这样就可以另程序更加安全。

+

6.3.2 volatile限定符

+

6.3.3 restrict限定符

+

Chapter 7:文件处理

+

7.1 文件和文件类型

+

7.1.1 文件

+

文件其实是硬盘上的一段已经被命名的存储区域,C将文件看成一系列连续的字节,每一段字节都可以被单独读取。

+

7.1.2 文件模式

+

C提供两种文件模式:文本模式和二进制模式。

+
    +
  • 所有文件的内容都以二进制形式存储,但是如果文件最初使用二进制编码的字符表示文本,那么这个文件就是文本文件,其中包含文本内容。如果文件中的二进制值表示机器语言代码或者数值数据或者图片以及音乐编码,那么这个文件就是二进制文件,其中包含二进制内容。
  • +
  • C提供了两种访问文件的途径:文本模式和二进制模式。在二进制模式之中,程序可以访问文件的每一个字节,而在文本模式之中,程序看见的内容和文件实际的内容不同,换行符会进行不同样式的映射转换。
  • +
+

7.2 基本的文件处理

+

7.2.1 标准文件和标准I/O

+

C程序会自动打开三个文件:标准输入、标准输出和标准错误输出。通常时候下,标准输入是普通的输入设备,一般是键盘;标准输出和标准错误输出都是系统的普通输出设备,一般是显示屏。函数getchar()、函数printf()和函数puts()都使用的是标准输出。标准错误输出提供了一个逻辑上不同的地方来显示错误输出,如果我们将输出发送给文件,那么发送到标准错误输出的内容仍然会被发送到屏幕上。

+

7.2.2 基本文件处理

+
    +
  • [[noreturn]] void exit(int exit_code)函数
  • +
+

exit()函数关闭所有打开的文件并且结束程序,正如函数声明处所说

+
    +
  • File *fopen(const char *restrict filename, const char *restrict mode)函数
  • +
+

fopen()函数打开一个文件,其文件名由传入函数的第一个参数标识,返回文件指针。其需要的第二个参数是一个字符串,指定了待打开文件的模式。

+

我们常见的打开文件模式有下面这些:

+
    +
  • "r" 以只读模式打开文件;
  • +
  • "w" 以写模式打开文件,并且将现有文件的长度截为 0,如果文件不存在,则创建一个新文件;
  • +
  • "a" 以写模式打开文件,在现有文件结尾添加内容,若文件不存在,则创建一个新文件;
  • +
  • "r+" 以更新模式打开文件,亦即可以读写文件。
  • +
+

如果打开文件失败,且不创建新文件,返回一个空指针

+

值得注意的是,文件指针并不指向任何实际文件,只是指向一个包含文件信息的数据对象(换句话说是一个结构)其中包含了操作文件所用函数所需要的缓冲区信息。

+
    +
  • int fclose(FILE *stream)函数
  • +
+

fclose()函数关闭由stream给出的文件流,无论关闭是否成功,stream均与这个文件无关。The behavior is undefined if the value of the pointer stream is used after fclose returns.

+

如果关闭成功,fclose()函数返回0,反之返回EOF

+
    +
  • int fprintf(FILE *restrict stream, const char *restrict format, ...)函数
  • +
+

fprintf()函数和printf()函数基本相同,只不过输出流从默认的stdout变成了需要自行给出的stream,亦即函数接受的第一个参数表示需要输出的位置。

+
    +
  • int fscanf(FILE *restrict stream,const char *restrict format, ...)函数
  • +
+

这个函数和scanf()函数大差不差,只不过接受的第一个参数需要是待读取文件的文件指针。

+
    +
  • char *strerror(int errnum)函数
  • +
+

返回一个指针,指向错误代码errnum代表的文字描述。errnum一般需要从变量errno中取得。

+
    +
  • long ftell(FILE *stream)函数
  • +
+

ftell()函数返回一个long类型的值,为stream的位置标识符的当前值,亦即。如果出现错误,ftell()函数将会返回-1,全局变量errno被设置为一个正值,我们可以使用errno变量来查看错误代码。比如:

+
if(fseek(fp, 0L, SEEK_END) == -1)
+{
+    fprintf(stderr,"ERROR:%s\n",strerror(errno));
+    fclose(fp);
+    return 1;
+}
+
+
    +
  • int fseek(FILE *stream, long offset, int origin)函数
  • +
+

fseek()函数将文件看做是数组,将位置标识符stream移动到目标位置。函数的第三个参数是模式,这个参数确定起始点。stdio.h 头文件内有三个表示模式的文件常量:SEEK_SET 表示文件开始处;SEEK_CUR 表示当前位置;SEEK_END 表示文件末尾。第二个参数是相对于origin的偏移量,以字节为单位,可以为正值(前移)、负值(后移)或者0(保持不动)。

+

如果一切正常,fseek()返回0,若出现错误(比如试图移动的距离超出文件范围了),返回值为-1

+

ftell()函数在文本模式和在二进制模式的工作方式不同,ANSI C规定,ftell()函数的返回值可以当做fseek()函数的第二个参数。对于MS-DOS,ftell()返回的值将\r\n当做一个字节计数。

+
    +
  • +

    函数

    +
  • +
  • +

    函数

    +
  • +
  • +

    函数

    +
  • +
  • +

    size_t fread(void *restrict buffer, size_t size, size_t count, FILE * resrict stream)函数

    +
  • +
+

fread()函数接受的参数和fwrite()相同。在fread()函数之中,buffer是待读取文件数据在内存之中的地址,stream指定要读取的文件,该函数可以用于读取文件之中的数据,size代表着待读取数据每个元素的大小,count代表待读取项的项数。函数返回成功读取项的项数,一般是count,如果出现错误或者读到EOF,返回的值就会比count小。

+

值得一提的是:The file position indicator for the stream is advanced by the number of characters read.

+
    +
  • size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream)函数
  • +
+

fwrite()函数将缓冲数组buffer里面的count个元素写入到流stream之中。函数将需要写入的数据重新编译为unsigned char类型的数组,通过重复调用fptc()函数将其写入stream之中。和fread()函数相同,The file position indicator for the stream is advanced by the number of characters read. + 在实际使用fread()函数和fwrite()函数读写文件之中的数据时,文件位置指示符不断前进,这使得我们不会重复读取数据,亦即可以实现这样的操作,一个循环就能实现文件从头读到尾的操作:

+
 while(fread(&buffer, sizeof(int16_t), 1, input))
+{
+    buffer *= factor;
+    fwrite(&buffer, sizeof(int16_t), 1, output);
+}
+
+

7.3 流简介

+

在C中,我们处理的是流是一系列连续的字节,不同属性和不同种类的输入由属性更加统一的流来表示。流告诉我们,我们可以利用和处理文件相同的方式来处理键盘输入。打开文件的过程就是把流与文件相关联,读写都通过流来完成。

+

在标准头文件stdio.h之中,定义了三个文本流stdin stdout stderr

+

Chapter 8:结构和其他数据形式

+

8.1 结构

+

8.1.1 结构的定义与基本属性

+

结构的声明描述了一个结构的组织布局:

+
struct book{
+    int index;
+    int val;
+};
+
+

结构体struct book描述了由两个整数类型组成的一个结构体,后续程序中可以利用模板struct book来声明具有相同数据组织结构的结构变量。

+

一般使用的结构初始化方式有三种,除了对于每一个结构成员进行值初始化之外,可以直接进行列表初始化和利用初始化器初始化:

+
struct book bk1 = {231, 1219};
+struct book bk2 = {.val = 2023, .index = 1, 23};
+
+

指向结构的指针具有指针的优点。指向结构的指针比结构本身更加容易操控、在函数中执行更有效率,并且有可能数据表示数据的结构中包含指向其他结构的指针。结构和数组不同,结构名代表的是这个数据集合,而不是结构变量的地址。

+

结构允许嵌套,也允许使用匿名结构,还允许定义结构数组,但是结构中的的匿名结构就很恶心。

+

在两个结构类型相同的情况下,我们允许将一个结构赋值给另外一个结构,这是将每个成员的值都赋给另外一个结构的相应成员。

+

结构不仅可以作为参数传递,也可以作为返回值返回。与传递结构参数相比,传递结构指针执行起来很快,并且在不同版本的C上都可以执行;缺点是不能保护数据(const限定符就可以解决了)。将结构作为参数传递的优点是,函数处理的是原始数据的副本,可以保护数据,但是需要拷贝副本,浪费了时间和内存。

+

8.1.2 结构中的字符数组和字符指针

+

我们可以在结构之中使用以下两种方式存储字符串:

+
#define LEN 20
+struct names{
+    char first[LEN];
+    char last[LEN];
+}
+
+struct names1{
+    char *first1;
+    char *last1;
+}
+
+

如果仅仅是声明数组并且随即初始化,那么两种声明方式是没有区别的。但是如果使用类似于scanf("%s",&names1.first1);的方式,第二种声明方式就会出现危险。因为程序并未给first1分配存储空间,它对应的是存储在静态存储区的字符串字面量,换言之,结构体names1里存储的只是两个字符串的指针,如果仍要实行该操作,因为scanf()函数将字符串放在names1.first1对应的地址上,但是由于这是没有经过初始化的变量,地址可以是任何值,因此程序会将字符串放在任何地方。简而言之,结构变量中的指针应该只是用来程序中管理那些已经分配或者分配在别的地方的字符串。

+

如果使用malloc()函数来分配内存并且用指针来存储地址,这样处理字符串就会比较合理,当然需要记得使用free()释放相关内存。

+

8.1.3 复合字面量和结构

+

复合字面量可以用于数组或者结构,如果活只需要一个临时结构值,符合字面量很好用,比如我们可以使用复合字面量创建一个结构赋给另外一个结构或者作为函数的参数。语法是将类型名放在圆括号之中,后面紧跟花括号括起来的初始化列表。比如(某些代码进行了适当的精简):

+
struct book{
+    char title[10];
+    char auther[10];
+    double value;
+}
+struct book POMA = (struct book){
+    "thistitle",
+    "thisman",
+    11.11
+};
+int cal(struct book tmp);
+cal((struct book){"thattitle","thatman",22.2});
+
+

8.1.4 伸缩型数组成员

+

利用伸缩型数组成员这一特性声明的结构,起最后一个数组成员具有一些特性:其一,该数组不会立刻存在;其二,使用这个伸缩型数组成员可以编写合适的代码,就好像这个数组确实存在并且具有所需数目的元素一样。但是对这个数组有这以下要求:首先,这个数组成员必须是结构的最后一个成员;其次,结构中至少拥有一个成员;最后,伸缩数组的声明类似于普通数组,只不过其中括号是空的。另外,声明一个具有伸缩型数组成员的结构时,我们不能使用这个数组干任何事,必须先给它分配内存空间后才能以指针形式使用它。比如:

+
struct flex{
+    size_t count;
+    double average;
+    double array[];
+}
+struct flex *ptr;
+ptr = malloc(sizeof(struct flex) + n*sizeof(double));
+ptr->count = n;
+
+

使用伸缩型数组成员的结构具有一下要求:第一,我们不能用结构进行赋值或者拷贝,比如*ptr1 = *ptr2,不然这样只能拷贝非伸缩型数组成员外的所有成员,如果非要拷贝,应该使用mencpy()函数;第二,不要按值方式将这种结构传递给函数,应该传递指针;第三,不应该将使用伸缩型数组成员的结构作为数组成员或者另外一个结构的成员。

+

8.2 联合

+

联合(union)是一种数据类型,可以在同一个内存空间之中存储不同的数据类型(但是不是同时)。其典型用法是,设计一种表以存储既无规律,实现也不知道顺序的混合类型。使用联合类型的数组,每个联合都大小相等,每个联合可以存储各种数据类型。

+
union hold{
+    int digit;
+    double bigfl;
+    char letter;
+};
+
+

以上声明的联合可以存储一个int类型、一个double类型或者一个char类型的值。联合只能存储一个值,其占用的内存空间是占用内存最大类型所占用的内存。使用联合的方法如下:

+
union hold fix;
+fix.digit = 1;          //把1存储在fix,占用两个字节
+fix.bigfl = 1.1;        //把先前存储的内容抹去,把1.1存储在fix,占用八个字节
+
+

8.3 枚举

+

可以使用枚举类型(enumerated type)声明符号名称表示整型常量。使用关键字enum可以声明枚举类型并且指定其可以具有的值(事实上,enum常量就是int类型,所有可以使用int类型的地方都可以使用枚举类型)。enum类型的用法如下:

+
enum spectrum {red, orange, yellow, green = 100, blue, violet};
+enum spectrum color = red;
+printf("%d, %d, %d, %d", red, orange, blue, violet);    //输出为0, 1, 101, 102
+
+

在使用完枚举声明后,red等就成了具有名称的常量。第二个语句声明了枚举变量color,并且拿red的值初始化color。这种不连续的枚举直接按照整数进行处理,无法按照想象中直接遍历枚举内的元素。

+

8.4 typedef

+

利用typedef可以为某一类型自定义名称。我们之前已经利用define进行了自定义名称,但是define只是单纯的文本替换,并且相比于typedef要更为死板很多。比如:

+
#define STRING char*
+typedef char* String;
+STRING str1, str2;              //其实是char *str1, str2;只创建了一个字符串和一个字符
+String strr1, strr2;            //其实是char *strr1, *strr2;创建了两个字符串
+
+

这就明白为什么define只不过是单纯的文本替换了。同时,利用typedef为结构变量命名的时候,可以省略掉这个结构的标签,比如:

+
typedef struct{
+    int data; int index;
+}pair;
+
+

其实这是为一个匿名结构命名。typedef更好的一点是可以为更加复杂的类型命名:比如typedef char (* FRPTC()) [5];FRPTC声明为一个函数类型,这个函数返回一个指针,指针指向内含五个char元素的数组。

+

8.5 函数和指针

+

Chapter 9:位操作

+

9.1 进制、位和字节

+

9.1.1 计数

+

计算机基于二进制,通过关闭和打开状态的组合来表示信息。C语言利用字节表示存储系统字符集所需的大小,通常一字节(byte)包含八(bit),计算机界用八位组(octet)特指八位字节。可以从左到右给这八位编码为7 ~0,编号为7的位被称为高阶位,编号为0的被称为低阶位。

+

如何利用二进制表示有符号整数取决于硬件,最通用的做法是利用补码。二进制补码利用一字节的第一位(高阶位)表示数值的正负,如果高阶位是0,则此时表示非负数,其值与正常情况相同;如果高阶位为1,则此时表示负数,但是这时负值的量是九位组合100000000(256的位组合)减去这个负数的位组合。比如某负数为10011010,其表示-12211111111则表示-1。这样,我们就可以用一字节来表示从-128~127的所有数字。

+

浮点数分两部分存储:二进制小数和二进制指数。计算机中存储浮点数的时候,要留出若干位存储二进制小数,剩下的位存储指数。二进制小数用有限多个\(1/2\)的幂的和近似表示数字(事实上,二进制小数只能精确表示有限多个\(1/2\)的幂的和)。一般而言,数字的实际值是由二进制小数乘以\(2\)的指定次幂组成。

+

9.1.2 其他进制数

+

计算机界常用八进制十六进制计数系统,这些计数系统比十进制更加接近计算机的二进制系统。

+
    +
  • 八进制(octal)基于八的幂,每个八进制位对应三个二进制位。我们在数字前加上一个0来特别表示一个数是八进制。
  • +
  • 十六进制(hexadecimal)基于十六的幂,每个十六进制位对应四个二进制位。我们在数字前加上0x来特别表示一个数是十六进制。十六进制是表示字节的非常好的方式。
  • +
+

9.2 按位运算符

+

9.2.1 按位逻辑运算符

+
    +
  • +

    按位取反(反码):~

    +
  • +
  • +

    按位与:&

    +
  • +
  • +

    按位或:|

    +
  • +
  • +

    按位异或:^

    +
  • +
+

9.2.2 移位运算符

+
    +
  • 左移:<<
  • +
  • 右移:>>
  • +
+

9.2.3 应用

+
    +
  • 掩码
  • +
  • 打开位
  • +
  • 关闭位
  • +
  • 切换位
  • +
  • 检查位的值
  • +
  • 快速乘除运算
  • +
+

9.3 位字段

+

9.4 对齐特性

+

没看懂,先不写。

+

Chapter 10 C预处理器和C库

+

Chapter 11

+

C常用库

+

assert

+

stdio

+

int sprintf(char *buffer, const char *format,...)函数

+

向字符串buffer里写入,相当于多了一个转换格式/读写的工具函数。

+

int fprintf(FILE *stream, const char *format,...)函数

+

sscanf()函数

+

fscanf()函数

+

向输出流stream中写入。

+

stdlib

+

x.2.x 随机数

+
    +
  • void srand(unsigned int seed)
  • +
+

srand()函数为伪随机数生成器rand()播种,正常的用法是:srand((unsigned int) time(NULL))

+

这段代码利用当前时间为伪随机数生成器rand(0)提供种子,这样子就可以得到了近似于真随机的随机数。

+
    +
  • int rand(void)
  • +
+

伪随机数生成器rand()生成一个介于0RAND_MAX的随机数。如果没有srand()的播种,rand()函数就会默认生成种子为1的随机数。每次调用rand()函数,我们得到的都是上次生成的随机数的下一个数

+

值得注意的是,在调用函数rand()之前的时候,伪随机数生成器只应该被播种一次。

+
+

Generally speaking, the pseudo-random number generator should only be seeded once, before any calls to rand(), and the start of the program. It should not be repeatedly seeded, or reseeded every time you wish to generate a new batch of pseudo-random numbers.

+
+

更重要的是,当rand()接受相同的种子的时候,他会生成相同的随机数数列。

+

time

+

x.3.1 变量类型

+
    +
  • time_t 这是一个适合储存日历时间的长整型(long int)变量,表示着从POSIX time (1970年1月1日00:00)开始的总秒数。
  • +
+

x.3.2 函数

+
    +
  • time_t time(time_t *seconds)
  • +
+

time()函数将当前日历时间作为一个time_t类型的变量返回,并且将这个变量存储在输入的指针seconds中(前提是这个指针不为空指针)。

+

由于time_t类型其实是一个long int转换成int(或者unsigned int)的时候还是需要强制转换说明的2

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Language/Java/index.html b/Computer Science/Programming Language/Java/index.html new file mode 100644 index 0000000..fbe2600 --- /dev/null +++ b/Computer Science/Programming Language/Java/index.html @@ -0,0 +1,1587 @@ + + + + + + + + + + + + + + + + + + + + + + + Java - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Java

+
+

Abstract

+

这是我学习Java语言的笔记,动机很简单,我想听的CS61BAlgorithms课程都是基于Java的,所以我需要学习Java。

+

参考书籍:

+
    +
  • 《Java核心技术》 卷I
  • +
  • 《On Java》 基础卷
  • +
  • 《Algorithms》
  • +
+
+
+

Java is a high-level, class-based, object-oriented programming language.

+
+

Basic

+

1.1 在写代码之前

+

Java的类库源文件在JDK中以压缩文件lib/src.zip的形式发布,其包括了所有公共类库的源代码,解压缩这个文件就可以得到源代码。

+

使用命令行工具,我们可以编译和运行Java程序。编译Java程序使用javac命令,javac程序是一个Java编译器,将我们的代码编译成字节码文件,也就是类文件(扩展名为.class);再使用java命令启动Java虚拟机,执行编译器编译到类文件的字节码。

+

编译器需要文件名,需要提供扩展名.java,而虚拟机需要类名,不需要提供扩展名。

+

1.2 基本程序结构

+

调用方法的通用语法是object.method(parameters),其中object是一个对象,method是对象的一个方法,parameters是方法的参数。

+

对于这段最简单的代码:

+
public class FirstSample{
+    public static void main(String[] args){
+        System.out.println("We will not use 'Hello, World!'");
+    }
+}
+
+

关键词public被称为访问修饰符/Access modifier,决定了控制程序其他部分对这部分代码的访问级别。class表示Java程序中的全部内容都包含在类中,类是Java应用的构建模块。一个源文件只能有一个公共类,但是可以有任意数量的非公共类,源文件的文件名必须和公共类的类名相同,并且用.java作为扩展名。

+

在执行已经编译的程序的时候,虚拟机总是从指定类的main方法的代码开始执行,所以类的源代码中必须包含一个main方法,且main方法必须声明为public,当然直接声明全套public static也是极好的。方法其实就是函数的另外一种说法,我们也可以自行定义方法并且添加到类中。

+

1.3 对象与类

+

Java是一种纯粹的面对对象的语言,面对对象的程序是由对象组成的,每个对象包括对用户公开的特定功能与隐藏的实现。在面对对象程序设计中,数据是第一位的,之后我们才考虑操作数据的大小。

+

1.3.1 类

+

类/Class指定了如何构造对象,通过一个类构造/Construct对象的过程称为创建这个类的一个实例/Instance封装/Encapsulation是面对对象程序设计的一个重要概念,是指将数据与行为组合在一个包中,并对对象的使用者隐藏了具体的实现细节。对象中的数据称为实例字段/Instance field,操作数据的过程称为方法/Method,作为一个类的实例,一个对象有一组特定的实例字段值,这些值的集合就是这个对象的当前状态/State。只要在对象上调用一个方法,它的状态就有可能发生改变。

+

封装的关键在于,不能让其他类的方法直接访问这个类的实例字段。我们还可以通过扩展其他的类来构建新类,这个新类具有被扩展的类的所有属性与方法,这种通过扩展一个类来得到另外一个类的过程叫做继承/Inheritance

+

使用面对对象编程之前,必须清楚对象的三个主要特性:

+
    +
  • 对象的行为/Behavior:可以对对象施加哪些操作,或者应用哪些方法?
  • +
  • 对象的状态/State:调用那些方法的时候,对象将会如何响应?
  • +
  • 对象的标识/Identity:如何区分可能具有相同行为和状态的不同对象?
  • +
+

对象的标识是两两不同的,每个对象都有一个唯一的标识。

+

类之间的最常见的关系有:依赖/uses-a聚合/has-a继承/is-a

+

依赖/Dependence是最一般且最明显的关系,比如Order类使用了Account类,因为Order类需要访问Account类来获取信息。应该尽可能减少相互依赖的类,或者说减少类之间的耦合/Coupling。因为耦合度越低,越不容易在修改一个类的时候影响其他类。

+

聚合/Aggregation表明了一个类包含另外一个类的对象。

+

继承/Inheritance表示了一个更特殊的类与一个更一般的类之间的关系,在特殊化的类里边定义了更多的特殊方法与额外功能。

+

1.3.2 预定义类

+

在Java中,没有类就不能做任何事情,但是并不是所有类都表现出面对对象的典型特征,比如Math类,它只包括了一些方法,甚至没有实例字段。下面我们将以Date类与LocalDate类为例说明类的使用。

+

在Java中,我们需要使用构造器/构造函数/Constructor来构造新的实例,构造器是一种特殊的方法,用来构造并且初始化对象,并且构造器总是与类同名。我们看几个例子:

+
    +
  • new Date();:使用new操作符,我们就可以构造一个Date对象,并且将这个对象初始化为当前的日期与时间。
  • +
  • String s = new Date().toString();我们可以对这个对象应用一个方法,将这个日期转换成一个字符串。
  • +
  • System.out.println(new Date());我们也可以将这个对象传递给一个方法。
  • +
  • Date rightNow = new Date();我们定义了一个对象那个变量rightNow,其可以引用Date类型的变量,并且将新构造的对象存储在对象变量rightNow中。
  • +
+

对于对象变量而言,他们并不包含一个对象,只是引用一个对象,我们可以显式地将对象变量初始化为null,这就表明这个变量目前没有引用任何对象,对一个赋值为null的变量,我们不允许应用任何方法。

+

尽管我们使用了引用这个词,但是Java中的对象变量更像是C++中的对象指针,并且Java的语法甚至和C++的是一样的。所有的Java对象都存储在堆之中,当一个对象包含另外一个对象变量的时候,其实只是包含了另外一个堆对象的指针。

+

上面提到的Date类的实例有一个状态,就是一个特定的时间点,时间是距离另外一个固定的时间点的毫秒数,这个时间点就是所谓的纪元/Epoch,在Java中,纪元是UTC时间1970年1月1日00:00:00。

+
    +
  • LocalDate.now();
  • +
  • LocalDate newYearsEve = LocalDate.of(1999, 12, 31);
  • +
  • int year = newYearsEve.getYear();/int month = newYearsEve.getMonthValue();/int day = newYearsEve.getDayOfMonth();
  • +
  • LocalDate aThousandDaysLater = newYearsEve.plusDays(1000);访问器方法/Accessor method,与更改器方法/Mutator method
  • +
+

1.3.3 自定义类

+

我们不仅仅需要学会使用常用的类与配套的方法,还需要学会编写类。我们经常写的一种类叫做主力类/Workhorse class,这种类没有main方法,但是有自己的实例字段和实力方法,是构建一个完整程序的众多部分之一。

+

最简单的类形式为:

+
type class ClassName{
+    field;          // 实例字段
+    constructor;    // 构造器
+    method;         // 方法
+}
+
+

实例字段可以是基本类型,也可以是对象。我们一般需要将实例字段声明为private,这确保只有这个类的方法可以访问这种字段,这就是封装的一部分。而方法可以声明为private或者publicpublic方法可以被任何类的任何方法调用。private方法只可以被本类的其他方法调用。

+

我们先看一个自定义类的例子:

+
public class Employee{
+    private String name;
+    private double salary;
+    private LocalDate hireDay;
+
+    public Employee(String n, double s, int year, int month, int day){
+        name = n;
+        salary = s;
+        hireDay = LocalDate.of(year, month, day);
+    } // constructor
+
+    public String getName(){
+        return name;
+    } // more methods
+}
+
+

构造器开始看,构造器与类同名。构造Employee类的对象时,构造器会运行,将实例字段初始化为所希望的初始状态。构造器没有返回值,可以有参数,也可以没有参数。

+

在声明对象变量的时候,我们可以用var关键字声明,Java会根据变量的初始值推导出其类型。比如,对上面的类,我们只需要声明var harry = new Employee("Harry Hacker", 50000, 1989, 10, 1);就可以了。

+

在使用构造器初始化一个对象的时候,有可能将某个实例字段初始化为null,但又有可能对这个字段应用某个方法,一个“宽容”的解决方法就是将null参数转换成一个适当的非null值,Objects类给予了一种便利方法:Objects.requireNonNullElse(T, defalt obj),如果输入的对象Tnull,那么就将返回默认值default obj。同样地,其实还提供了一种“严格”的方法Objects.requireNonNull(T, string message),如果输入的对象Tnull,那么就将抛出一个NullPointerException异常并且显示出问题的描述。

+

方法会操作对象并且访问其实例字段,方法一般会有两个参数,第一个参数是隐式参数/Implicit parameter,出现在方法名之前;第二个参数是显式参数/Explicit parameter,出现在方法名之后的括号里面。在方法中,我们可以使用this关键字来引用隐式参数。

+

封装是极其有必要的,我们来看一些比较特殊的方法,这些方法只访问并且返回实例字段的值,因此被称为字段访问器/Field accessor。相比于将实例字段声明为public,编写单独的访问器会更加安全:外界的代码不能修改这些实例字段,并且如果这些实例字段出了问题,我们直接调试字段访问器就可以了,如果是public的话,我们就需要在所有的代码中寻找问题。

+

有时,想要获取或者改变一个实例字段的值,我们需要提供下面三项内容:

+
    +
  • 一个私有的实例字段;
  • +
  • 一个公共的字段访问器方法;
  • +
  • 一个公共的字段更改器方法。
  • +
+

这样的处理非常好,首先可以改变内部实现而不改变该类方法之外的任何其他代码;其次,更改器方法可以完成错误检查,这就非常好了!

+

另外,不要编写返回可变对象引用的访问器方法,这样我们好好的封装就毁了!如果硬要返回一个可变对象的引用的话,首先应该对它进行克隆/Clone,克隆是指存放在另外一个新位置上的对象副本,使用类重的clone方法可以完成这个操作。

+

访问权限是一件非常重要的事情。方法可以访问所属类的对象的任何数据,当然包括私有数据,但是不能访问其他对象的私有数据

+

尽管大部分方法都是公共的,但是某些情况下,私有方法可能会更加有用,比如我们希望将一个计算方法分解成若干个独立的辅助方法,但是这些方法不应该作为公共接口,这是因为其与当前实现关系非常紧密,或者需要一个特殊的协议或者调用次序,这些方法就应该实现为私有方法。实现私有方法很简单,只需要将关键字public改为private就好了。

+

如果一个方法是私有的,并且类的作者确信这个方法不会在别处使用,这个方法就可以被简单地剔除,但是如果方法是公共的,就不能简单地删除一个方法了,因为还有可能会有其余的代码依赖于这个方法。

+

我们可以将一些变量、类与方法设置为final。当我们定义一个类时使用了final修饰,这个类就不能被继承,这个类的成员变量可以根据需要设为final,但是类中的所有成员方法都会被设为final。如果定义了一个方法为final,这个方法就被“锁定”了,无法被子类的 方法重写,对方法定义为final一般常见于认为这个方法已经足够完整,不需要改变了。修饰变量是final用的最多的地方,final变量必须显式指定初始值,并且一旦被赋值,就不能给被重新赋值;如果final的是一个基本变量,这个变量就不能改动了,如果是一个引用变量,那么对其初始化之后就不能再指向其他变量

+

比如private final StringBuilder evaluations = new StringBuilder();,这里的evaluations就不能指向别的对象了,但是这个对象可以修改,比如evaluations.append(LocalDate.now() + ":Yes!")final修饰符对于类型为基本类型或者不可变类的字段尤其有用,并且final修饰符一般与static修饰符一起使用。

+

1.3.4 静态字段与静态方法

+

我们发现,先前的很多方法都标记了static修饰符,下面

+

1.4 数据类型

+

数据类型就是一组数据与对其能进行的操作的集合。

+

Java是典型的C类语言,声明变量的方法与C极为相似,但是在Java中,变量名的标识符的组成得到了扩充:字母、数字、货币符号与“标点链接符”组成变量名,首字母不能为数字。特别地,字母、数字与货币符号的范围更大,字母可以是一种语言表示中的任何Unicode字符,数字可以是09表示一位数字的任何Unicode字符。

+

1.4.1 基本类型

+

Java最基本的类型有下面几种,六种数字类型,一种字符类型,一种布尔型:

+
    +
  • +

    整型

    +
  • +
  • +

    双精度实数类型,与其对应的算数运算符(double)。

    +

    我们使用double类型来表示双精度实数,使用64位,值域非常之大。

    +
  • +
  • +

    字符型charchar使用UTF-16方案进行编码,以前原本用于表示单个字符,但是现在情况变化了,有的Unicode字符需要两个char值。char类型的字面量要用单引号括起来,也可以表示为十六进制的值,比如\u0041就是A

    +

    在Unicode编码之前,已经有许多编码标准了,我们最熟悉的就是美国的ASCII编码。标准不统一会出现下面两个问题:对一个特定的代码值,在不同的机制中对应不同的字母;大字符集的语言的编码长度会有不同,有的是单字节编码,有的就使用双字节或者多字节编码。

    +

    Java的字符型使用的16位编码在当时设计时的确是很好的改进,但是现在的Unicode字符已经超过65536个,这就尴尬住了。所以一个实用的建议就是不要在程序之中使用char类型,除非要处理UTF-16代码单元,否则就使用String类型。

    +

    还是简单介绍一下Unicode编码吧:码点/Code point是指与一个编码表中某个字符对应的代码值,Unicode中的码点使用十六进制书写,并且在前面加上一个U+U+0041就是A的码点。Unicode中的码点可以分为17个代码平面/Code plane。第一个代码平面被称为基本多语言平面/Basic multilingual plane,其包含了从U+0000U+FFFF的“经典”Unicode编码,其余的16个代码平面从U+10000U+10FFFF,包含了各种辅助字符/Supplementary character,这些平面包含了一些不常用的字符,比如一些古代文字、表意文字等等。

    +

    UTF-16使用不同长度的代码表示所有Unicode码点,在基本多语言平面之中,每个字符使用16位表示,被称为代码单元/Code unit,辅助字符使用一对连续的代码单元表示,这种编码对使用基本多语言平面中未采用的2048个值范围(称为替代区域,U+D800U+DBFF用于第一个代码单元,U+DC00U+DFFF用于第二个代码单元)。而Java中的char类型描述就采用了UTF-16编码的一个代码单元。

    +
  • +
+

1.4.2 运算符

+

1.5 控制语句

+

1.6 字符串

+

1.7 输入输出

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Language/Python/index.html b/Computer Science/Programming Language/Python/index.html new file mode 100644 index 0000000..d487c00 --- /dev/null +++ b/Computer Science/Programming Language/Python/index.html @@ -0,0 +1,2335 @@ + + + + + + + + + + + + + + + + + + + + + + + Python - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Python Saves The World

+

Basic Note

+

变量的命名

+

变量名只能包含字母、数字和下划线 “_”,变量名的第一个字符只能是字母或者下划线,变量名对大小写敏感,且不能将关键字 (亦即保留字) 作为变量名。

+

数据类型

+

Python中的变量不需要声明数据类型,每个变量在使用之前必须赋值,变量在赋值之后才会被创建。我们在创建变量的时候不需要考虑变量的类型——这和C不同——变量就是变量,没有类型,而我们所说的“类型”只是变量所指的内存中对象的类型,因为不同的对象 (比如字符串和整数) 需要以不同的方式存储。并且我们可以为多个变量同时赋值,也可以为多个对象指定多个变量。比如下面的例子:

+
counter = 100          # 整型变量
+miles   = 1000.0       # 浮点型变量
+name    = "runoob"     # 字符串
+
+a = b = c = 1          # 为多个变量同时赋值
+a, b, c = 1, 2, "Hi"   # 为多个对象指定多个变量
+
+

Python内置的type()函数可以用来查询变量所指的对象类型,并且可以使用isinstance()来判断:

+
a, b, c, d =20, 5.5, True, 4+3j
+print(type(a), type(b), type(c), type(d))
+>>> <class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
+print(isinstance(a, int))
+>>> True
+
+

type()isinstance()的区别在于:

+
    +
  • type()不会认为子类是一种父类类型;
  • +
  • isinstance()会认为子类是一种父类类型。
  • +
+

字符串 (string)

+

对字符串的操作

+

字符串就是一系列字符,由引号 (可以是单引号或者双引号) 确定,其列表有两种索引方式:从左到右默认从0开始;或者从右向左从-1开始。对于字符串的某些处理和C类似,比如我们可以实现以下操作:

+
str = "Hello"
+print(str[0])               #Output:H
+print(str[2:4])             #Output:ll
+print(str * 2)              #Output:HelloHello
+print(str + " " + "world")  #Output:Hello world
+print(str[0:4:2])           #Output:Hl
+
+

我们可以发现,字符串的某些处理其实就是对列表的处理。但是值得注意的是,Python没有单独的字符类型,一个字符就是长度为1的字符串,并且Python的字符串不能被改变。

+

在Python中,我们可以使用方法进行对数据的操作,某些方法会改变数据内容 (比如reverse()),某些则不会 (比如下面这些)。对于字符串,利用lower()upper()title()strip()lstrip()rstrip(),我们可以去除字符串两侧的空格,并且调整字符的大小写。比如:

+
name = "hEllo "
+print(name.title())         #Output:Hello 
+print(name.upper())         #Output:HELLO 
+print(name.lower(),end="")  #Output:hello  (后边没有换行)
+print(name.rstrip(),end="@")#Output:hEllo@ 
+
+

在Python中,空白泛指所有非打印字符,比如空格、列表和换行符。print()在打印结束之后会自动换行,但是如果在print()函数之后参加end=""参数,我们就可以实现不换行效果,事实上Python里end参数的默认值为"\n",表明在打印的字符串的末尾自动添加换行符,来设定特定符号,比如上面代码的最后一行将字符串的末尾自动添加了一个@

+

对字符串的比较

+

数字 (Number)

+

类型

+

Python支持intfloatboolcomplex四种类型。整数类型只有一种int,表示为长整型。

+

运算

+

求模运算符%、四则运算符+ - * /与取余运算符%均和C语言中的相同,只是默认情况下的除法/的结果是一个浮点数,而使用运算符//就可以得到一个整数。此外,运算符**表示乘方。

+

类型转换

+

以下函数均将接受的参数进行转化并返回。

+

str()函数

+

int()函数将字符串表示的整形数值转化成整型数字。

+

float()函数将字符串表示的浮点数转化成浮点数。

+

列表 (List)

+

列表由一系列按照特定顺序排列的元素组成,我们用方括号表示列表,并且用逗号分隔其中的元素。列表中的元素可以不相同,甚至可以包含列表 (也就是嵌套)。列表的索引和字符串的索引相同,从0开始;或者从尾部开始,最后一个元素的索引为-1,往前一位为-2,以此类推。

+

需要注意的是,sorted()函数和sort()方法 (和排序相关的) 均不能用在字符串和数字混合的列表 (元组和字典) 排序之中。

+

元组 (Tuple)

+

字典 (Dictionary)

+

声明与基本操作

+

字典是一系列键-值对。每一个键都与值相对应,我们可以用键访问对应的值。值可以是任意数据类型,但是键必须是不可变的数据类型,比如数字或字符串。我们允许创建空字典,可以随时添加、修改或者删除字典内的数据。

+
dictionary1 = dict()
+dictionary1['first'] = "1st"    #添加键-值对
+dictionary1['first'] = "111"    #修改值
+print(dictionary['first'])      #访问值
+del dictionary1['first']        #删除值的同时删除键-值对
+dictionary1.clear()             #清空词典
+del dictionary1                 #删除词典
+
+

可以发现添加键-值对的语法和修改值的相同。

+

遍历词典

+

如果要遍历字典内的键-值对,我们需要先声明两个变量,使用items()方法,它返回一个键-值对列表,在遍历每一个键值对的过程之中,会将键和值依次存储到两个变量之中。同理keys()方法和values()方法分别返回一个存储着键和值的列表,值得注意的是这些列表的元素顺序和其原本的存储顺序不相同,因为Python只关心键与值的对应关系,而不关心存储顺序。

+
dic1 ={'name': "Hello", 'year': 18, 'position': 'hang'}
+for key,val in dic1.items():
+    print(key,val)
+for key in dic1.keys:
+    print(key.title())
+for val in dic1.values()
+    print(val.upper())
+
+

嵌套

+

字典列表

+

字典中的列表

+

字典中的字典

+

语句(statement)

+

布尔运算符(boolean operators)

+

Python支持三个布尔运算符:andornot,它们的内容和C中的&&||!相同,优先级也相同:not有最高的优先级 ,and其次,or的优先级最低。同时,布尔运算符还支持短路运算(short circiuting),即如果andor的第一个操作数(也就是operand)一定可以决定表达式的真值,就不会检查后面的表达式,所以True or 1 / 0False and 1 / 0甚至都没问题。

+

需要注意的是,andor都不将返回值限定为True或者False,相反,它们返回最后一个求值的参数(the last evaluated argument),比如字符串s需要在它为空的时候被替换成一个默认值,就可以使用s = s or "Default"来处理。但是not总需要创建一个新的值,所以不管接收到的参数是不是一个布尔值,都返回布尔值。

+

Python将0None''(空字符串)和[](空列表)都规定为False,其余值规定为True。这表明了布尔值的范围其实比纯粹的TrueFalse更加丰富。

+

复合语句(compound statement)

+

语句值由解释器运行的,执行一项操作的语句(A statement is executed by the interpreter to perform an action)。

+

复合语句由一个或者多个子句(clause)组成,每个子句由一个句头(header)和一个句体(suite)组成,组成复合语句的子句头都处于相同的缩进层级。 每个子句头以一个作为唯一标识的关键字开始并以一个冒号结束。 子句体是由一个子句控制的一组语句。 子句体可以是在子句头的冒号之后与其同处一行的一条或者由分号分隔的多条简单语句,或者也可以是在其之后缩进的一行或多行语句。 只有后一种形式的子句体才能包含嵌套的复合语句。简而言之,复合语句大概长这样:

+
<header>:           
+    <statements>        # 两个句头之间夹着的是Suite
+    ...                 # 以上是一个Clause
+<separating header>:
+    <statements>
+    ...
+...
+
+
    +
  • 第一个句头决定了这个复合语句的类型。
  • +
  • 字句的句头控制句体的执行(The header of a clause controls the suite that follows)。
  • +
  • def语句、if语句和while语句都是标准的复合语句。
  • +
  • 执行子句体指的就是按照句体内的表达式顺序执行表达式。
  • +
+

if语句

+

for循环

+

while循环

+

循环的控制

+

利用continuebreak来跳过此次循环或者跳出循环,逻辑和C一样。

+

while循环还可以这样用:根据对列表判断是否非空来控制循环。

+
unconfirmed_users = ["1","2","3"]
+while unconfirmed_users
+    print(unconfirmed_users.pop())
+print(unconfirmed_users)
+
+

这个循环只会在列表unconfirmed_users非空的时候运行,当它变空的时候,就不会继续运行了。

+

assert语句

+

assert语句的基本语法如下:assert_stmt ::= "assert" <expression> ["," <expression>]。当assert后面的<expression>的布尔值是False时,程序会中断运行,并且抛出AssertionError: <expression>,这里的<expression>对应的是方括号里的<expression>。一个例子如下:

+
>>> assert 2 > 3, 'Math is broken'
+# Traceback (most recent call last):
+#    File "<stdin>", line 1, in <module>
+# AssertionError: Math is broken
+
+

return语句

+

A return statement completes the evaluation of call

+

函数

+

函数就是一个带名字的代码块,用于完成具体的工作。关键字def表示开始定义一个函数,向Python指出函数名,并且提供形参。函数定义下所有缩进行构成函数体,被三个引号引起来的部分是称作文档字符串的注释,描述函数是做什么的,Python用其生成有关程序中函数的文档。

+

在定义中括号里出现的变量是形式参数 (Formal Parameter),是函数完成工作需要的信息,在调用函数时传入的是实际参数 (Actual Argument),是调用函数的时候传递给函数的信息,值存储在相应的形式参数之中。

+
def calc(number,times=2):               # Function signature
+    """完成乘方的操作,默认为平方"""
+    ret = 1                             # Function body
+    for cnt in range(0,times):
+        ret *= number
+    return ret
+
+

我们认为赋值操作是一种简单的抽象(abstraction)方式,它将变量的名字与其值联系到了一起;而函数定义是一种更强大的抽象方式,它允许将名字与表达式联系到了一起。函数由函数签名与函数体组成。

+
    +
  • +

    函数签名(function signature)<name>(<formal parameters>)表明了函数的名字与接受的形式参数的数量;

    +
  • +
  • +

    函数体(function body)<expression>决定了使用函数时的计算过程。

    +
  • +
+

def语句的执行过程如下:

+
    +
  • Create a function with signature <name>(<formal parameters>);
  • +
  • Set the body of that function to be everything indented after the first line;
  • +
  • Bind <name> to that function in current frame.
  • +
+

Procedure for calling/applying user-defined functions(version 1):

+
    +
  • Add a local frame, forming a new environment;
  • +
  • Bind the function's formal parameters to is arguments in that frame;
  • +
  • Execute the body of the function in that new environment.
  • +
+

函数的定义域(domain):

+

函数的值域(range):

+

函数可以分为纯函数(pure function)和非纯函数(non-pure function)两类,纯函数指的是没有副作用(side-effect)的函数,反之,非纯函数有副作用,print()函数就是典型的非纯函数,它将内容显示在终端上。如果一个函数体内没有return语句,函数会自动返回Noneprint()就是这样返回的。A side effect isn't a value:it is anything that happens as a consequence of calling a function.

+

有意思的是,在终端中,print()会显示没有引号的文本,但是return会保留引号。下面是一个例子:

+
def what_prints():
+    print('Hello World!')
+    return 'Exiting this function.'
+
+>>> what_prints()
+Hello World!
+'Exiting this function.'
+
+

None

+

None在Python里面表示一种特殊的值:Nothing

+

None其实有着其相应的数据类型:NoneType,所以在进行None + 4的操作的时候,就会出现类型错误:TypeError: unsupported operand type(s) for +: 'NoneType' and 'int',这表明None和一般的数据类型不能相加。

+

用户输入

+

input()函数接受一个参数,即需要向用户显示的提示 (prompt) ,暂停程序运行并将提示输出到屏幕上,等待读取用户输入,在按下回车键之后继续运行,并且将用户的输入作为input()函数的返回值。

+

转义字符

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
max(a,b)输出a和b的最大值
+

Lambda Expressions

+
lambda_expr ::= "lambda" [parameter_list] ":" return_expression
+
+

Lambda expressions (sometimes called lambda forms) are expressions that evaluate to fuctions by specifying two things: the parameters and a return expression. Lambda expressions are used to create anonymous functions. The expression lambda parameters : expression yields a function object, and this unnamed object behaves as a functions object defined with:

+
def <lambda>(parameters):
+    return expression
+
+

While both lambda expressions and def statements create function objects, there are some notable differences. lambda expressions work like other expressions; much like a mathematical expression just evaluates to a number and does not alter the current environment, a lambda expression evaluates to a function without changing the current environment: It does not create or modify any variables.

+

Recursive Functions

+

Definition: A function is called recursive if the body of that function calls itself, either directly or indirectly.

+

Implication: Executing the body of a recursive function may require applying that function again.

+

The anatomy of a recursive function:

+
    +
  • the def statement header is similiar to other functions.
  • +
  • Conditional statements check for base cases.
  • +
  • Base cases are evaluated without recursive calls.
  • +
  • Recursive cases are evaluated with recursive calls.
  • +
+

Object-Oriented Programming

+

Standard Library

+

operator模块

+

opertaor模块包含了一套和Python内置的运算符对应的高效率函数,包含的种类有:对象的比较运算、逻辑运算、数学运算和序列运算。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
---------
operator.add()add(1,2)3
operator.mul()mul(2,3)6
+

CS61A

+

Lab 0

+

Docstring:

+

Lecture 2: Functions

+

An expression describes a computation and evaluates to a value.

+

Evaluation procedure for call expressions:

+
    +
  • Evaluate the operator and then the operand subexpressions (from left to right).
  • +
  • Apply the function that is the value of the operator subexpression to the arguments that are the values of the operand subexpression.
  • +
+

All expressions can use function call notation. (demo)

+

Call expression:

+

Environment diagrams visualize the interpreter's progress.

+

a function's signature has all the information needed to create a local frame.

+

Pure functions: only return values.

+

Non-pure functions: have side effects.

+

print() is a non-pure function because it displays its output depending on the argument passed in , and returning None.

+

Debug

+

Using print() statements

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Programming Language/index.html b/Computer Science/Programming Language/index.html new file mode 100644 index 0000000..387ebe8 --- /dev/null +++ b/Computer Science/Programming Language/index.html @@ -0,0 +1,1116 @@ + + + + + + + + + + + + + + + + + + + + + + + Programming Language - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Programming Language

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/System/Assembly/index.html b/Computer Science/System/Assembly/index.html new file mode 100644 index 0000000..683213b --- /dev/null +++ b/Computer Science/System/Assembly/index.html @@ -0,0 +1,1119 @@ + + + + + + + + + + + + + + + + + + + + + + + Assembly - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Assembly

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/System/CSAPP/index.html b/Computer Science/System/CSAPP/index.html new file mode 100644 index 0000000..7382f14 --- /dev/null +++ b/Computer Science/System/CSAPP/index.html @@ -0,0 +1,1568 @@ + + + + + + + + + + + + + + + + + + + + + + + CSAPP - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

CSAPP

+
+

Abstract

+

这是我对《深入理解计算机系统》一书的读书笔记。

+

参考:

+
    +
  • +

    《深入理解计算机系统》

    +
  • +
  • +

    《Comptuer System: A Programmer's Perspective》

    +
  • +
+
+

Chapter 01 A Tour of Computer Systems

+

1.4.1 Hardware Organization of a System

+

计算机系统的硬件组成包括:总线/BusI/O设备/IO devices主存/Main memory处理器/Processor

+
    +
  • +

    总线是贯穿整个系统的一组电子管道,携带信息字节并负责在各个设备之间传输。总线被设计成传送定长的字节块,被称为字/Word,现代的计算机的字长大多为4个字节/32位或者8个字节/64位。

    +
  • +
  • +

    I/O设备

    +
  • +
  • +

    主存是一个临时存储设备,在处理器执行程序的时候,用来存放程序和程序处理的数据。主存是由一组动态随机存取存储器/Dynamic random access memory/DRAM组成的,在逻辑上看是一个线性的字节数组,每个字节都有唯一的地址,且地址从零开始。

    +
  • +
  • +

    中央处理器单元/Central processing unit简称为处理器,处理器负责解释(或者执行)主存中的指令。处理器的核心是大小为一个字的寄存器/Register,称为程序计数器/Program counter/PC

    +
  • +
+

1.9.1 Amdahl's Law

+

当我们对系统的某个部分加速的时候,其对整个系统性能的影响取决于该部分的重要性和加速程度。特别地,假设系统执行某个应用程序需要的时间为\(T_{old}\),某部分所需执行时间与该时间所用的比例为\(\alpha\),而这部分性能提升的比例为\(k\),改进之后,总的执行时间为

+
\[T_{new}=T_{old}*(1-\alpha)+T_{old}*\alpha/k.\]
+

那么,我们可以的到加速比\(S\)

+
\[S=\frac{T_{old}}{T_{new}}=\frac{1}{(1-\alpha)+\alpha/k}.\]
+

我们同时也考虑极限情况,也就是 \(k\to\infty\) 的情况,此时加速比\(S\)

+
\[S=\frac{1}{1-\alpha}.\]
+

这就是加速比的上界了。

+

总之,Amdahl's Law告诉我们,为了显著提升系统性能,必须提升全系统中相当大的部分的性能

+

1.9.2 Concurrency and parallelism

+

并发(concurrency)和并行(parallelism)是两个不同的概念。并发是一个通用的概念,指一个同时具有多个活动的系统。并行是指使用并发来使一个系统运行得更快。并行可以在计算机系统的多个抽象层次上运用,我们按照系统层次结构中从高到底的顺序重点强调三个层次:

+
    +
  • 线程级并发:使用
  • +
+

Chapter 02 Representing and Manipulating Information

+

2.1 Information Storage

+

2.1.6 Introduction to Boolean Algebra

+

十九世纪中期,布尔通过将逻辑值TRUEFALSE编码为二进制值10,能够设计为一种代数,以研究逻辑推理的基本原则,这种代数叫做布尔代数/Boolean algebra

+

布尔代数有四种基本运算~&|^,分别对应于逻辑运算NOTANDOREXCLUSIVE-OR,我们可以列出简单的真值表如下:

+

alt text

+

接下来,我们将上述四个布尔运算推广到位向量/Bit vectors的运算,所谓位向量就是固定长度\(w\),由01组成的串。所谓的推广也非常简单,就是将上述四个布尔运算应用到位向量的每一位上,得到的结果也是一个位向量。换句话说,就是我们在C语言中学的按位运算。

+

2.2 Integer Representations

+

2.2.1 Unsigned Encodings

+

无符号数的编码就是经典的二进制编码,假设一个无符号整数数据有\(w\)位,我们可以将位向量写作\(\vec{x}\),也就是\([x_{w-1},x_{w-2},\cdots,x_0]\)来表示向量的每一位。我们用一个函数\(B2U_w\)(是Binary to Unsigned的缩写)来表示二进制向无符号整数的转换:

+
\[B2U_w(\vec{x}) = \sum_{i=0}^{w-1}x_i2^i.\]
+

我们很容易可以得知:

+
    +
  • \(w\)位能表示的无符号整数的范围为\([0,2^w-1]\)
  • +
  • 函数\(B2U_w\)是一个双射。\(B2U_w\)将每一个长度为\(w\)的位向量映射为唯一的无符号整数,相对地,每一个在区间\([0,2^w-1]\)内的整数都可以唯一表示为一个长度为\(w\)的位向量。
  • +
+

2.2.2 Two's-Complement Encodings

+

最常见的有符号整数编码是补码/Two's-complement编码。在补码编码中,一个\(w\)位的有符号整数\(\vec{x}\)的值可以表示为:

+
\[B2T_w(\vec{x}) = -x_{w-1}2^{w-1}+\sum_{i=0}^{w-2}x_i2^i.\]
+

最高有效位也称为符号位,其权重为\(-2^{w-1}\),其余位的权重和无符号整数编码一样。同样,我们可以得知:

+
    +
  • \(w\)位能表示的有符号整数的范围为\([-2^{w-1},2^{w-1}-1]\)
  • +
  • 函数\(B2T_w\)是一个双射。
  • +
+

类似的,我们可以定义四进制与十六进制的编码。

+

补码编码有十分有趣的特性:

+
    +
  • 补码的范围是不对称的,负数的范围比整数的范围大1,也就是说编码的最小值\(TMin\)没有与之对应的整数。
  • +
  • 最大的无符号数值刚刚好比最大值的两倍多一点点\(UMax_w=2TMax_w+1\)。补码的负数的位模式在无符号表示中都变成了比原补码整数大的正数。
  • +
+
+

在C库中的limits.h中定义了一些常用的整数的最大值与最小值,用来限制编译器运行的不同整型数据的取值范围,例如INT_MAXINT_MINUINT_MAX等。

+

在C库中的stdint.h中定义了一些固定大小的整数类型,例如int8_tuint8_tint16_tuint16_t等,这些类型很好地提升了程序的可移植性。

+
+

有符号数还有下面两种其他的表示方法:

+
    +
  • 反码/Ones'-complement:除了最高位有效的权是\(-(2^{w-1}-1)\),其余和补码是一样的:
  • +
+
\[B2O_w(\vec{x}) = -x_{w-1}(2^{w-1}-1)+\sum_{i=0}^{w-2}x_i2^i.\]
+
    +
  • 原码/Sign-magnitude:最高位是符号位,用来确定剩下的位应该取正权还是取负权,其余位表示数值的绝对值:
  • +
+
\[B2S_w(\vec{x}) = (-1)^{x_w-1}\cdot\left(\sum_{i=0}^{w-2}x_i2^i\right).\]
+

这两种编码方式都有统一的缺点:对于数字0,有两种完全不同的表示方法,并且这两种编码不能很好地支持算数运算,因而,我们现在开始使用更加方便的补码编码。

+

2.3 Integer Arithmetic

+

2.3.1 Unsigned Addition

+

2.4 Floating Point

+

Chapter 03 Machine-Level Representation of Programs

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/System/System1/index.html b/Computer Science/System/System1/index.html new file mode 100644 index 0000000..b1e855a --- /dev/null +++ b/Computer Science/System/System1/index.html @@ -0,0 +1,1243 @@ + + + + + + + + + + + + + + + + + + + + + + + 计算机系统 I - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

计算机系统 I 笔记

+
+

Abstract

+

这是浙江大学“计算机系统 I”课程的相关笔记,覆盖了数字逻辑与计算机组成的部分内容。

+

参考书籍:

+
    +
  • 《深入理解计算机系统》
  • +
+

同样也可以参考我对《深入理解计算机系统》一书的笔记

+
+

Lecture 1: Introduction

+

Lab 0-1

+

SPICE 仿真

+

反相器有两组/四个引脚,V_PWR和V_GND分别代表电源引脚和接地引脚;

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/System/Verilog/index.html b/Computer Science/System/Verilog/index.html new file mode 100644 index 0000000..9ee5158 --- /dev/null +++ b/Computer Science/System/Verilog/index.html @@ -0,0 +1,1470 @@ + + + + + + + + + + + + + + + + + + + + + + + Verilog - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Verilog

+

Chapter 1 Basic Knowledge

+

1.1 FPGA

+

FPGA/Field Programmable Gate Array/现场可编程门阵列:FPGA器属于专用集成电路/ASIC的一种半定制电路,是可以编程的逻辑列阵,可以按照设计人员的需求配置指定的电路结构,让客户不必依赖于芯片制造商设计和制造的专用集成电路就可以实现所需要的功能,同时实现非常高效的逻辑运算。其基本结构包括可编程输入输出单元,可配置逻辑块,数字时钟管理模块,嵌入式块RAM,布线资源,内嵌专用硬核,底层内嵌功能单元。

+

1.2 Verilog

+

Verilog HDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。Verilog HDL提供了编程语言接口,通过这个接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行。

+
module main(
+    input I0,
+    input I1.
+    input I2,
+    output O );
+
+

wire的电器特性:

+
    +
  • wire必须被有且仅有一个assign输入;
  • +
  • wire可以有0个或者多个assign输出.
  • +
+

运算符

+

按位运算符:

+
    +
  • &:按位与;
  • +
  • |:按位或;
  • +
  • ^:按位异或;
  • +
  • ~:按位取反;
  • +
  • ~^:按位同或;
  • +
+

Example

+

1.1 2-to-1 Multiplexer

+

我们首先以一种特别的角度看与门:与的运算的作用之一就是屏蔽,当某个输入的值为零时,与的输出就是零,不管另一个输入是什么。这就使得我想要的数据都未被屏蔽,不想要的都被屏蔽为0。比如对于运算\(A\land S\)\(S\)可以看作一个选择子,当\(S=T\)的时候,输出就是\(A\),不论\(A\)的真值为多少,输出的值就是\(A\)的值;当\(S=F\)的时候,输出就是\(F\),这时候\(A\)就被屏蔽了。

+

二路选择器的逻辑就是“屏蔽”,对于下面的二路选择器,最重要的结构就是上下两个与门中间一个非门,选择信号\(S\)分成两份,通过非门变成两个不同的信号,分别接向两个与门,如果\(S\)的信号为\(1\)/\(T\),那么就将下面的门屏蔽,输出上边的门信号;反之亦然。 +alt text

+
+
+
+

这里边利用了Verilog内置的一些门,比如ANDOR门。这种描述方式的优点就是可以很好的与真实的电路相对应,但是缺点就是不够简洁,写起来很坐牢。 +

module Mux2to1 (
+    input I0,
+    input I1,
+    input S,
+    output O
+    );
+    wire S0_n;
+    NOT not0 (S0_n, S);
+    // assign S0_n = ~S;
+    wire and0_s;
+    wire and1_s;
+    AND and0(and0_s, I0, S0_n);
+    AND and1(and1_s, I1, S);
+    OR or0(O, and0_s, and1_s);
+

+
+
+

这种描述方法充分利用了与&、或|、非~以及异或^等运算符代替了ANDORNOT等门的描述,使得描述更加简洁。忍不住了,直接写数组。 +

module Mux2to1 (
+    input [1:0] I,
+    input S,
+    output O
+    );
+    assign O = I[0] & ~S | I[1] & S;
+
+并且这种写法还需要注意优先级的问题,Verilog的优先级是~>&>|,所以这里的写法是正确的。

+

我们还应该知道:

+
    +
  • 一个类C的运算符其实是一个简化描述的电路
  • +
  • 一个运算符的操作数是这个电路的输入;
  • +
  • 一个运算符运算表达式的值是这个电路的输出;
  • +
  • 运算表达式的嵌套是门电路的级联;
  • +
+
+
+

这种描述方法是最简洁的,但是也是最抽象的,使用了大量的高度抽象的类C语句来提升编程的灵活性: +

module Mux2to1 (
+    input I0,
+    input I1,
+    input S,
+    output O
+    );
+    assign O = S ? I1 : I0;
+

+

Verilog利用了C中的三目运算符来实现了二路选择器,语法是这样的exp0 ? exp1 : exp2,这里的赋值语句并不是表示如果选择子\(S\)\(1\),我就把I0I1连上,实际上这就是一个二路选择器exp0构造选择子电路的输出,真不是不连电路啊……

+
+
+
+

if-else 必须在always块中使用,并且输出必须是reg类型。但是在always@(*)中,内部的reg被综合成wire类型

+

1.2 复合多路选择器/Cascaded Mux

+

多路选择器可以根据选择子从多个单bit输入中选择单bit输出,但是如果我们需要从多个多bit输入中选择多bit输出,那么就需要使用复合多路选择器。复合多路选择器在硬件实现上其实是由多个单路选择器级联而成的。

+

1.3 七段数码管译码器/Seven-Segment Decoder

+

七段数码管的显示译码的对应关系如下,使用复合多路选择器,就不难得到下面源码。解释源码的方法很简单,把它的接口ag分开,当卡诺图写就好了。

+

alt text +alt text

+
+
+
+
+
+
module SegDecoder (
+    input wire [3:0] data,
+    input wire point,
+    input wire LE,
+
+    output wire a,
+    output wire b,
+    output wire c,
+    output wire d,
+    output wire e,
+    output wire f,
+    output wire g,
+    output wire p
+);
+
+    assign a = LE | ( data[0] &  data[1] & ~data[2] &  data[3] | 
+                      data[0] & ~data[1] &  data[2] &  data[3] | 
+                     ~data[0] & ~data[1] &  data[2] & ~data[3] | 
+                      data[0] & ~data[1] & ~data[2] & ~data[3] );
+    assign b = LE | ( data[0] &  data[1] &  data[3] | 
+                     ~data[0] &  data[2] &  data[3] |
+                     ~data[0] &  data[1] &  data[2] | 
+                      data[0] & ~data[1] &  data[2] & ~data[3] );
+    assign c = LE | ( data[1] &  data[2] &  data[3] |
+                     ~data[0] &  data[1] & ~data[2] & ~data[3] |
+                     ~data[0] &  data[2] &  data[3] );
+    assign d = LE | (~data[0] &  data[1] & ~data[2] &  data[3] |
+                      data[0] &  data[1] &  data[2] |
+                     ~data[0] & ~data[1] &  data[2] & ~data[3] |
+                      data[0] & ~data[1] & ~data[2] & ~data[3] );
+    assign e = LE | ( data[0] & ~data[1] & ~data[2] |
+                     ~data[1] &  data[2] & ~data[3] |
+                      data[0] & ~data[3] );
+    assign f = LE | ( data[0] &  data[1] & ~data[3] |
+                      data[1] & ~data[2] & ~data[3] |
+                      data[0] & ~data[2] & ~data[3] |
+                      data[0] & ~data[1] &  data[2] &  data[3] );
+    assign g = LE | (~data[0] & ~data[1] &  data[2] &  data[3] |
+                      data[0] &  data[1] &  data[2] & ~data[3] |
+                     ~data[1] & ~data[2] & ~data[3] );
+    assign p = ~point;
+
+endmodule //SegDecoder
+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/System/images/image.png b/Computer Science/System/images/image.png new file mode 100644 index 0000000..92dc517 Binary files /dev/null and b/Computer Science/System/images/image.png differ diff --git a/Computer Science/System/images/img-Verilog/5.png b/Computer Science/System/images/img-Verilog/5.png new file mode 100644 index 0000000..dc8a89e Binary files /dev/null and b/Computer Science/System/images/img-Verilog/5.png differ diff --git a/Computer Science/System/images/img-Verilog/7.png b/Computer Science/System/images/img-Verilog/7.png new file mode 100644 index 0000000..6579287 Binary files /dev/null and b/Computer Science/System/images/img-Verilog/7.png differ diff --git a/Computer Science/System/images/img-Verilog/mux2to1.png b/Computer Science/System/images/img-Verilog/mux2to1.png new file mode 100644 index 0000000..c24837f Binary files /dev/null and b/Computer Science/System/images/img-Verilog/mux2to1.png differ diff --git a/Computer Science/System/index.html b/Computer Science/System/index.html new file mode 100644 index 0000000..cfedcf8 --- /dev/null +++ b/Computer Science/System/index.html @@ -0,0 +1,1111 @@ + + + + + + + + + + + + + + + + + + + + + + + Index - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Index

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Web/CSS/index.html b/Computer Science/Web/CSS/index.html new file mode 100644 index 0000000..514cb75 --- /dev/null +++ b/Computer Science/Web/CSS/index.html @@ -0,0 +1,1119 @@ + + + + + + + + + + + + + + + + + + + + + + + CSS - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

CSS

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Web/HTML/index.html b/Computer Science/Web/HTML/index.html new file mode 100644 index 0000000..0655810 --- /dev/null +++ b/Computer Science/Web/HTML/index.html @@ -0,0 +1,1367 @@ + + + + + + + + + + + + + + + + + + + + + + + HTML - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

HTML

+
+

Abstract

+

这是我的HTML笔记。

+

为啥要学HTML?

+

都学计算机了,总得学点前端吧。况且对于一个强迫症而言,我需要合适的工具来改进排版。

+
+
+

Info

+

HTML(HyperText Markup Language)是用来描述网页的一种标记语言。标记语言使用一套标记标签来描述内容。

+
+

01 HTML基础

+

01.1 HTML基本结构

+

下面是一个完整的HTML页面:

+
<!DOCTYPE HTML>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <title> 第一个HTML页面 </title>
+    </head>
+
+    <body>
+        <h1> 第一个标题 </h1>
+        <p> 第一个段落 </p>
+    </body>
+</html>
+
+

其中: +- <!DOCTYPE HTML> 声明了文档类型,为HTML5文档。 +- <html> 元素是HTML页面的根元素,定义了整个HTML文档。 +- <head> 元素包含了文档的元(meta)数据,如标题、链接到外部样式表等。 +- <meta charset="utf-8"> 这就是一个元数据,定义了网页的编码格式为UTF-8。 +- <title> 元素描述了文档的标题。 +- <body> 元素包含了可见的页面内容,定义了HTML文档的主体。 +- <h1> 元素定义了一个大标题,这是最高级的标题,<h6> 定义了最低级的标题。 +- <p> 元素定义了一个段落。

+

我们能看出来,HTML标签是由尖括号包围的关键词,比如<html>,并且大多数标签都是成对出现的,比如<html></html>,其中前者是开始标签/开放标签,后者是结束标签/闭合标签

+

HTML元素和HTML标签表示的是一样的意思,但是严格来说,HTML元素包括了开始标签和结束标签,元素的内容就是标签之间塞进去的部分。

+

下面就是一个可视化的HTML页面结构:

+
<html> +
<head> +
<title>页面标题</title> +
+</head> +
+
<body> +
<h1>这是一个标题</h1>
+
<p>这是一个段落。</p>
+
<p>这是另外一个段落。</p>
+</body> +
+</html> +
+


+

01.2 最基础的语法

+
    +
  • +

    标题:标题是通过<h1><h6>标签来定义的,<h1>是最大的标题,<h6>是最小的标题。

    +
    <h1> 最大的标题</h1>
    +<h2> 次大的标题</h2>
    +<h3> 更小的标题</h3>
    +
    +
  • +
  • +

    段落:段落是通过<p>标签来定义的。

    +
    <p> 这是一个段落。</p>
    +<p> 这是另外一个段落。</p>
    +
    +
  • +
  • +

    链接:链接是通过<a>标签来定义的,在href属性中指定连接的URL。

    +
    <a href="http://www.baidu.com"> 这是一个链接</a>
    +
    +
  • +
  • +

    图像:图像是通过<img>标签来定义的,通过src属性指定图像的URL。图像的名称和尺寸是通过属性的方式指定的。

    +
    <img src="/images/logo.png" width="258" height="39" />
    +
    +
  • +
+

01.3 HTML元素

+

HTML元素以开始标签开始,以结束标签终止,结束标签里边会塞一个斜杠/,中间塞的就是元素内容。值得注意的是:

+
    +
  • 某些标签具有空内容
  • +
  • 大多数元素可以具有属性
  • +
  • 空元素在开始标签就进行关闭;
  • +
  • HTML元素可以嵌套,HTML文档就是由嵌套的元素构成的。
  • +
+

没有内容的HTML元素称为空元素,空元素在开始标签内关闭。比如定义换行的标签<br>就是没有关闭标签的空元素。尽管空元素给我们一种错觉,似乎空元素就不用关闭了,但是在开始标签内添加一个斜杠才是空元素的正确关闭方式,比如<br />,虽然现在的标准与当前的浏览器对于<br>都是有效的,但是XHTML、XML和未来版本的HTML都要求所有元素必须关闭。

+

HTML标签对于大小写不敏感,<P><p>是一样的,甚至很多网站都使用大写的HYML标签。但是标准推荐小写,并且在XHTML和未来版本的HTML中,都强制使用小写

+

01.4 HTML属性

+

对于HTML属性,有下面信息:

+
    +
  • HTML元素可以设置属性;
  • +
  • 属性可以在元素中添加附加信息;
  • +
  • 属性一般描述于开始标签
  • +
  • 属性一般是以键值对的形式出现,比如name="value"
  • +
+

我们拿链接元素来举例:

+
<a href="http://baidu.com">这是定向到百度的超文本链接</a>
+
+

属性值应该始终被包括在引号之内,双引号是最常用的,但是单引号也可以,如果属性值本身就有了双引号,那么必须在外边使用单引号。

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Web/Javascript/index.html b/Computer Science/Web/Javascript/index.html new file mode 100644 index 0000000..7420f02 --- /dev/null +++ b/Computer Science/Web/Javascript/index.html @@ -0,0 +1,1119 @@ + + + + + + + + + + + + + + + + + + + + + + + JavaScript - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

JavaScript

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Web/YAML/index.html b/Computer Science/Web/YAML/index.html new file mode 100644 index 0000000..c1fe23c --- /dev/null +++ b/Computer Science/Web/YAML/index.html @@ -0,0 +1,1481 @@ + + + + + + + + + + + + + + + + + + + + + + + YAML - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

YAML

+ +

YAML是一种数据序列化语言,更多用于编写配置文件

+

基本语法

+
    +
  • +

    大小写敏感

    +
  • +
  • +

    使用缩进表示层级关系

    +
  • +
  • +

    缩进只能使用空格,不能使用tab

    +
  • +
  • +

    缩进的空格数目不重要,但是同一个层级上的元素左侧必须对齐

    +
  • +
  • +

    #表示注释,但是只支持单行注释

    +
  • +
+

数据类型

+

YAML支持下面几种数据类型:

+
    +
  • +

    对象:是键值对的集合,也叫映射(Mapping)

    +
  • +
  • +

    数组:一组按照次序排列的值,有成为序列(Sequence)或者列表(List)

    +
  • +
  • +

    纯量:单个的、不可再分的值,也叫标量(Scalar)

    +
  • +
+

对象

+

对象键值对使用冒号结构表示:key: value,冒号的后面要加一个空格。对象支持多级嵌套,也支持流式风格的语法(亦即使用花括号包裹,拿逗号分割),比如:

+
key:
+  value
+  chile-key: value
+  flow-style-key: {child-key1: value1, child-key2: value2}
+
+

当遇到复杂对象时,我们允许使用问号?来声明,这样就可以使用多个词汇(其实是数组)来组成键,亦即对象的属性是一个数组,对应的值也是一个数组:

+
?
+  - keypart1
+  - keypart2
+:
+  - value1
+  - value2
+
+

数组

+

一组以区块格式(Block Format)(亦即短横线+空格)开头的数据构成一个数组:

+
values: 
+  - value1
+  - value2
+  - value3
+
+

YAML也支持*内联格式(Inline Format)的数组(拿方括号包裹,逗号加空格分割):

+
values: [value1, value2, value3]
+
+

同样,嵌套格式的数组也是完全支持的,只需要使用缩进表示层级关系就好了。

+

纯量

+

字符串一般不需要使用引号包裹,但是如果在字符串之中使用了反斜杠开头的转义字符就必须用引号包裹了:

+
strings:
+  - this is a string
+  - 'this is s string'
+  - "this is a string"
+  - this is "a 'string'"
+
+

布尔值TruetrueTRUEYesyesYES都为真;FalsefalseFALSENonoNO皆为假。

+

整数:除了可以正常写十进制,YAML还支持二进制(前缀0b)和十六进制(前缀0x)表示:

+
int: 
+  - 666
+  - 0b1010_0111
+  - 0x10
+
+

浮点数:字面量(3,14)和科学计数法(6.8523015e+5)都可以。

+

nullNull~都是空,不指定默认也是空。

+

时间戳:使用ISO 8601格式的时间数据(日期和时间之间使用T链接,使用+表示时区):

+
date1: 2024-02-10 # 这是日期
+date2: 2024-02-10T20:30:00+08:00 # 这是时间戳
+
+

引用

+

为了保持内容的简洁,避免过多的重复的定义,YAML使用&表示建立锚点,*表示引用锚点、<<表示合并到当前数据:

+
defaults: &defaults
+  adapter:  postgres
+  host:     localhost
+
+development:
+  database: myapp_development
+  <<: *defaults
+
+test:
+  database: myapp_test
+  <<: *defaults
+
+

上面的代码相当于:

+
defaults:
+  adapter:  postgres
+  host:     localhost
+
+development:
+  database: myapp_development
+  adapter:  postgres
+  host:     localhost
+
+test:
+  database: myapp_test
+  adapter:  postgres
+  host:     localhost
+
+

特殊语法支持

+

保留换行

+

使用竖线|来表示该语法,这时每行的缩进和尾行空白都会去掉,而额外的缩进则被保留: +

lines: |
+  我是第一行
+  我是第二行
+    我是吴彦祖
+      我是第四行
+  我是第五行
+
+# JSON
+# "lines": "我是第一行\n我是第二行\n  我是吴彦祖\n    我是第四行\n我是第五行"
+

+

折叠换行

+

使用右尖括号>表示该语法,这时只有空白行才会被识别为换行,原来的换行符都会被转换为一个空格:

+
# YAML
+lines: >
+  我是第一行
+  也是第一行
+  仍是第一行
+  依旧是第一行
+
+  第二行
+  也是第二行
+
+# JSON
+# "lines": "我是第一行 也是第一行 仍是第一行 依旧是第一行\n第二行 也是第二行"
+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/Web/index.html b/Computer Science/Web/index.html new file mode 100644 index 0000000..6ff9870 --- /dev/null +++ b/Computer Science/Web/index.html @@ -0,0 +1,1111 @@ + + + + + + + + + + + + + + + + + + + + + + + Index - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Index

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Computer Science/index.html b/Computer Science/index.html new file mode 100644 index 0000000..c5899d1 --- /dev/null +++ b/Computer Science/index.html @@ -0,0 +1,1112 @@ + + + + + + + + + + + + + + + + + + + + + + + Computer Science - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Computer Science

+
+

Abstract

+

有关计算机的都在这了!

+

这里是我在浙江大学图灵班期间的学习笔记。

+
+
+

Warning

+

这里有部分为了整齐而放弃了一部分考究的内容分类,请不要在意,谢谢!

+
+

Table of Contents

+

Programming Basis

+ +

Programming Language

+ +

Web

+ +

System

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Javascripts/katex.js b/Javascripts/katex.js new file mode 100644 index 0000000..6db5642 --- /dev/null +++ b/Javascripts/katex.js @@ -0,0 +1,39 @@ +(function () { + 'use strict'; + + var katexMath = (function () { + var maths = document.querySelectorAll('.arithmatex'), + tex; + + for (var i = 0; i < maths.length; i++) { + tex = maths[i].textContent || maths[i].innerText; + if (tex.startsWith('\\(') && tex.endsWith('\\)')) { + katex.render(tex.slice(2, -2), maths[i], {'displayMode': false}); + } else if (tex.startsWith('\\[') && tex.endsWith('\\]')) { + katex.render(tex.slice(2, -2), maths[i], {'displayMode': true}); + } + } + }); + + (function () { + var onReady = function onReady(fn) { + if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", fn); + } else { + document.attachEvent("onreadystatechange", function () { + if (document.readyState === "interactive") { + fn(); + } + }); + } + }; + + onReady(function () { + if (typeof katex !== "undefined") { + katexMath(); + } + }); + })(); + + }()); + \ No newline at end of file diff --git a/Javascripts/mathjax.js b/Javascripts/mathjax.js new file mode 100644 index 0000000..dd987d4 --- /dev/null +++ b/Javascripts/mathjax.js @@ -0,0 +1,19 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true, + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex", + }, +}; + +document$.subscribe(() => { + MathJax.startup.output.clearCache(); + MathJax.typesetClear(); + MathJax.texReset(); + MathJax.typesetPromise(); +}); \ No newline at end of file diff --git a/Javascripts/scheme.js b/Javascripts/scheme.js new file mode 100644 index 0000000..b73a6c7 --- /dev/null +++ b/Javascripts/scheme.js @@ -0,0 +1,98 @@ +(() => { + + const preferToggle = e => { + if (localStorage.getItem("data-md-prefers-color-scheme") === "true") { + document.querySelector("body").setAttribute("data-md-color-scheme", (e.matches) ? "slate" : "default") + } + var frame = document.querySelector(".giscus-frame") + var theme = document.querySelector("body").getAttribute("data-md-color-scheme") === "slate" ? "https://gcore.jsdelivr.net/gh/TonyCrane/note/docs/css/giscus.css" : "light" + frame.contentWindow.postMessage( + { giscus: { setConfig: { theme } } }, + "https://giscus.app" + ) + } + + const setupTheme = body => { + const preferSupported = window.matchMedia("(prefers-color-scheme)").media !== "not all" + let scheme = localStorage.getItem("data-md-color-scheme") + let prefers = localStorage.getItem("data-md-prefers-color-scheme") + let oldversion = localStorage.getItem("/.__palette") + + if (oldversion) { + localStorage.removeItem("/.__palette") + } + + if (!scheme) { + scheme = "slate" + } + if (!prefers) { + prefers = "false" + } + + if (prefers === "true" && preferSupported) { + scheme = (window.matchMedia("(prefers-color-scheme: dark)").matches) ? "slate" : "default" + } else { + prefers = "false" + } + + body.setAttribute("data-md-prefers-color-scheme", prefers) + body.setAttribute("data-md-color-scheme", scheme) + + if (preferSupported) { + const matchListener = window.matchMedia("(prefers-color-scheme: dark)") + matchListener.addListener(preferToggle) + } + } + + const observer = new MutationObserver(mutations => { + mutations.forEach(mutation => { + if (mutation.type === "childList") { + if (mutation.addedNodes.length) { + for (let i = 0; i < mutation.addedNodes.length; i++) { + const el = mutation.addedNodes[i] + + if (el.nodeType === 1 && el.tagName.toLowerCase() === "body") { + setupTheme(el) + break + } + } + } + } + }) + }) + + observer.observe(document.querySelector("html"), {childList: true}) + setupTheme(document.querySelector("body")) +})() + +window.toggleScheme = () => { + const body = document.querySelector("body") + const preferSupported = window.matchMedia("(prefers-color-scheme)").media !== "not all" + let scheme = body.getAttribute("data-md-color-scheme") + let prefer = body.getAttribute("data-md-prefers-color-scheme") + + if (preferSupported && scheme === "default" && prefer !== "true") { + prefer = "true" + scheme = (window.matchMedia("(prefers-color-scheme: dark)").matches) ? "slate" : "default" + } else if (preferSupported && prefer === "true") { + prefer = "false" + scheme = "slate" + } else if (scheme === "slate") { + prefer = "false" + scheme = "default" + } else { + prefer = "false" + scheme = "slate" + } + localStorage.setItem("data-md-prefers-color-scheme", prefer) + localStorage.setItem("data-md-color-scheme", scheme) + body.setAttribute("data-md-prefers-color-scheme", prefer) + body.setAttribute("data-md-color-scheme", scheme) + + var frame = document.querySelector(".giscus-frame") + var theme = scheme === "slate" ? "https://gcore.jsdelivr.net/gh/TonyCrane/note/docs/css/giscus.css" : "light" + frame.contentWindow.postMessage( + { giscus: { setConfig: { theme } } }, + "https://giscus.app" + ) +} diff --git a/Javascripts/tablesort.js b/Javascripts/tablesort.js new file mode 100644 index 0000000..545388f --- /dev/null +++ b/Javascripts/tablesort.js @@ -0,0 +1,6 @@ +document$.subscribe(function () { + var tables = document.querySelectorAll("article table:not([class])"); + tables.forEach(function (table) { + new Tablesort(table); + }); +}); \ No newline at end of file diff --git a/Javascripts/toc.js b/Javascripts/toc.js new file mode 100644 index 0000000..6b58905 --- /dev/null +++ b/Javascripts/toc.js @@ -0,0 +1,80 @@ +(function (window, document) { + function register($toc) { + const currentInView = new Set(); + const headingToMenu = new Map(); + const $menus = Array.from($toc.querySelectorAll('.md-nav__list > li > a')); + + for (const $menu of $menus) { + const elementId = $menu.getAttribute('href').trim().slice(1); + const $heading = document.getElementById(elementId); + if ($heading) { + headingToMenu.set($heading, $menu); + } + } + + const $headings = Array.from(headingToMenu.keys()); + + const callback = (entries) => { + for (const entry of entries) { + if (entry.isIntersecting) { + currentInView.add(entry.target); + } else { + currentInView.delete(entry.target); + } + } + let $heading; + if (currentInView.size) { + // heading is the first in-view heading + $heading = [...currentInView].sort(($el1, $el2) => $el1.offsetTop - $el2.offsetTop)[0]; + } else if ($headings.length) { + // heading is the closest heading above the viewport top + $heading = $headings + .filter(($heading) => $heading.offsetTop < window.scrollY) + .sort(($el1, $el2) => $el2.offsetTop - $el1.offsetTop)[0]; + } + if ($heading && headingToMenu.has($heading)) { + $menus.forEach(($menu) => $menu.classList.remove('is-active')); + + const $menu = headingToMenu.get($heading); + $menu.classList.add('is-active'); + let $menuList = $menu.parentElement.parentElement.parentElement; + while ( + $menuList.classList.contains('md-nav') && + $menuList.parentElement.tagName.toLowerCase() === 'li' + ) { + $menuList.parentElement.children[0].classList.add('is-active'); + $menuList = $menuList.parentElement.parentElement.parentElement; + } + } + }; + const observer = new IntersectionObserver(callback, { threshold: 0 }); + + for (const $heading of $headings) { + observer.observe($heading); + // smooth scroll to the heading + if (headingToMenu.has($heading)) { + const $menu = headingToMenu.get($heading); + $menu.setAttribute('data-href', $menu.getAttribute('href')); + $menu.setAttribute('href', 'javascript:;'); + $menu.addEventListener('click', () => { + if (typeof $heading.scrollIntoView === 'function') { + $heading.scrollIntoView({ behavior: 'smooth' }); + } + const anchor = $menu.getAttribute('data-href'); + if (history.pushState) { + history.pushState(null, null, anchor); + } else { + location.hash = anchor; + } + }); + $heading.style.scrollMargin = '4em'; + } + } + } + + if (typeof window.IntersectionObserver === 'undefined') { + return; + } + + document.querySelectorAll('.md-sidebar--secondary').forEach(register); +})(window, document); diff --git a/Math/Analysis/A Little More Analysis.pdf b/Math/Analysis/A Little More Analysis.pdf new file mode 100644 index 0000000..f48f375 Binary files /dev/null and b/Math/Analysis/A Little More Analysis.pdf differ diff --git a/Math/Discrete Mathematics/01 Propositional Logic/index.html b/Math/Discrete Mathematics/01 Propositional Logic/index.html new file mode 100644 index 0000000..d76fb40 --- /dev/null +++ b/Math/Discrete Mathematics/01 Propositional Logic/index.html @@ -0,0 +1,1263 @@ + + + + + + + + + + + + + + + + + + + + + + + Propositional Logic - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Part 01 Propositional Logic

+

1.1 Propositions

+

A proposition is a declarative sentence that is either true or false, but not both. We use letters to denote propositional variables, or sentential variables, i.e. variables that represent propositions. The truth value of a proposition is true, denoted by T, if it is a true proposition, and similiarly, the truth value of a proposition is false, denoted by F, if it is a false proposition.Propositions that cannot be expressed in terms of simpler propositions are called atomic propositions.

+

We can form new propostions from existing ones using logical connectives. Here are six useful logical connectives: Negation/NOT (\(\neg\)), Conjunction/AND (\(\land\)), Disjunction/OR (\(\lor\)), Exclusive Or/XOR (\(\oplus\)), Conditional/IF-THEN (\(\to\)), and Biconditional/IFF AND ONLY IF (\(\leftrightarrow\)).

+

More on IMPLICATION:

+
    +
  • In \(p\to q\), \(p\) is the hypothesis/antecedent前件/premise前提, and \(q\) is the conclusion/consequent后件.
  • +
  • In \(p\to q\) there does not need to be any connection between the antecedent or the consequent. The “meaning” of \(p\to q\) depends only on the truth values of \(p\) and \(q\).
  • +
+

From \(p\to q\), we can form the converse \(q\to p\), the inverse \(\neg p\to \neg q\), and the contrapositive \(\neg q\to \neg p\). The converse and the inverse are not logically equivalent to the original conditional, but the contrapositive is.

+

Construction of a truth table:

+
    +
  • Rows: Need a row for every possible combination of values for the atomic propositions.
  • +
  • Columns.1: Need a column for the compound proposition (usually at far right)
  • +
  • Columns.2: Need a column for the truth value of each expression that occurs in the compound proposition as it is built up. (This includes the atomic propositions.)
  • +
+

The truth value of \(p\leftrightarrow q\) is the same as the truth value of \((p\to q)\land (q\to p)\), that is to say, \(p\leftrightarrow q\) is true if and only if \(p\) and \(q\) have the same truth value.

+

Precedence of Logical Operators: From highest to lowest, the precedence of logical operators is \(\neg\), \(\land\), \(\lor\), \(\to\), and \(\leftrightarrow\).

+

1.3 Logical Equivalence

+

Basic terminology and its concepts:

+
    +
  • Tautologies/永真式: A tautology is a proposition which is always true, e.g. \(p\lor \neg p\);
  • +
  • Contradictions/矛盾式: A contradiction is a proposition which is always false, e.g. \(p\land \neg p\);
  • +
  • Contingencies/可能式: A contingency is a proposition which is neither a tautology nor a contradiction, e.g. \(p\).
  • +
+

Two compound propositions \(p\) amd \(q\) are logically equivalent if \(q\leftrightarrow q\) is a tautology. We denote this by \(p\equiv q\) or \(p\Leftrightarrow q\).

+

Compound propositions that have the same truth values for all possible cases, in other words, the columns in a truth table giving their truth values agree, are called equivalent.

+

(Important) Conditional-disjunction equivalence states that for any propositions \(p\) and \(q\), we have

+
\[p\to q\equiv \neg p\lor q.\]
+

Absorption laws states that for any propositions \(p\) and \(q\), we have

+
\[p\lor (p\land q)\equiv p.\]
+
\[p\land (p\lor q)\equiv p.\]
+

De Morgan's Laws states that for any propositions \(p\) and \(q\), we have

+
\[\neg(p\land q)\equiv \neg p\lor \neg q\]
+
\[\neg(p\lor q)\equiv \neg p\land \neg q.\]
+

Distribution laws states that for any propositions \(p\), \(q\), and \(r\), we have

+
\[p\lor (q\land r)\equiv (p\lor q)\land (p\lor r).\]
+
\[p\land (q\lor r)\equiv (p\land q)\lor (p\land r).\]
+

Identity Laws states that for any propositions \(p\), we have

+
\[p\land T\equiv p.\]
+
\[p\lor F\equiv p.\]
+

Domination Laws states that for any propositions \(p\), we have

+
\[p\lor T\equiv T.\]
+
\[p\land F\equiv F.\]
+

Idempotent Laws states that for any propositions \(p\), we have

+
\[p\lor p\equiv p.\]
+
\[p\land p\equiv p.\]
+

Moreover, Commutative Laws and Associative Laws are also valid for logical connectives: for any propositions \(p\), \(q\), and \(r\), we have

+
\[p\lor q\equiv q\lor p.\]
+
\[p\land q\equiv q\land p.\]
+
\[(p\lor q)\lor r\equiv p\lor (q\lor r).\]
+
\[(p\land q)\land r\equiv p\land (q\land r).\]
+

Involving Conditional and Biconditional statements, we have

+

Conditional and Biconditional statements

+ + +

The Dual of compound proposition that contains only the logic operators \(\land\), \(\lor\), and \(\neg\) the proposition obtained by replacing each \(\land\) by \(\lor\), each \(\lor\) by \(\land\), each \(T\) by \(F\), and each \(F\) by \(T\). The dual of \(S\) is denoted by \(S^*\). For example, the dual of \(p\lor (q\land \neg r)\) is \(\neg p\land (q\lor \neg r)\).

+

We already know that only two logical operators \(\{\neg,\land\}\) or \(\{\neg,\lor\}\) are enough to express all logical propositions. Thus, a collection of logical operators is called functionally complete if every possible logical proposition is logically equivalent to a compound proposition involving only these operators.

+

The Sheffer Stroke/与非 is a functionally complete set of logical operators. It is denoted by \(p|q\), and \(p|q\) is false when both \(p\) and \(q\) are true, and true otherwise. The Peirce Arrow/或非 is also a functionally complete set of logical operators. It is denoted by \(p\downarrow q\), and \(p\downarrow q\) is true when both \(p\) and \(q\) are false, and false otherwise.

+

A compound proposition is satisfiable if there is an assignment of truth values to its variables that makes it true. When no such assignments exits, the compound proposition is unsatisfiable.

+

A compound proposition is unsatisfiable if and only if it is a contradiction or its negation is a tautology.

+

1.4 Applications of Propositional Logic

+

A list of propositions is consistent if it is possible to assign truth values to the proposition variables so that each proposition is true.

+

1.5 Propositional Normal Forms

+

Propositional formula/命题公式 is a compound proposition that is built up from atomic propositions using logical connectives with the following criteria:

+
    +
  • Each propositional variable is a formula, and the truth values T and F are formulas.
  • +
  • If \(A\) is a formula, then \(\neg A\) is a formula.
  • +
  • If \(A\) and \(B\) are formulas, then \((A\land B)\), \((A\lor B)\), \((A\to B)\), and \((A\leftrightarrow B)\) are formulas.
  • +
  • A string of symbols is a formula if and only if it is determined by (finitely maly applications of) the above three rules.
  • +
+

Formulas can be transformed into standard forms so that they become more convenient for symbolic manipulations and make identification and comparison of two formulas easier. There are two types of normal forms in propositional calculus:

+
    +
  • +

    the Disjunctive Normal Form/DNF/析取范式: A formula is said to be in DNF if it written as a disjuction, in which all terms are conjunctions of literals.
    + For example, \((p\land q)\lor (\neg p\land r)\), \(p\lor (q\land r)\), \(\neg p\lor T\) are in DNF, and the disjunction \(\neg(p\land q)\lor r\) is not.

    +
  • +
  • +

    the Conjunctive Normal Form/CNF/合取范式: A formula is said to be in CNF if it written as a conjunction, in which all terms are disjunctions of literals.

    +
  • +
+

We can introduce the concept of Clauses/子句 to simplify the concept of DNF and CNF. A disjunction/conjunction with literials as disjuncts/conjuncts are called a Disjunctive/Conjunctive clause/析取子句/合取子句. Disjunctive/conjunctive clauses are simply called clauses. Moreover, conjunctive clause is also called Basic product and disjunctive clause is also called Basic addition.

+

Thus, a CNF is a conjunction of disjunctive clauses, and a DNF is a disjunction of conjunctive clauses.

+

A Midterm/极小项 is a conjunction of literials in which each variable is represented exactly once.

+

(IMPORTANT) There are \(2n\) different minterm for \(n\) propositional variables. For example there \(4\) different minterm for \(p\), \(q\), they are \(p\land q\), \(p\land\neg q\), \(\neg p \land q\), \(\neg p\land\neg q\). For the sake of simplification, we use \(m_j\) denote the minterms. Where \(j\) is a integer, its binary representation corresponds the evaluation of variables that make \(m_j\) be equal to T.

+

If a proposition form is denoted by: \(f=m_j\lor m_k\lor\cdots\lor m_l\), then we simply denote

+
\[f=\sum m(j,k,\cdots,l).\]
+

Properties of minterms:

+
    +
  • Each minterm is true for exactly one assignment.
  • +
  • The conjunction of two different minterm is always false.
  • +
  • The disjunction of all minterms is T.
  • +
  • A disjinction of minterms is true only if at least one of the constituent minterms is ture.
  • +
+

If a function, as \(f\), is given by truth table, we know exactly for which assignments it is true. Consequently, we can select the minterms that make the function true and form the disjunction of these minterms.

+

If a Boolean function is expressed as a disjunction of minterms, it is said to be in full disjunctive form.

+

All above is the concept of DNF and the concept and use of minterms. Now we turn to CNF.

+

A compound proposition is in CNF if it is a conjunction of disjunctive clauses. Every proposition can be put in an equivalent CNF. CNF is useful in the study of resolution theorem proving used in AI.

+

A compound proposition can be put in conjunctive normal form through repeated application of the logical equivalences covered earlier.

+

A Maxterm/极大项 is a disjunction of literials in which each variable is represented exactly once. If a Boolean function is expressed as a conjunction of maxterms, it is said to be in full conjunctive form.

+

We can get the full conjunctive form of a Boolean function from its full disjunction form: Let \(f=\sum f(j,k,\cdots,l)\), \(g=\sum m(\{0,1,2,\cdots,2^{n-1}\}-\{j,k,\cdots,l\})\), then \(f\lor g = T\), \(f\land g = F\).

+
\[f = \neg g = \prod M(\{0,1,2,\cdots,2^{n-1}\}-\{j,k,\cdots,l\}).\]
+

The \(M_i\) is a maxterm defined by \(M_i=\neg m_i\).

+

1.6 Predicates and Quantifiers

+

In this section, we will introduce Predicate logic/谓词逻辑. A predicate refers to a property that the subject of the statement can have. We can denote the statement "\(x\) is greater than \(3\)" by \(P(x)\), where \(P\) denotes the predicate "is greater than \(3\)" and \(x\) is the variable. The statement \(P(x)\) is also said to be the value of the propositional function \(P\) at \(x\).

+

Propositional functions become propositions when their variables are each replaced by a value from the domain.

+

We need quantifiers/量词 to express the meaning of English words including all and some. Two most important quantifiers are:

+
    +
  • Universal Quantifier: \(\exists\) means "There exists";
  • +
  • Existential Quantifier: \(\forall\) means "For all".
  • +
+

Domain/domain or discourse/universe of discourse: the range of the possible values of the variable.

+

Given the domain as \(\{x_1, x_2, \cdots, x_n\}\), the proposition \(\forall xP(x)\) is equivalent to \(P(x_1)\land P(x_2)\land\cdots\land P(x_n)\), and the proposition \(\exists xP(x)\) is equivalent to \(P(x_1)\lor P(x_2)\lor\cdots\lor P(x_n)\).

+

Uniqueness Quantifier: \(\exists !\) means "There exists a unique", that is \(P(x)\) is true for one and only one \(x\) in the domain. The uniqueness quantifier can be expressed without the symbol \(!\) : \(\exists x(P(x)\land \forall y(P(x)\to y=x))\).

+

Precedence of Quantifiers: The quantifiers \(\forall\) and \(\exists\) have higher precedence than the logical connectives \(\neg\), \(\land\), \(\lor\), \(\to\), and \(\leftrightarrow\). For example, \(\forall xP(x)\land Q(x)\) means \((\forall xP(x))\land Q(x)\).

+

Bound Variable: A variable is bound if it is known or quantified. A variable is free if it is neither quantified or specified with a value.

+

All the variables in a propositional function must be quantified or set equal to a particular value to turn it into a proposition.

+

Scope of a quantifier: the part of a logical expression to which the quantifier is applied

+

Logical Equivalence with Logical Quantifiers:

+

alt text

+

De Morgan's Laws for Quantifiers:

+
\[\neg\forall xP(x)\equiv \exists x\neg P(x).\]
+
\[\neg\exists xP(x)\equiv \forall x\neg P(x).\]
+

1.7 Nested Quantifiers

+

Nested Quantifiers: Two quantifiers are nested if one is within the scope of the other. For example, \(\forall x\exists yP(x,y)\) means "For every \(x\), there exists a \(y\) such that \(P(x,y)\) is true".

+

Order of Quantifiers: Only both quantifiers are universal or both are existential, the order of quantifiers can be changed. +alt text

+

Distributions for Quantifiers over Logical Connectives: Here I list two examples: \(\forall x(P(x)\land Q(x))\equiv \forall xP(x)\land \forall xQ(x)\) is True, whereas \(\forall x(P(x)\to Q(x))\equiv \forall xP(x)\to \forall xQ(x)\) is False.

+

1.8 Rules of Inference

+

Valid Argumemts:An argument in propositional logic is a sequence of propositions. All but the final proposition are called premises/前提. The last statement is the conclusion/结论. The argument is valid/有效 if the premises imply the conclusion. An argument form is an argument that is valid no matter what propositions are substituted into its propositional variables.

+

If the premises are \(p_1, p_2,\dots, p_n\) and the conclusion is \(q\) then \((p_1\land p2 \land \cdots\land p_n )\to q\) is a tautology.

+

Inference Rules are all argument simple argument forms that will be used to construct more complex argument forms.

+

Modus Ponens/假言推理: If \(p\to q\) and \(p\) are true, then \(q\) is true. Corresponding Tautology: \((p\land (p\to q))\to q\).

+

Modus Tollens/取拒式: If \(p\to q\) and \(\neg q\) are true, then \(\neg p\) is true. Corresponding Tautology: \(((p\to q)\land \neg q)\to \neg p\).

+

Hypothetical Syllogism/假言三段论: If \(p\to q\) and \(q\to r\) are true, then \(p\to r\) is true. Corresponding Tautology: \(((p\to q)\land (q\to r))\to (p\to r)\).

+

Disjunctive Syllogism/析取三段论: If \(p\lor q\) and \(\neg p\) are true, then \(q\) is true. Corresponding Tautology: \(((p\lor q)\land \neg p)\to q\).

+

Addition/附加律: If \(p\) is true, then \(p\lor q\) is true. Corresponding Tautology: \(p\to (p\lor q)\).

+

Simplification/简化律: If \(p\land q\) is true, then \(p\) is true. Corresponding Tautology: \((p\land q)\to p\).

+

Conjunction/合取律: If \(p\) and \(q\) are true, then \(p\land q\) is true. Corresponding Tautology: \((p\land q)\to (p\land q)\).

+

Resolution/消解律: If \(p\lor q\) and \(\neg p\lor r\) are true, then \(q\lor r\) is true. Corresponding Tautology: \(((p\lor q)\land (\neg p\lor r))\to (q\lor r)\).

+

Universal Instantiation/全称实例: If \(\forall xP(x)\) is true, then \(P(c)\) is true for any \(c\) in the domain. Corresponding Tautology: \(\forall xP(x)\to P(c)\).

+

Universial Generalization/全称引入: If \(P(c)\) is true for any \(c\) in the domain, then \(\forall xP(x)\) is true. Corresponding Tautology: \(P(c)\to \forall xP(x)\).

+

Existential Instantiation/存在实例: If \(\exists xP(x)\) is true, then \(P(c)\) is true for some \(c\) in the domain. Corresponding Tautology: \(\exists xP(x)\to P(c)\).

+

Existential Generalization/存在引入: If \(P(c)\) is true for some \(c\) in the domain, then \(\exists xP(x)\) is true. Corresponding Tautology: \(P(c)\to \exists xP(x)\).

+

Universial Modus Ponens/全称假言推理: If \(\forall x(p(x)\to q(x))\) and \(p(a)\) are true, then \(q(a)\) is true. Corresponding Tautology: \((\forall x(p(x)\to q(x))\land p(a))\to q(a)\).

+

1.9 Introduction to Proofs

+

A proof is a valid argument that establishes the truth of a statement. In math, CS, and other disciplines, informal proofs which are generally shorter, are generally used.

+

A theorem/定理 is a statement that can be shown to be true using: definitions, other theorems, axioms (statements which are given as true), rules of inference.

+

A lemma/引理 is a 'helping theorem' or a result which is needed to prove a theorem.

+

A corollary/推论 is a result which follows directly from a theorem.

+

Less important theorems are sometimes called propositions/命题.

+

A conjecture/猜想 is a statement that is being proposed to be true. Once a proof of a conjecture is found, it becomes a theorem. It may turn out to be false.

+

Direct Proof: Assume that \(p\) is true. Use rules of inference, axioms, and logical equivalences to show that \(q\) must also be true.

+

Proof by Contraposition/反证法: Assume \(\neg q\) and show \(\neg p\) is true also. This is sometimes called an indirect proof method. If we give a direct proof of \(\neg q\to\neg p\) then we have a proof of \(p\to q\).

+

Proof by Contradiction/归谬证明法/Reductio ad absurdum: To prove \(p\), assume \(\neg p\) and derive a contradiction such as \(r\land \neg r\). (an indirect form of proof). Since we have shown that \(\neg p\to F\) is true , it follows that the contrapositive \(T\to p\) also holds.

+

1.10 Proof Method and Strategy

+

Proof by cases: To prove \((p_1\lor p_2\lor \cdots\lor p_n)\to q\), using the tautology \((p_1\to q)\land (p_2\to q)\land\cdots\land (p_n\to q)\leftrightarrow (p_1\lor p_2\lor \cdots\lor p_n)\to q\), we need to prove \(p_1\to q\), \(p_2\to q\), \(\cdots\), and \(p_n\to q\).

+

Existence Proofs/存在性证明,Without Loss of Generality/不失一般性,Nonconstructive Proofs/非构造性证明,Proof by Counterexample/反例证明,Uniqueness Proofs/唯一性证明,Backward Proof/逆向证明.

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Math/Discrete Mathematics/02 Basic Structures/index.html b/Math/Discrete Mathematics/02 Basic Structures/index.html new file mode 100644 index 0000000..5fc328e --- /dev/null +++ b/Math/Discrete Mathematics/02 Basic Structures/index.html @@ -0,0 +1,950 @@ + + + + + + + + + + + + + + + + + + + + + + + Basic Structures - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Basic Structures: Sets, Functions, Sequences, Sums, and Matrices

+

2.1 Sets

+

A set is an unordered collection of distinct objects, called elements or members of the set. A set is said to contain its elements. We write \(a\in A\) to denote that \(a\) is an element of the set \(A\). The notation \(a\notin A\) denotes that \(a\) is not an element of the set \(A\).

+

Roster method: A set can be described by listing its elements between braces. For example, the set of vowels in the English alphabet can be written as \(V=\{a,e,i,o,u\}\). Listing an element more than once does not change the set. The set \(\{a,e,i,o,u\}\) is the same as the set \(\{a,e,i,o,u,u\}\).

+

Set-builder notation: A set can be described by specifying a property that its members must satisfy.

+

Universal Set: The set \(U\) containing all the objects currently under consideration.

+

Empty Set: The set containing no elements, denoted by \(\emptyset\) or \(\{\}\).

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Math/Discrete Mathematics/04 Graph Theory/index.html b/Math/Discrete Mathematics/04 Graph Theory/index.html new file mode 100644 index 0000000..2c2a7f8 --- /dev/null +++ b/Math/Discrete Mathematics/04 Graph Theory/index.html @@ -0,0 +1,881 @@ + + + + + + + + + + + + + + + + + + + + + + + Graph Theory - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Graph Theory

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Math/Discrete Mathematics/Discrete Mathematics/index.html b/Math/Discrete Mathematics/Discrete Mathematics/index.html new file mode 100644 index 0000000..7b082fd --- /dev/null +++ b/Math/Discrete Mathematics/Discrete Mathematics/index.html @@ -0,0 +1,959 @@ + + + + + + + + + + + + + + + + + + + + + + + Discrete Mathematics - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Discrete Mathematics

+
+

Abstract

+

这是我在2023-2024学年春夏学期修读《离散数学理论基础》的课程笔记。

+

离散数学的内容繁杂,包含逻辑、集合论、图论等内容。对于计算机专业的学生来说,这部分包含的内容更加宽泛,可以说是“在数理基础课上讲不到的都在这了”

+

参考书籍:

+
    +
  • 《Discrete Mathematics and Its Applications》 By Kenneth H. Rosen
  • +
  • 《Concrete Mathmatics》 By Ronald L. Graham
  • +
+
+

Table of Contents

+ + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Math/Discrete Mathematics/images/image.png b/Math/Discrete Mathematics/images/image.png new file mode 100644 index 0000000..6bce031 Binary files /dev/null and b/Math/Discrete Mathematics/images/image.png differ diff --git a/Math/Discrete Mathematics/images/image1-1.png b/Math/Discrete Mathematics/images/image1-1.png new file mode 100644 index 0000000..c418f95 Binary files /dev/null and b/Math/Discrete Mathematics/images/image1-1.png differ diff --git a/Math/Discrete Mathematics/images/image1-2.png b/Math/Discrete Mathematics/images/image1-2.png new file mode 100644 index 0000000..c3ed31c Binary files /dev/null and b/Math/Discrete Mathematics/images/image1-2.png differ diff --git a/Math/index.html b/Math/index.html new file mode 100644 index 0000000..471d87e --- /dev/null +++ b/Math/index.html @@ -0,0 +1,898 @@ + + + + + + + + + + + + + + + + + + + + + + + Basic Courses - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Math

+
+

Abstract

+

有关数学的都在这了,目前正在学习的有:

+
    +
  • 数学分析
  • +
  • 复分析
  • +
  • 线性代数
  • +
+
+

Analysis

+
+

Abstract

+

这里是我的分析学笔记,我打算在分析学稍微深耕一点点,所以这里的内容可能会比较多。

+

我会奋力学,奋力更的!

+
+

Mathematical Analysis

+
+
+
+
A Little More Analysis
+
383 KB / 63 P / 2024-02-16
+
+

下载

+
+

Analysis All in One

+
+

Warning

+

什么?还没写?

+

先学再说!

+
+

Algebra

+

Linear Algebra

+
+

Abstract

+

真的在写了!哦,只是抄抄书啊……

+
+

Topology

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Reading/Taking Sides/Sustainability/index.html b/Reading/Taking Sides/Sustainability/index.html new file mode 100644 index 0000000..b2a106f --- /dev/null +++ b/Reading/Taking Sides/Sustainability/index.html @@ -0,0 +1,938 @@ + + + + + + + + + + + + + + + + + + + + + + + Sustainability - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Taking Sides: Clashing Views in Sustainability

+

Introduction

+

The Brundtland Commission laid out the most famous definition of sustainable development as development that "meets the needs of the present without compromising the ability of future generations to meet their needs."

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Reading/Taking Sides/index.html b/Reading/Taking Sides/index.html new file mode 100644 index 0000000..4e41ea3 --- /dev/null +++ b/Reading/Taking Sides/index.html @@ -0,0 +1,874 @@ + + + + + + + + + + + + + + + + + + + + + + + Taking Sides - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Taking Sides

+
+

Info

+

Taking Sides,亦即《立场》丛书

+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Reading/The Western Heritage/index.html b/Reading/The Western Heritage/index.html new file mode 100644 index 0000000..ee84cd3 --- /dev/null +++ b/Reading/The Western Heritage/index.html @@ -0,0 +1,976 @@ + + + + + + + + + + + + + + + + + + + + + + + The Western Heritage - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +
+

Info

+

未完工!我会加紧进度的!

+
+
+

Warning

+

本文仅作为本人对《The Western Heritage》一书的笔记,除记录知识以外再无其它意义

+
+

The Western Heritage

+

Chapter 0 : What Is The Western Heritage?

+

The western heritage emerges from an evolved and evolving story of human actions and interactions, peaceful and violent, that arose in the eastern Mediterranean, then spread across the western Mediterranean into northern Europe, and eventually to the American continents, and in their broadest impact, to the peoples of Africa and Asia as well.

+

The Western Heritage as a distinct portion of world history descends from the ancient Greeks, who saw their own political life based on open discussion of law and policy. The Greeks invented the concept of citizenship, defining it as engagement in some form of self-government. The Greeks also established their conviction that reason can shape and analyze physical nature, politics, and morality.

+

Rome spread its authority through military conquest across the Mediterranean world, embracing Greek literature and philosophy. Romans' conquest and imposition of law created the Western world as a vast empire stretching from Egypt and Syria in the east to Britain in the West. Although the Roman Republic, governed by Senate and popular political institutions (元老院与公众政治机构), gave way to the autocratic rule of Roman Empire, the idea of a free republic law and constitutional (宪法的) arrangements limiting political authority survived centuries of arbitrary (武断专制的、随心所欲的) rule by emperors.

+

Emperor Constantine reorganized the Roman Empire in two fundamental ways: First, he moved the capital from Rome to Constantinople. Thereafter (其后) large portions of the Western empire became subject to the rulers of Germanic tribes. In the confusion of these times, most of the texts embodying ancient philosophy, literature, and history became lost in the West, and for centuries Western Europeans became intellectually severed from that ancient heritage. Second, Constantine's recognition of Christianity as the official religion of the empire.

+

康斯坦丁将基督教作为帝国的官方宗教,由于基督教是单神论宗教,康斯坦丁对基督教的接纳导致了异端多神论宗教的消亡。此后,西方世界或多或少的都有与基督教相连,或者与承认罗马主教为首的基督教会相连。

+

随着皇权逐渐崩溃,主教变成了西欧许多区域的事实上的统治者,但是基督教会从未在未与世俗的统治者协商或者冲突的情况下加以统治,并且宗教法也没有取代世俗法,况且世俗的统治者也无法在忽略教会的影响下加以统治。Hence, from the fourth century C.E. to the present day, rival claims to political and moral authority between ecclesiastical and political officials have characterized the west.

+

In the seventh century, the rise of Islam, a new monotheistic religion, which spread rapidly through conquests across North Africa and eventually into Spain, confronted a new challenge to the Western World. Christians attempted to reclaim the Holy Land (圣地,亦即巴勒斯坦) from Muslim control in church-inspired military crusades (十字军东征) that still resonate negatively in the Islamic world.

+

However, while intellectual life languished in the West, most of the texts of ancient Greek and Latin learning survived and were studied in the Muslim world. By the fourteenth century, European thinkers redefined themselves and their intellectual ambitions by recovering the literature and science from the ancient world, reuniting Europe with its Graeco-Roman past.

+

From the twelfth through the eighteenth centuries, a new European political system arose based on centralized monarchies (中央集权的君主制) characterized by large armies, navies and bureaucracies loyal to the monarch (忠诚于皇帝的官僚体制), and by the capacity to raise revenues (提升税收). Most of these monarchies recognized both the political role of local or national assemblies drawn from the propertied elites (有产阶级精英) and the binding power of constitutional law on themselves. ** (宪法对于他们自己的约束力) The monarchies, their military, and their expanding commercial economies became the basis for the extension of European and Western influence around the globe.**

+

In the late fifteenth and early sixteenth centuries, two transforming events occurred. The first was the European discovery and the conquest of American continents, thus opening the Americas to Western institutions, religion, and economic exploitation. The labor shortage of Americas led to the forced migration of millions of Africans as slaves to the America. By the mid-seventeenth century the West consequently embraced the entire transatlantic world and its multiracial societies.

+

Second, shortly after the American encounter, a religious schism erupted within Latin Christianity. (基督教分裂) Reformers rejecting both many medieval Christian doctrines as unbiblical and the primacy of the Pope in Rome established Protestant churches across much of northern Europe. (宗教改革者不仅反对许多中世纪的基督教义,认为它们是不符合圣经的,还反对罗马天主教教皇的至高无上的地位,并且在北欧的大部分土地上建立了新教教堂) As a consequence, for almost two centuries religious warfare between Protestants and Roman Catholics overwhelmed the continent as monarchies chose to defend one side or the other. The religious turmoil meant that Europeans who conquered and settled the Americans carried with them particularly energized religious convictions, with **Roman Catholics dominating Latin America and English Protestants most of North America. **

+

By the late eighteenth century, the idea if the West denoted a culture increasingly dominated by two new forces. First, science arising from a new understanding of nature achieved during the sixteenth and seventeenth centuries persuaded growing numbers of the educated elite that human beings can rationally master nature for ever-expanding productive purposes improving the health and well-being of humankind. From this era to the present, the West has been associated with advances in technology, medicine, and scientific research. Second, during the eighteenth century, a drive for economy improvement that vastly increased agricultural production and then industrial manufacturing transformed economic life, especially in Western Europe and later the United States. Both of these economic development went hand in hand with urbanization and the movement of industrial economy into cities where the new urban populations experienced major urban dislocation (社会失序).

+

During the last quarter of eighteenth century, political revolution erupted across the transatlantic world. The British colonies of North America revolted, and then revolution occurred in France and spread across much of Europe. The Wars of Independence liberated Latin America from its European conquerors. Those revolutions created bold new modes of political life, rooting the legitimacy of the state in some form of popular government and generally written constitutions. Thereafter, despite the presence of authoritarian governments on the European continent, the idea of West, now including the new republics of the United States and Latin America, became associated with liberal democratic governments. (这些革命创造了新的政治生活模式,将国家的合法性和某种形式的人民政府和成文宪法联系到了一起。自此之后,除了欧洲大陆某些独裁政府,西方的概念,变得与自由民主的政府联系到了一起。)

+

During the nineteenth century, most major European states came to identify themselves in terms of nationality - language, history, and ethnicity - rather than loyalty to a monarch. Nationalism eventually inflamed popular opinion and unloosed unprecedented political ambition by European governments.

+

These ambitions led to imperialism and the creation of new overseas European empires in the late nineteenth century. For people living in European-administered Asian and African colonies, the idea and reality of the West embodied foreign domination and often disadvantageous involvement in a world economy. Even after colonial peoples around the globe challenged European imperial authority and gained independence, these former colonial peoples often suspected the West of seeking to control them. Hence, anticolonialism like colonialism before it redefined definitions of the West far from its borders.

+

Late nineteenth-century nationalism and imperialism also unleashed with World War I in 1914 unprecedented military hostilities among European nations that spread around the globe, followed a quarter century later by an even greater world war. As one result of World War, revolution occurred in Russia with the establishment of the communist Soviet Union. During the interwar years, a Fascist Party seized power in Italy and a Nazi Party took control of Germany. In response to these new authoritarian regimes, West European powers and the United States identified themselves with liberal democratic constitutionalism, individual freedom, commercial capitalism, science and learning freely pursued, and religious liberty, all of which they defined as the Western Heritage. (将他们自己认为是自由民主立宪政府、拥有个人自由、商业资本主义、拥有追求知识和科学的自由、宗教信仰自由,他们将这些定义为 Western Heritage。)

+

During the Cold War , conceived of as an East-West, democratic versus communist struggle that concluded with the collapse of the Soviet Union in 1991, the Western Powers led by the United States continued to embrace those values in conscious opposition to the Soviet government, which since 1945 had also dominated much of Eastern Europe.

+

Since 1991 the West has again become redefined in the minds of many people as a world political and economic order dominated by the United States. Europe clearly remains the West, but political leadership has moved to Northern America. That American domination and recent American foreign policy have led throughout the West and elsewhere to much criticism of United States.

+

Such self-criticism itself embodies one of the most important and persistent parts of the Western Heritage. From Hebrew prophets and Socrates to the critics of European imperialism, American foreign policy, social inequality, and environmental devastation, voices in the West have again and again been raised to criticize often in the most strident manner the policies of Western governments and the thought, values, social conditions, and the inequalities of Western societies.

+

Consequently, we study the Western Heritage not because the subject always or even primarily presents an admirable picture, but because the study of the Western Heritage like the study of all history calls us to an integrity of research, observation, and analysis that clarifies our minds and challenges our moral sensibilities. The challenge of history is the challenge of thinking, and it is to that challenge that this book invites its readers.

+

Chapter 1 The Birth of Civilization

+

Culture may be defined as the ways of living built up by a group and passed on from a generation to another. It includes behavior such as courtship and child-rearing practices; material things such as tools, clothing, and shelter; and ideas, institutions, and beliefs. Language, apparently a uniquely human trait, lies behind our ability to create ideas and institutions and to transmit culture from one generation to another. Our flexible and dexterous hands enable us to hold and make tools and so to create the material artifacts of culture. Because culture is learned and not inherited, it permits rapid adaption to changing conditions, making possible the spread of humanity to almost all the lands of the globe.

+

During the Paleolithic,

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Reading/index.html b/Reading/index.html new file mode 100644 index 0000000..8a9f26b --- /dev/null +++ b/Reading/index.html @@ -0,0 +1,838 @@ + + + + + + + + + + + + + + + + + + + + + + + Reading - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Reading

+
+

Abstract

+

在这里的都是我的读书笔记!包括但不限于哲学、历史学、心理学与社会学。

+

当然挖的坑越多就越难填(x

+

加油哦!

+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Varia/Booklist/index.html b/Varia/Booklist/index.html new file mode 100644 index 0000000..613b947 --- /dev/null +++ b/Varia/Booklist/index.html @@ -0,0 +1,1037 @@ + + + + + + + + + + + + + + + + + + + + + + + Booklist - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Booklist

+

Computer Science

+
    +
  • 《Computer System: A Programmer's Perspective》 Randal E. Bryant, David R. O'Hallaron 著
  • +
+

Math

+
    +
  • +

    《数学分析》 梅加强 著

    +
  • +
  • +

    《数学分析讲义》 陈天权 著

    +
  • +
  • +

    《Real And Complex Analysis》 Walter Rudin 著

    +
  • +
+

Literature

+
    +
  • 《雪国》 川端康成 著
  • +
+

Varia

+

Philosophy

+
    +
  • +

    《哲学导论》 王德峰 著

    +
  • +
  • +

    《西方现代思想讲义》 刘擎 著

    +
  • +
+

History

+
    +
  • +

    《The Western Heritage》

    +
  • +
  • +

    《枫丹白露宫 千年法国史》 让·弗朗索瓦·埃贝尔、蒂埃里·萨尔芒 著

    +
  • +
+

Society

+
    +
  • 《基本收入》 盖伊·斯坦丁 著
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Varia/Envs/index.html b/Varia/Envs/index.html new file mode 100644 index 0000000..e106d82 --- /dev/null +++ b/Varia/Envs/index.html @@ -0,0 +1,896 @@ + + + + + + + + + + + + + + + + + + + + + Environment Configuration - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Environment Configuration Record

+

WSL

+

咕咕咕,咕咕,咕咕咕。

+

暑假配Docker的时候再说。

+

Docker

+

咕咕,咕咕咕,咕咕。

+

暑假再说。

+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Varia/Learning Plan/index.html b/Varia/Learning Plan/index.html new file mode 100644 index 0000000..ebd8ebb --- /dev/null +++ b/Varia/Learning Plan/index.html @@ -0,0 +1,823 @@ + + + + + + + + + + + + + + + + + + + + + + + Learning Plan - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Learning Plan

+
+

Abstract

+

挖坑时间到!这真的只是我对我的学习期望而已,想学不代表一定会学(x

+

当然,我是一定会奋力学的!

+
+ + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Varia/Typst/index.html b/Varia/Typst/index.html new file mode 100644 index 0000000..d4fcca9 --- /dev/null +++ b/Varia/Typst/index.html @@ -0,0 +1,811 @@ + + + + + + + + + + + + + + + + + + + + + + + Typst Learning Report - V1CeVersa's Notebook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Typst Learning Report

+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..1cf13b9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/images/pdf.svg b/assets/images/pdf.svg new file mode 100644 index 0000000..a44518f --- /dev/null +++ b/assets/images/pdf.svg @@ -0,0 +1,149 @@ + + + + + PDF file icon + + + + + + + + + + image/svg+xml + + PDF file icon + 08/10/2018 + + + Adobe Systems + + + + + CMetalCore + + + Fuente del texto "PDF": +Franklin Gothic Medium Cond + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/javascripts/bundle.bd41221c.min.js b/assets/javascripts/bundle.bd41221c.min.js new file mode 100644 index 0000000..70bcbf1 --- /dev/null +++ b/assets/javascripts/bundle.bd41221c.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var _i=Object.create;var br=Object.defineProperty;var Ai=Object.getOwnPropertyDescriptor;var Ci=Object.getOwnPropertyNames,Ft=Object.getOwnPropertySymbols,ki=Object.getPrototypeOf,vr=Object.prototype.hasOwnProperty,eo=Object.prototype.propertyIsEnumerable;var Zr=(e,t,r)=>t in e?br(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,F=(e,t)=>{for(var r in t||(t={}))vr.call(t,r)&&Zr(e,r,t[r]);if(Ft)for(var r of Ft(t))eo.call(t,r)&&Zr(e,r,t[r]);return e};var to=(e,t)=>{var r={};for(var o in e)vr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Ft)for(var o of Ft(e))t.indexOf(o)<0&&eo.call(e,o)&&(r[o]=e[o]);return r};var gr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Hi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ci(t))!vr.call(e,n)&&n!==r&&br(e,n,{get:()=>t[n],enumerable:!(o=Ai(t,n))||o.enumerable});return e};var jt=(e,t,r)=>(r=e!=null?_i(ki(e)):{},Hi(t||!e||!e.__esModule?br(r,"default",{value:e,enumerable:!0}):r,e));var ro=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{a(r.next(c))}catch(p){n(p)}},s=c=>{try{a(r.throw(c))}catch(p){n(p)}},a=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,s);a((r=r.apply(e,t)).next())});var no=gr((xr,oo)=>{(function(e,t){typeof xr=="object"&&typeof oo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var o=!0,n=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(C){return!!(C&&C!==document&&C.nodeName!=="HTML"&&C.nodeName!=="BODY"&&"classList"in C&&"contains"in C.classList)}function c(C){var ct=C.type,Ne=C.tagName;return!!(Ne==="INPUT"&&s[ct]&&!C.readOnly||Ne==="TEXTAREA"&&!C.readOnly||C.isContentEditable)}function p(C){C.classList.contains("focus-visible")||(C.classList.add("focus-visible"),C.setAttribute("data-focus-visible-added",""))}function l(C){C.hasAttribute("data-focus-visible-added")&&(C.classList.remove("focus-visible"),C.removeAttribute("data-focus-visible-added"))}function f(C){C.metaKey||C.altKey||C.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(C){o=!1}function h(C){a(C.target)&&(o||c(C.target))&&p(C.target)}function w(C){a(C.target)&&(C.target.classList.contains("focus-visible")||C.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(C.target))}function A(C){document.visibilityState==="hidden"&&(n&&(o=!0),Z())}function Z(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function te(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(C){C.target.nodeName&&C.target.nodeName.toLowerCase()==="html"||(o=!1,te())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",A,!0),Z(),r.addEventListener("focus",h,!0),r.addEventListener("blur",w,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var zr=gr((kt,Vr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof kt=="object"&&typeof Vr=="object"?Vr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof kt=="object"?kt.ClipboardJS=r():t.ClipboardJS=r()})(kt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Li}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(D){try{return document.execCommand(D)}catch(M){return!1}}var h=function(M){var O=f()(M);return u("cut"),O},w=h;function A(D){var M=document.documentElement.getAttribute("dir")==="rtl",O=document.createElement("textarea");O.style.fontSize="12pt",O.style.border="0",O.style.padding="0",O.style.margin="0",O.style.position="absolute",O.style[M?"right":"left"]="-9999px";var I=window.pageYOffset||document.documentElement.scrollTop;return O.style.top="".concat(I,"px"),O.setAttribute("readonly",""),O.value=D,O}var Z=function(M,O){var I=A(M);O.container.appendChild(I);var W=f()(I);return u("copy"),I.remove(),W},te=function(M){var O=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},I="";return typeof M=="string"?I=Z(M,O):M instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(M==null?void 0:M.type)?I=Z(M.value,O):(I=f()(M),u("copy")),I},J=te;function C(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?C=function(O){return typeof O}:C=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},C(D)}var ct=function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},O=M.action,I=O===void 0?"copy":O,W=M.container,K=M.target,Ce=M.text;if(I!=="copy"&&I!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(K!==void 0)if(K&&C(K)==="object"&&K.nodeType===1){if(I==="copy"&&K.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(I==="cut"&&(K.hasAttribute("readonly")||K.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Ce)return J(Ce,{container:W});if(K)return I==="cut"?w(K):J(K,{container:W})},Ne=ct;function Pe(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Pe=function(O){return typeof O}:Pe=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},Pe(D)}function xi(D,M){if(!(D instanceof M))throw new TypeError("Cannot call a class as a function")}function Xr(D,M){for(var O=0;O0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof W.action=="function"?W.action:this.defaultAction,this.target=typeof W.target=="function"?W.target:this.defaultTarget,this.text=typeof W.text=="function"?W.text:this.defaultText,this.container=Pe(W.container)==="object"?W.container:document.body}},{key:"listenClick",value:function(W){var K=this;this.listener=p()(W,"click",function(Ce){return K.onClick(Ce)})}},{key:"onClick",value:function(W){var K=W.delegateTarget||W.currentTarget,Ce=this.action(K)||"copy",It=Ne({action:Ce,container:this.container,target:this.target(K),text:this.text(K)});this.emit(It?"success":"error",{action:Ce,text:It,trigger:K,clearSelection:function(){K&&K.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(W){return hr("action",W)}},{key:"defaultTarget",value:function(W){var K=hr("target",W);if(K)return document.querySelector(K)}},{key:"defaultText",value:function(W){return hr("text",W)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(W){var K=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(W,K)}},{key:"cut",value:function(W){return w(W)}},{key:"isSupported",value:function(){var W=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],K=typeof W=="string"?[W]:W,Ce=!!document.queryCommandSupported;return K.forEach(function(It){Ce=Ce&&!!document.queryCommandSupported(It)}),Ce}}]),O}(a()),Li=Mi},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s},438:function(o,n,i){var s=i(828);function a(l,f,u,h,w){var A=p.apply(this,arguments);return l.addEventListener(u,A,w),{destroy:function(){l.removeEventListener(u,A,w)}}}function c(l,f,u,h,w){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(A){return a(A,f,u,h,w)}))}function p(l,f,u,h){return function(w){w.delegateTarget=s(w.target,f),w.delegateTarget&&h.call(l,w)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(o,n,i){var s=i(879),a=i(438);function c(u,h,w){if(!u&&!h&&!w)throw new Error("Missing required arguments");if(!s.string(h))throw new TypeError("Second argument must be a String");if(!s.fn(w))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,h,w);if(s.nodeList(u))return l(u,h,w);if(s.string(u))return f(u,h,w);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,h,w){return u.addEventListener(h,w),{destroy:function(){u.removeEventListener(h,w)}}}function l(u,h,w){return Array.prototype.forEach.call(u,function(A){A.addEventListener(h,w)}),{destroy:function(){Array.prototype.forEach.call(u,function(A){A.removeEventListener(h,w)})}}}function f(u,h,w){return a(document.body,u,h,w)}o.exports=c},817:function(o){function n(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var Va=/["'&<>]/;qn.exports=za;function za(e){var t=""+e,r=Va.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function V(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function z(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||a(u,h)})})}function a(u,h){try{c(o[u](h))}catch(w){f(i[0][3],w)}}function c(u){u.value instanceof ot?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){a("next",u)}function l(u){a("throw",u)}function f(u,h){u(h),i.shift(),i.length&&a(i[0][0],i[0][1])}}function so(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof ue=="function"?ue(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function k(e){return typeof e=="function"}function pt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Wt=pt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=ue(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(A){t={error:A}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(A){i=A instanceof Wt?A.errors:[A]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=ue(f),h=u.next();!h.done;h=u.next()){var w=h.value;try{co(w)}catch(A){i=i!=null?i:[],A instanceof Wt?i=z(z([],V(i)),V(A.errors)):i.push(A)}}}catch(A){o={error:A}}finally{try{h&&!h.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Wt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)co(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Er=Ie.EMPTY;function Dt(e){return e instanceof Ie||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function co(e){k(e)?e():e.unsubscribe()}var ke={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var lt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?Er:(this.currentObservers=null,a.push(r),new Ie(function(){o.currentObservers=null,Ve(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new j;return r.source=this,r},t.create=function(r,o){return new vo(r,o)},t}(j);var vo=function(e){se(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Er},t}(v);var St={now:function(){return(St.delegate||Date).now()},delegate:void 0};var Ot=function(e){se(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=St);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(ut.cancelAnimationFrame(o),r._scheduled=void 0)},t}(zt);var yo=function(e){se(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(qt);var de=new yo(xo);var L=new j(function(e){return e.complete()});function Kt(e){return e&&k(e.schedule)}function _r(e){return e[e.length-1]}function Je(e){return k(_r(e))?e.pop():void 0}function Ae(e){return Kt(_r(e))?e.pop():void 0}function Qt(e,t){return typeof _r(e)=="number"?e.pop():t}var dt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Yt(e){return k(e==null?void 0:e.then)}function Bt(e){return k(e[ft])}function Gt(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function Jt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Di(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Xt=Di();function Zt(e){return k(e==null?void 0:e[Xt])}function er(e){return ao(this,arguments,function(){var r,o,n,i;return Ut(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,ot(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,ot(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,ot(n)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function tr(e){return k(e==null?void 0:e.getReader)}function N(e){if(e instanceof j)return e;if(e!=null){if(Bt(e))return Ni(e);if(dt(e))return Vi(e);if(Yt(e))return zi(e);if(Gt(e))return Eo(e);if(Zt(e))return qi(e);if(tr(e))return Ki(e)}throw Jt(e)}function Ni(e){return new j(function(t){var r=e[ft]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Vi(e){return new j(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?g(function(n,i){return e(n,i,o)}):ce,ye(1),r?Qe(t):jo(function(){return new or}))}}function $r(e){return e<=0?function(){return L}:x(function(t,r){var o=[];t.subscribe(S(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new v}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,h=0,w=!1,A=!1,Z=function(){f==null||f.unsubscribe(),f=void 0},te=function(){Z(),l=u=void 0,w=A=!1},J=function(){var C=l;te(),C==null||C.unsubscribe()};return x(function(C,ct){h++,!A&&!w&&Z();var Ne=u=u!=null?u:r();ct.add(function(){h--,h===0&&!A&&!w&&(f=Pr(J,c))}),Ne.subscribe(ct),!l&&h>0&&(l=new it({next:function(Pe){return Ne.next(Pe)},error:function(Pe){A=!0,Z(),f=Pr(te,n,Pe),Ne.error(Pe)},complete:function(){w=!0,Z(),f=Pr(te,s),Ne.complete()}}),N(C).subscribe(l))})(p)}}function Pr(e,t){for(var r=[],o=2;oe.next(document)),e}function R(e,t=document){return Array.from(t.querySelectorAll(e))}function P(e,t=document){let r=me(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function me(e,t=document){return t.querySelector(e)||void 0}function Re(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var la=T(d(document.body,"focusin"),d(document.body,"focusout")).pipe(be(1),q(void 0),m(()=>Re()||document.body),B(1));function vt(e){return la.pipe(m(t=>e.contains(t)),Y())}function Vo(e,t){return T(d(e,"mouseenter").pipe(m(()=>!0)),d(e,"mouseleave").pipe(m(()=>!1))).pipe(t?be(t):ce,q(!1))}function Ue(e){return{x:e.offsetLeft,y:e.offsetTop}}function zo(e){return T(d(window,"load"),d(window,"resize")).pipe(Me(0,de),m(()=>Ue(e)),q(Ue(e)))}function ir(e){return{x:e.scrollLeft,y:e.scrollTop}}function et(e){return T(d(e,"scroll"),d(window,"resize")).pipe(Me(0,de),m(()=>ir(e)),q(ir(e)))}function qo(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)qo(e,r)}function E(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)qo(o,n);return o}function ar(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function gt(e){let t=E("script",{src:e});return H(()=>(document.head.appendChild(t),T(d(t,"load"),d(t,"error").pipe(b(()=>Ar(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),_(()=>document.head.removeChild(t)),ye(1))))}var Ko=new v,ma=H(()=>typeof ResizeObserver=="undefined"?gt("https://unpkg.com/resize-observer-polyfill"):$(void 0)).pipe(m(()=>new ResizeObserver(e=>{for(let t of e)Ko.next(t)})),b(e=>T(qe,$(e)).pipe(_(()=>e.disconnect()))),B(1));function pe(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Ee(e){return ma.pipe(y(t=>t.observe(e)),b(t=>Ko.pipe(g(({target:r})=>r===e),_(()=>t.unobserve(e)),m(()=>pe(e)))),q(pe(e)))}function xt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function sr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var Qo=new v,fa=H(()=>$(new IntersectionObserver(e=>{for(let t of e)Qo.next(t)},{threshold:0}))).pipe(b(e=>T(qe,$(e)).pipe(_(()=>e.disconnect()))),B(1));function yt(e){return fa.pipe(y(t=>t.observe(e)),b(t=>Qo.pipe(g(({target:r})=>r===e),_(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function Yo(e,t=16){return et(e).pipe(m(({y:r})=>{let o=pe(e),n=xt(e);return r>=n.height-o.height-t}),Y())}var cr={drawer:P("[data-md-toggle=drawer]"),search:P("[data-md-toggle=search]")};function Bo(e){return cr[e].checked}function Be(e,t){cr[e].checked!==t&&cr[e].click()}function We(e){let t=cr[e];return d(t,"change").pipe(m(()=>t.checked),q(t.checked))}function ua(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function da(){return T(d(window,"compositionstart").pipe(m(()=>!0)),d(window,"compositionend").pipe(m(()=>!1))).pipe(q(!1))}function Go(){let e=d(window,"keydown").pipe(g(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:Bo("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),g(({mode:t,type:r})=>{if(t==="global"){let o=Re();if(typeof o!="undefined")return!ua(o,r)}return!0}),le());return da().pipe(b(t=>t?L:e))}function ve(){return new URL(location.href)}function st(e,t=!1){if(G("navigation.instant")&&!t){let r=E("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function Jo(){return new v}function Xo(){return location.hash.slice(1)}function Zo(e){let t=E("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function ha(e){return T(d(window,"hashchange"),e).pipe(m(Xo),q(Xo()),g(t=>t.length>0),B(1))}function en(e){return ha(e).pipe(m(t=>me(`[id="${t}"]`)),g(t=>typeof t!="undefined"))}function At(e){let t=matchMedia(e);return nr(r=>t.addListener(()=>r(t.matches))).pipe(q(t.matches))}function tn(){let e=matchMedia("print");return T(d(window,"beforeprint").pipe(m(()=>!0)),d(window,"afterprint").pipe(m(()=>!1))).pipe(q(e.matches))}function Ur(e,t){return e.pipe(b(r=>r?t():L))}function Wr(e,t){return new j(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let s=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+s*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function De(e,t){return Wr(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),B(1))}function rn(e,t){let r=new DOMParser;return Wr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),B(1))}function on(e,t){let r=new DOMParser;return Wr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),B(1))}function nn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function an(){return T(d(window,"scroll",{passive:!0}),d(window,"resize",{passive:!0})).pipe(m(nn),q(nn()))}function sn(){return{width:innerWidth,height:innerHeight}}function cn(){return d(window,"resize",{passive:!0}).pipe(m(sn),q(sn()))}function pn(){return Q([an(),cn()]).pipe(m(([e,t])=>({offset:e,size:t})),B(1))}function pr(e,{viewport$:t,header$:r}){let o=t.pipe(X("size")),n=Q([o,r]).pipe(m(()=>Ue(e)));return Q([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function ba(e){return d(e,"message",t=>t.data)}function va(e){let t=new v;return t.subscribe(r=>e.postMessage(r)),t}function ln(e,t=new Worker(e)){let r=ba(t),o=va(t),n=new v;n.subscribe(o);let i=o.pipe(ee(),oe(!0));return n.pipe(ee(),$e(r.pipe(U(i))),le())}var ga=P("#__config"),Et=JSON.parse(ga.textContent);Et.base=`${new URL(Et.base,ve())}`;function we(){return Et}function G(e){return Et.features.includes(e)}function ge(e,t){return typeof t!="undefined"?Et.translations[e].replace("#",t.toString()):Et.translations[e]}function Te(e,t=document){return P(`[data-md-component=${e}]`,t)}function ne(e,t=document){return R(`[data-md-component=${e}]`,t)}function xa(e){let t=P(".md-typeset > :first-child",e);return d(t,"click",{once:!0}).pipe(m(()=>P(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function mn(e){if(!G("announce.dismiss")||!e.childElementCount)return L;if(!e.hidden){let t=P(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return H(()=>{let t=new v;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),xa(e).pipe(y(r=>t.next(r)),_(()=>t.complete()),m(r=>F({ref:e},r)))})}function ya(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function fn(e,t){let r=new v;return r.subscribe(({hidden:o})=>{e.hidden=o}),ya(e,t).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))}function Ct(e,t){return t==="inline"?E("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},E("div",{class:"md-tooltip__inner md-typeset"})):E("div",{class:"md-tooltip",id:e,role:"tooltip"},E("div",{class:"md-tooltip__inner md-typeset"}))}function un(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return E("aside",{class:"md-annotation",tabIndex:0},Ct(t),E("a",{href:r,class:"md-annotation__index",tabIndex:-1},E("span",{"data-md-annotation-id":e})))}else return E("aside",{class:"md-annotation",tabIndex:0},Ct(t),E("span",{class:"md-annotation__index",tabIndex:-1},E("span",{"data-md-annotation-id":e})))}function dn(e){return E("button",{class:"md-clipboard md-icon",title:ge("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Dr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,E("del",null,p)," "],[]).slice(0,-1),i=we(),s=new URL(e.location,i.base);G("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=we();return E("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},E("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&E("div",{class:"md-search-result__icon md-icon"}),r>0&&E("h1",null,e.title),r<=0&&E("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return E("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&E("p",{class:"md-search-result__terms"},ge("search.result.term.missing"),": ",...n)))}function hn(e){let t=e[0].score,r=[...e],o=we(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scoreDr(l,1)),...c.length?[E("details",{class:"md-search-result__more"},E("summary",{tabIndex:-1},E("div",null,c.length>0&&c.length===1?ge("search.result.more.one"):ge("search.result.more.other",c.length))),...c.map(l=>Dr(l,1)))]:[]];return E("li",{class:"md-search-result__item"},p)}function bn(e){return E("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>E("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?ar(r):r)))}function Nr(e){let t=`tabbed-control tabbed-control--${e}`;return E("div",{class:t,hidden:!0},E("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function vn(e){return E("div",{class:"md-typeset__scrollwrap"},E("div",{class:"md-typeset__table"},e))}function Ea(e){let t=we(),r=new URL(`../${e.version}/`,t.base);return E("li",{class:"md-version__item"},E("a",{href:`${r}`,class:"md-version__link"},e.title))}function gn(e,t){return e=e.filter(r=>{var o;return!((o=r.properties)!=null&&o.hidden)}),E("div",{class:"md-version"},E("button",{class:"md-version__current","aria-label":ge("select.version")},t.title),E("ul",{class:"md-version__list"},e.map(Ea)))}var wa=0;function Ta(e,t){document.body.append(e);let{width:r}=pe(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=sr(t),n=typeof o!="undefined"?et(o):$({x:0,y:0}),i=T(vt(t),Vo(t)).pipe(Y());return Q([i,n]).pipe(m(([s,a])=>{let{x:c,y:p}=Ue(t),l=pe(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:s,offset:{x:c-a.x+l.width/2-r/2,y:p-a.y+l.height+8}}}))}function Ge(e){let t=e.title;if(!t.length)return L;let r=`__tooltip_${wa++}`,o=Ct(r,"inline"),n=P(".md-typeset",o);return n.innerHTML=t,H(()=>{let i=new v;return i.subscribe({next({offset:s}){o.style.setProperty("--md-tooltip-x",`${s.x}px`),o.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),T(i.pipe(g(({active:s})=>s)),i.pipe(be(250),g(({active:s})=>!s))).subscribe({next({active:s}){s?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Me(16,de)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(_t(125,de),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?o.style.setProperty("--md-tooltip-0",`${-s}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Ta(o,e).pipe(y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))}).pipe(ze(ie))}function Sa(e,t){let r=H(()=>Q([zo(e),et(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=pe(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return vt(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),ye(+!o||1/0))))}function xn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return H(()=>{let i=new v,s=i.pipe(ee(),oe(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),yt(e).pipe(U(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),T(i.pipe(g(({active:a})=>a)),i.pipe(be(250),g(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Me(16,de)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(_t(125,de),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),d(n,"click").pipe(U(s),g(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),d(n,"mousedown").pipe(U(s),ae(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Re())==null||p.blur()}}),r.pipe(U(s),g(a=>a===o),Ye(125)).subscribe(()=>e.focus()),Sa(e,t).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))})}function Oa(e){return e.tagName==="CODE"?R(".c, .c1, .cm",e):[e]}function Ma(e){let t=[];for(let r of Oa(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function yn(e,t){t.append(...Array.from(e.childNodes))}function lr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of Ma(t)){let[,c]=a.textContent.match(/\((\d+)\)/);me(`:scope > li:nth-child(${c})`,e)&&(s.set(c,un(c,i)),a.replaceWith(s.get(c)))}return s.size===0?L:H(()=>{let a=new v,c=a.pipe(ee(),oe(!0)),p=[];for(let[l,f]of s)p.push([P(".md-typeset",f),P(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?yn(f,u):yn(u,f)}),T(...[...s].map(([,l])=>xn(l,t,{target$:r}))).pipe(_(()=>a.complete()),le())})}function En(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return En(t)}}function wn(e,t){return H(()=>{let r=En(e);return typeof r!="undefined"?lr(r,e,t):L})}var Tn=jt(zr());var La=0;function Sn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Sn(t)}}function _a(e){return Ee(e).pipe(m(({width:t})=>({scrollable:xt(e).width>t})),X("scrollable"))}function On(e,t){let{matches:r}=matchMedia("(hover)"),o=H(()=>{let n=new v,i=n.pipe($r(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let s=[];if(Tn.default.isSupported()&&(e.closest(".copy")||G("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${La++}`;let p=dn(c.id);c.insertBefore(p,e),G("content.tooltips")&&s.push(Ge(p))}let a=e.closest(".highlight");if(a instanceof HTMLElement){let c=Sn(a);if(typeof c!="undefined"&&(a.classList.contains("annotate")||G("content.code.annotate"))){let p=lr(c,e,t);s.push(Ee(a).pipe(U(i),m(({width:l,height:f})=>l&&f),Y(),b(l=>l?p:L)))}}return _a(e).pipe(y(c=>n.next(c)),_(()=>n.complete()),m(c=>F({ref:e},c)),$e(...s))});return G("content.lazy")?yt(e).pipe(g(n=>n),ye(1),b(()=>o)):o}function Aa(e,{target$:t,print$:r}){let o=!0;return T(t.pipe(m(n=>n.closest("details:not([open])")),g(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(g(n=>n||!o),y(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Mn(e,t){return H(()=>{let r=new v;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Aa(e,t).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}var Ln=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var qr,ka=0;function Ha(){return typeof mermaid=="undefined"||mermaid instanceof Element?gt("https://unpkg.com/mermaid@10.7.0/dist/mermaid.min.js"):$(void 0)}function _n(e){return e.classList.remove("mermaid"),qr||(qr=Ha().pipe(y(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Ln,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),B(1))),qr.subscribe(()=>ro(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${ka++}`,r=E("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})),qr.pipe(m(()=>({ref:e})))}var An=E("table");function Cn(e){return e.replaceWith(An),An.replaceWith(vn(e)),$({ref:e})}function $a(e){let t=e.find(r=>r.checked)||e[0];return T(...e.map(r=>d(r,"change").pipe(m(()=>P(`label[for="${r.id}"]`))))).pipe(q(P(`label[for="${t.id}"]`)),m(r=>({active:r})))}function kn(e,{viewport$:t,target$:r}){let o=P(".tabbed-labels",e),n=R(":scope > input",e),i=Nr("prev");e.append(i);let s=Nr("next");return e.append(s),H(()=>{let a=new v,c=a.pipe(ee(),oe(!0));Q([a,Ee(e)]).pipe(U(c),Me(1,de)).subscribe({next([{active:p},l]){let f=Ue(p),{width:u}=pe(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let h=ir(o);(f.xh.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),Q([et(o),Ee(o)]).pipe(U(c)).subscribe(([p,l])=>{let f=xt(o);i.hidden=p.x<16,s.hidden=p.x>f.width-l.width-16}),T(d(i,"click").pipe(m(()=>-1)),d(s,"click").pipe(m(()=>1))).pipe(U(c)).subscribe(p=>{let{width:l}=pe(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(U(c),g(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=P(`label[for="${p.id}"]`);l.replaceChildren(E("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),d(l.firstElementChild,"click").pipe(U(c),g(f=>!(f.metaKey||f.ctrlKey)),y(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return G("content.tabs.link")&&a.pipe(Le(1),ae(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let w of R("[data-tabs]"))for(let A of R(":scope > input",w)){let Z=P(`label[for="${A.id}"]`);if(Z!==p&&Z.innerText.trim()===f){Z.setAttribute("data-md-switching",""),A.click();break}}window.scrollTo({top:e.offsetTop-u});let h=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...h])])}}),a.pipe(U(c)).subscribe(()=>{for(let p of R("audio, video",e))p.pause()}),$a(n).pipe(y(p=>a.next(p)),_(()=>a.complete()),m(p=>F({ref:e},p)))}).pipe(ze(ie))}function Hn(e,{viewport$:t,target$:r,print$:o}){return T(...R(".annotate:not(.highlight)",e).map(n=>wn(n,{target$:r,print$:o})),...R("pre:not(.mermaid) > code",e).map(n=>On(n,{target$:r,print$:o})),...R("pre.mermaid",e).map(n=>_n(n)),...R("table:not([class])",e).map(n=>Cn(n)),...R("details",e).map(n=>Mn(n,{target$:r,print$:o})),...R("[data-tabs]",e).map(n=>kn(n,{viewport$:t,target$:r})),...R("[title]",e).filter(()=>G("content.tooltips")).map(n=>Ge(n)))}function Ra(e,{alert$:t}){return t.pipe(b(r=>T($(!0),$(!1).pipe(Ye(2e3))).pipe(m(o=>({message:r,active:o})))))}function $n(e,t){let r=P(".md-typeset",e);return H(()=>{let o=new v;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),Ra(e,t).pipe(y(n=>o.next(n)),_(()=>o.complete()),m(n=>F({ref:e},n)))})}function Pa({viewport$:e}){if(!G("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Ke(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Y()),o=We("search");return Q([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Y(),b(n=>n?r:$(!1)),q(!1))}function Rn(e,t){return H(()=>Q([Ee(e),Pa(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Y((r,o)=>r.height===o.height&&r.hidden===o.hidden),B(1))}function Pn(e,{header$:t,main$:r}){return H(()=>{let o=new v,n=o.pipe(ee(),oe(!0));o.pipe(X("active"),je(t)).subscribe(([{active:s},{hidden:a}])=>{e.classList.toggle("md-header--shadow",s&&!a),e.hidden=a});let i=fe(R("[title]",e)).pipe(g(()=>G("content.tooltips")),re(s=>Ge(s)));return r.subscribe(o),t.pipe(U(n),m(s=>F({ref:e},s)),$e(i.pipe(U(n))))})}function Ia(e,{viewport$:t,header$:r}){return pr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=pe(e);return{active:o>=n}}),X("active"))}function In(e,t){return H(()=>{let r=new v;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=me(".md-content h1");return typeof o=="undefined"?L:Ia(o,t).pipe(y(n=>r.next(n)),_(()=>r.complete()),m(n=>F({ref:e},n)))})}function Fn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Y()),n=o.pipe(b(()=>Ee(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),X("bottom"))));return Q([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),Y((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function Fa(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return $(...e).pipe(re(o=>d(o,"change").pipe(m(()=>o))),q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),B(1))}function jn(e){let t=R("input",e),r=E("meta",{name:"theme-color"});document.head.appendChild(r);let o=E("meta",{name:"color-scheme"});document.head.appendChild(o);let n=At("(prefers-color-scheme: light)");return H(()=>{let i=new v;return i.subscribe(s=>{if(document.body.setAttribute("data-md-color-switching",""),s.color.media==="(prefers-color-scheme)"){let a=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(a.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");s.color.scheme=c.getAttribute("data-md-color-scheme"),s.color.primary=c.getAttribute("data-md-color-primary"),s.color.accent=c.getAttribute("data-md-color-accent")}for(let[a,c]of Object.entries(s.color))document.body.setAttribute(`data-md-color-${a}`,c);for(let a=0;a{let s=Te("header"),a=window.getComputedStyle(s);return o.content=a.colorScheme,a.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(s=>r.content=`#${s}`),i.pipe(Oe(ie)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Fa(t).pipe(U(n.pipe(Le(1))),at(),y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))})}function Un(e,{progress$:t}){return H(()=>{let r=new v;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(y(o=>r.next({value:o})),_(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Kr=jt(zr());function ja(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Wn({alert$:e}){Kr.default.isSupported()&&new j(t=>{new Kr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||ja(P(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(y(t=>{t.trigger.focus()}),m(()=>ge("clipboard.copied"))).subscribe(e)}function Dn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function Ua(e,t){let r=new Map;for(let o of R("url",e)){let n=P("loc",o),i=[Dn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let s of R("[rel=alternate]",o)){let a=s.getAttribute("href");a!=null&&i.push(Dn(new URL(a),t))}}return r}function mr(e){return on(new URL("sitemap.xml",e)).pipe(m(t=>Ua(t,new URL(e))),he(()=>$(new Map)))}function Wa(e,t){if(!(e.target instanceof Element))return L;let r=e.target.closest("a");if(r===null)return L;if(r.target||e.metaKey||e.ctrlKey)return L;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),$(new URL(r.href))):L}function Nn(e){let t=new Map;for(let r of R(":scope > *",e.head))t.set(r.outerHTML,r);return t}function Vn(e){for(let t of R("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return $(e)}function Da(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...G("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=me(o),i=me(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=Nn(document);for(let[o,n]of Nn(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Te("container");return Fe(R("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new j(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),L}),ee(),oe(document))}function zn({location$:e,viewport$:t,progress$:r}){let o=we();if(location.protocol==="file:")return L;let n=mr(o.base);$(document).subscribe(Vn);let i=d(document.body,"click").pipe(je(n),b(([c,p])=>Wa(c,p)),le()),s=d(window,"popstate").pipe(m(ve),le());i.pipe(ae(t)).subscribe(([c,{offset:p}])=>{history.replaceState(p,""),history.pushState(null,"",c)}),T(i,s).subscribe(e);let a=e.pipe(X("pathname"),b(c=>rn(c,{progress$:r}).pipe(he(()=>(st(c,!0),L)))),b(Vn),b(Da),le());return T(a.pipe(ae(e,(c,p)=>p)),e.pipe(X("pathname"),b(()=>e),X("hash")),e.pipe(Y((c,p)=>c.pathname===p.pathname&&c.hash===p.hash),b(()=>i),y(()=>history.back()))).subscribe(c=>{var p,l;history.state!==null||!c.hash?window.scrollTo(0,(l=(p=history.state)==null?void 0:p.y)!=null?l:0):(history.scrollRestoration="auto",Zo(c.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),d(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(X("offset"),be(100)).subscribe(({offset:c})=>{history.replaceState(c,"")}),a}var Qn=jt(Kn());function Yn(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,Qn.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function Ht(e){return e.type===1}function fr(e){return e.type===3}function Bn(e,t){let r=ln(e);return T($(location.protocol!=="file:"),We("search")).pipe(He(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:G("search.suggest")}}})),r}function Gn({document$:e}){let t=we(),r=De(new URL("../versions.json",t.base)).pipe(he(()=>L)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>d(document.body,"click").pipe(g(i=>!i.metaKey&&!i.ctrlKey),ae(o),b(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?L:(i.preventDefault(),$(c))}}return L}),b(i=>{let{version:s}=n.get(i);return mr(new URL(i)).pipe(m(a=>{let p=ve().href.replace(t.base,"");return a.has(p.split("#")[0])?new URL(`../${s}/${p}`,t.base):new URL(i)}))})))).subscribe(n=>st(n,!0)),Q([r,o]).subscribe(([n,i])=>{P(".md-header__topic").appendChild(gn(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let a=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(a)||(a=[a]);e:for(let c of a)for(let p of n.aliases.concat(n.version))if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let a of ne("outdated"))a.hidden=!1})}function Ka(e,{worker$:t}){let{searchParams:r}=ve();r.has("q")&&(Be("search",!0),e.value=r.get("q"),e.focus(),We("search").pipe(He(i=>!i)).subscribe(()=>{let i=ve();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=vt(e),n=T(t.pipe(He(Ht)),d(e,"keyup"),o).pipe(m(()=>e.value),Y());return Q([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),B(1))}function Jn(e,{worker$:t}){let r=new v,o=r.pipe(ee(),oe(!0));Q([t.pipe(He(Ht)),r],(i,s)=>s).pipe(X("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(X("focus")).subscribe(({focus:i})=>{i&&Be("search",i)}),d(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=P("header [for=__search]");return d(n,"click").subscribe(()=>e.focus()),Ka(e,{worker$:t}).pipe(y(i=>r.next(i)),_(()=>r.complete()),m(i=>F({ref:e},i)),B(1))}function Xn(e,{worker$:t,query$:r}){let o=new v,n=Yo(e.parentElement).pipe(g(Boolean)),i=e.parentElement,s=P(":scope > :first-child",e),a=P(":scope > :last-child",e);We("search").subscribe(l=>a.setAttribute("role",l?"list":"presentation")),o.pipe(ae(r),Ir(t.pipe(He(Ht)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?ge("search.result.none"):ge("search.result.placeholder");break;case 1:s.textContent=ge("search.result.one");break;default:let u=ar(l.length);s.textContent=ge("search.result.other",u)}});let c=o.pipe(y(()=>a.innerHTML=""),b(({items:l})=>T($(...l.slice(0,10)),$(...l.slice(10)).pipe(Ke(4),jr(n),b(([f])=>f)))),m(hn),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(re(l=>{let f=me("details",l);return typeof f=="undefined"?L:d(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(g(fr),m(({data:l})=>l)).pipe(y(l=>o.next(l)),_(()=>o.complete()),m(l=>F({ref:e},l)))}function Qa(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=ve();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function Zn(e,t){let r=new v,o=r.pipe(ee(),oe(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),d(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),Qa(e,t).pipe(y(n=>r.next(n)),_(()=>r.complete()),m(n=>F({ref:e},n)))}function ei(e,{worker$:t,keyboard$:r}){let o=new v,n=Te("search-query"),i=T(d(n,"keydown"),d(n,"focus")).pipe(Oe(ie),m(()=>n.value),Y());return o.pipe(je(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(g(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(g(fr),m(({data:a})=>a)).pipe(y(a=>o.next(a)),_(()=>o.complete()),m(()=>({ref:e})))}function ti(e,{index$:t,keyboard$:r}){let o=we();try{let n=Bn(o.search,t),i=Te("search-query",e),s=Te("search-result",e);d(e,"click").pipe(g(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>Be("search",!1)),r.pipe(g(({mode:c})=>c==="search")).subscribe(c=>{let p=Re();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of R(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,h])=>h-u);f.click()}c.claim()}break;case"Escape":case"Tab":Be("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...R(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Re()&&i.focus()}}),r.pipe(g(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=Jn(i,{worker$:n});return T(a,Xn(s,{worker$:n,query$:a})).pipe($e(...ne("search-share",e).map(c=>Zn(c,{query$:a})),...ne("search-suggest",e).map(c=>ei(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,qe}}function ri(e,{index$:t,location$:r}){return Q([t,r.pipe(q(ve()),g(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>Yn(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=E("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function Ya(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return Q([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),Y((i,s)=>i.height===s.height&&i.locked===s.locked))}function Qr(e,o){var n=o,{header$:t}=n,r=to(n,["header$"]);let i=P(".md-sidebar__scrollwrap",e),{y:s}=Ue(i);return H(()=>{let a=new v,c=a.pipe(ee(),oe(!0)),p=a.pipe(Me(0,de));return p.pipe(ae(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(He()).subscribe(()=>{for(let l of R(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=pe(f);f.scrollTo({top:u-h/2})}}}),fe(R("label[tabindex]",e)).pipe(re(l=>d(l,"click").pipe(Oe(ie),m(()=>l),U(c)))).subscribe(l=>{let f=P(`[id="${l.htmlFor}"]`);P(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Ya(e,r).pipe(y(l=>a.next(l)),_(()=>a.complete()),m(l=>F({ref:e},l)))})}function oi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Lt(De(`${r}/releases/latest`).pipe(he(()=>L),m(o=>({version:o.tag_name})),Qe({})),De(r).pipe(he(()=>L),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Qe({}))).pipe(m(([o,n])=>F(F({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return De(r).pipe(m(o=>({repositories:o.public_repos})),Qe({}))}}function ni(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return De(r).pipe(he(()=>L),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Qe({}))}function ii(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return oi(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ni(r,o)}return L}var Ba;function Ga(e){return Ba||(Ba=H(()=>{let t=__md_get("__source",sessionStorage);if(t)return $(t);if(ne("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return L}return ii(e.href).pipe(y(o=>__md_set("__source",o,sessionStorage)))}).pipe(he(()=>L),g(t=>Object.keys(t).length>0),m(t=>({facts:t})),B(1)))}function ai(e){let t=P(":scope > :last-child",e);return H(()=>{let r=new v;return r.subscribe(({facts:o})=>{t.appendChild(bn(o)),t.classList.add("md-source__repository--active")}),Ga(e).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}function Ja(e,{viewport$:t,header$:r}){return Ee(document.body).pipe(b(()=>pr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),X("hidden"))}function si(e,t){return H(()=>{let r=new v;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(G("navigation.tabs.sticky")?$({hidden:!1}):Ja(e,t)).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}function Xa(e,{viewport$:t,header$:r}){let o=new Map,n=R(".md-nav__link",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=me(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(X("height"),m(({height:a})=>{let c=Te("main"),p=P(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return Ee(document.body).pipe(X("height"),b(a=>H(()=>{let c=[];return $([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let h=f.offsetParent;for(;h;h=h.offsetParent)u+=h.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),je(i),b(([c,p])=>t.pipe(Rr(([l,f],{offset:{y:u},size:h})=>{let w=u+h.height>=Math.floor(a.height);for(;f.length;){let[,A]=f[0];if(A-p=u&&!w)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Y((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),q({prev:[],next:[]}),Ke(2,1),m(([a,c])=>a.prev.length{let i=new v,s=i.pipe(ee(),oe(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),G("toc.follow")){let a=T(t.pipe(be(1),m(()=>{})),t.pipe(be(250),m(()=>"smooth")));i.pipe(g(({prev:c})=>c.length>0),je(o.pipe(Oe(ie))),ae(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=sr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=pe(f);f.scrollTo({top:u-h/2,behavior:p})}}})}return G("navigation.tracking")&&t.pipe(U(s),X("offset"),be(250),Le(1),U(n.pipe(Le(1))),at({delay:250}),ae(i)).subscribe(([,{prev:a}])=>{let c=ve(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),Xa(e,{viewport$:t,header$:r}).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))})}function Za(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),Ke(2,1),m(([s,a])=>s>a&&a>0),Y()),i=r.pipe(m(({active:s})=>s));return Q([i,n]).pipe(m(([s,a])=>!(s&&a)),Y(),U(o.pipe(Le(1))),oe(!0),at({delay:250}),m(s=>({hidden:s})))}function pi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new v,s=i.pipe(ee(),oe(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(s),X("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),d(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),Za(e,{viewport$:t,main$:o,target$:n}).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))}function li({document$:e}){e.pipe(b(()=>R(".md-ellipsis")),re(t=>yt(t).pipe(U(e.pipe(Le(1))),g(r=>r),m(()=>t),ye(1))),g(t=>t.offsetWidth{let r=t.innerText,o=t.closest("a")||t;return o.title=r,Ge(o).pipe(U(e.pipe(Le(1))),_(()=>o.removeAttribute("title")))})).subscribe(),e.pipe(b(()=>R(".md-status")),re(t=>Ge(t))).subscribe()}function mi({document$:e,tablet$:t}){e.pipe(b(()=>R(".md-toggle--indeterminate")),y(r=>{r.indeterminate=!0,r.checked=!1}),re(r=>d(r,"change").pipe(Fr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ae(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function es(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function fi({document$:e}){e.pipe(b(()=>R("[data-md-scrollfix]")),y(t=>t.removeAttribute("data-md-scrollfix")),g(es),re(t=>d(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function ui({viewport$:e,tablet$:t}){Q([We("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>$(r).pipe(Ye(r?400:100))),ae(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ts(){return location.protocol==="file:"?gt(`${new URL("search/search_index.js",Yr.base)}`).pipe(m(()=>__index),B(1)):De(new URL("search/search_index.json",Yr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var rt=No(),Rt=Jo(),wt=en(Rt),Br=Go(),_e=pn(),ur=At("(min-width: 960px)"),hi=At("(min-width: 1220px)"),bi=tn(),Yr=we(),vi=document.forms.namedItem("search")?ts():qe,Gr=new v;Wn({alert$:Gr});var Jr=new v;G("navigation.instant")&&zn({location$:Rt,viewport$:_e,progress$:Jr}).subscribe(rt);var di;((di=Yr.version)==null?void 0:di.provider)==="mike"&&Gn({document$:rt});T(Rt,wt).pipe(Ye(125)).subscribe(()=>{Be("drawer",!1),Be("search",!1)});Br.pipe(g(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=me("link[rel=prev]");typeof t!="undefined"&&st(t);break;case"n":case".":let r=me("link[rel=next]");typeof r!="undefined"&&st(r);break;case"Enter":let o=Re();o instanceof HTMLLabelElement&&o.click()}});li({document$:rt});mi({document$:rt,tablet$:ur});fi({document$:rt});ui({viewport$:_e,tablet$:ur});var tt=Rn(Te("header"),{viewport$:_e}),$t=rt.pipe(m(()=>Te("main")),b(e=>Fn(e,{viewport$:_e,header$:tt})),B(1)),rs=T(...ne("consent").map(e=>fn(e,{target$:wt})),...ne("dialog").map(e=>$n(e,{alert$:Gr})),...ne("header").map(e=>Pn(e,{viewport$:_e,header$:tt,main$:$t})),...ne("palette").map(e=>jn(e)),...ne("progress").map(e=>Un(e,{progress$:Jr})),...ne("search").map(e=>ti(e,{index$:vi,keyboard$:Br})),...ne("source").map(e=>ai(e))),os=H(()=>T(...ne("announce").map(e=>mn(e)),...ne("content").map(e=>Hn(e,{viewport$:_e,target$:wt,print$:bi})),...ne("content").map(e=>G("search.highlight")?ri(e,{index$:vi,location$:Rt}):L),...ne("header-title").map(e=>In(e,{viewport$:_e,header$:tt})),...ne("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Ur(hi,()=>Qr(e,{viewport$:_e,header$:tt,main$:$t})):Ur(ur,()=>Qr(e,{viewport$:_e,header$:tt,main$:$t}))),...ne("tabs").map(e=>si(e,{viewport$:_e,header$:tt})),...ne("toc").map(e=>ci(e,{viewport$:_e,header$:tt,main$:$t,target$:wt})),...ne("top").map(e=>pi(e,{viewport$:_e,header$:tt,main$:$t,target$:wt})))),gi=rt.pipe(b(()=>os),$e(rs),B(1));gi.subscribe();window.document$=rt;window.location$=Rt;window.target$=wt;window.keyboard$=Br;window.viewport$=_e;window.tablet$=ur;window.screen$=hi;window.print$=bi;window.alert$=Gr;window.progress$=Jr;window.component$=gi;})(); +//# sourceMappingURL=bundle.bd41221c.min.js.map + diff --git a/assets/javascripts/bundle.bd41221c.min.js.map b/assets/javascripts/bundle.bd41221c.min.js.map new file mode 100644 index 0000000..1663dab --- /dev/null +++ b/assets/javascripts/bundle.bd41221c.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/rxjs/node_modules/tslib/tslib.es6.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an